Skip to content

Commit 866a71a

Browse files
committed
JDA 5: first pass
1 parent 828f783 commit 866a71a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+657
-562
lines changed

database-code/src/main/scala/score/discord/canti/collections/ChannelByGuild.scala

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package score.discord.canti.collections
22

3-
import net.dv8tion.jda.api.entities.{Guild, GuildChannel => Channel}
3+
import net.dv8tion.jda.api.entities.Guild
4+
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel
45
import score.discord.canti.util.DBUtils
56
import score.discord.canti.wrappers.database.IDMapping._
67
import score.discord.canti.wrappers.jda.ID
@@ -11,14 +12,14 @@ import scala.concurrent.ExecutionContext.Implicits.global
1112
import scala.concurrent.Future
1213

1314
class ChannelByGuild(dbConfig: DatabaseConfig[_ <: JdbcProfile], tableName: String)
14-
extends AsyncMap[ID[Guild], ID[Channel]] {
15+
extends AsyncMap[ID[Guild], ID[GuildChannel]] {
1516

1617
import dbConfig.profile.api._
1718

1819
private class ChannelByGuild(tag: Tag, name: String)
19-
extends Table[(ID[Guild], ID[Channel])](tag, name) {
20+
extends Table[(ID[Guild], ID[GuildChannel])](tag, name) {
2021
val guildId = column[ID[Guild]]("guild", O.PrimaryKey)
21-
val channelId = column[ID[Channel]]("channel")
22+
val channelId = column[ID[GuildChannel]]("channel")
2223

2324
override def * = (guildId, channelId)
2425
}
@@ -31,15 +32,15 @@ class ChannelByGuild(dbConfig: DatabaseConfig[_ <: JdbcProfile], tableName: Stri
3132
})
3233
DBUtils.ensureTableCreated(dbConfig, channelByGuildTable, tableName)
3334

34-
override def get(key: ID[Guild]): Future[Option[ID[Channel]]] =
35+
override def get(key: ID[Guild]): Future[Option[ID[GuildChannel]]] =
3536
dbConfig.db.run(lookupQuery(key).result).map(_.headOption)
3637

37-
override def update(guild: ID[Guild], role: ID[Channel]): Future[Int] =
38+
override def update(guild: ID[Guild], role: ID[GuildChannel]): Future[Int] =
3839
database.run(channelByGuildTable.insertOrUpdate(guild, role))
3940

4041
override def remove(guild: ID[Guild]): Future[Int] =
4142
database.run(lookupQuery(guild).delete)
4243

43-
override def items: Future[Seq[(ID[Guild], ID[Channel])]] =
44+
override def items: Future[Seq[(ID[Guild], ID[GuildChannel])]] =
4445
throw new UnsupportedOperationException()
4546
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package score.discord.canti.collections
22

3-
import net.dv8tion.jda.api.entities._
3+
import net.dv8tion.jda.api.entities.{Guild, User, ISnowflake}
4+
import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel
45
import score.discord.canti.util.DBUtils
56
import score.discord.canti.wrappers.database.IDMapping._
67
import score.discord.canti.wrappers.jda.ID
@@ -10,15 +11,15 @@ import slick.jdbc.JdbcProfile
1011
import scala.concurrent.ExecutionContext.Implicits.global
1112
import scala.concurrent.Future
1213

13-
class UserByVoiceChannel(dbConfig: DatabaseConfig[_ <: JdbcProfile], tableName: String)
14-
extends AsyncMap[(ID[Guild], ID[VoiceChannel]), ID[User]] {
14+
class UserByAudioChannel(dbConfig: DatabaseConfig[_ <: JdbcProfile], tableName: String)
15+
extends AsyncMap[(ID[Guild], ID[AudioChannel]), ID[User]] {
1516

1617
import dbConfig.profile.api._
1718

1819
private class UserByChannelTable(tag: Tag)
19-
extends Table[(ID[Guild], ID[VoiceChannel], ID[User])](tag, tableName) {
20+
extends Table[(ID[Guild], ID[AudioChannel], ID[User])](tag, tableName) {
2021
val guildId = column[ID[Guild]]("guild")
21-
val channelId = column[ID[VoiceChannel]]("channel")
22+
val channelId = column[ID[AudioChannel]]("channel")
2223
val userId = column[ID[User]]("user")
2324
val pk = primaryKey("primary", (guildId, channelId))
2425

@@ -27,35 +28,35 @@ class UserByVoiceChannel(dbConfig: DatabaseConfig[_ <: JdbcProfile], tableName:
2728

2829
private val userByChannelTable = TableQuery[UserByChannelTable]
2930
private val lookupQuery =
30-
Compiled((guildId: ConstColumn[ID[Guild]], channelId: ConstColumn[ID[VoiceChannel]]) => {
31+
Compiled((guildId: ConstColumn[ID[Guild]], channelId: ConstColumn[ID[AudioChannel]]) => {
3132
userByChannelTable
3233
.filter(t => t.guildId === guildId && t.channelId === channelId)
3334
.map(_.userId)
3435
})
3536

3637
DBUtils.ensureTableCreated(dbConfig, userByChannelTable, tableName)
3738

38-
override def get(key: (ID[Guild], ID[VoiceChannel])): Future[Option[ID[User]]] = {
39+
override def get(key: (ID[Guild], ID[AudioChannel])): Future[Option[ID[User]]] = {
3940
val (guild, channel) = key
4041
dbConfig.db.run(lookupQuery(guild, channel).result).map(_.headOption)
4142
}
4243

43-
override def update(key: (ID[Guild], ID[VoiceChannel]), value: ID[User]): Future[Int] = {
44+
override def update(key: (ID[Guild], ID[AudioChannel]), value: ID[User]): Future[Int] = {
4445
val (guild, channel) = key
4546
dbConfig.db.run(userByChannelTable.insertOrUpdate(guild, channel, value))
4647
}
4748

4849
// Duplicated here so as not to pull "conversions" object any higher
4950
private def idHack[T <: ISnowflake](s: T) = new ID[T](s.getIdLong)
5051

51-
def remove(channel: VoiceChannel): Future[Int] =
52+
def remove(channel: AudioChannel): Future[Int] =
5253
dbConfig.db.run(lookupQuery(idHack(channel.getGuild), idHack(channel)).delete)
5354

54-
override def remove(key: (ID[Guild], ID[VoiceChannel])): Future[Int] = {
55+
override def remove(key: (ID[Guild], ID[AudioChannel])): Future[Int] = {
5556
val (guild, channel) = key
5657
dbConfig.db.run(lookupQuery(guild, channel).delete)
5758
}
5859

59-
override def items: Future[Seq[((ID[Guild], ID[VoiceChannel]), ID[User])]] =
60+
override def items: Future[Seq[((ID[Guild], ID[AudioChannel]), ID[User])]] =
6061
dbConfig.db.run(userByChannelTable.result).map(_.map(t => ((t._1, t._2), t._3)))
6162
}

database-code/src/main/scala/score/discord/canti/collections/VoiceBanExpiryTable.scala

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package score.discord.canti.collections
22

3-
import net.dv8tion.jda.api.entities.{Guild, User, VoiceChannel}
3+
import net.dv8tion.jda.api.entities.{Guild, User}
4+
import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel
45
import score.discord.canti.functionality.voicekick.VoiceBanExpiry
56
import score.discord.canti.util.DBUtils
67
import score.discord.canti.wrappers.database.IDMapping._
@@ -12,15 +13,15 @@ import scala.concurrent.ExecutionContext.Implicits.global
1213
import scala.concurrent.Future
1314

1415
class VoiceBanExpiryTable(dbConfig: DatabaseConfig[_ <: JdbcProfile], tableName: String)
15-
extends AsyncMap[(ID[Guild], ID[VoiceChannel], ID[User]), VoiceBanExpiry] {
16+
extends AsyncMap[(ID[Guild], ID[AudioChannel], ID[User]), VoiceBanExpiry] {
1617

1718
import dbConfig.profile.api._
1819

1920
private class VoiceBanExpirySchema(tag: Tag, name: String)
20-
extends Table[(ID[Guild], ID[VoiceChannel], ID[User], Long, Boolean)](tag, name) {
21+
extends Table[(ID[Guild], ID[AudioChannel], ID[User], Long, Boolean)](tag, name) {
2122

2223
val guildId = column[ID[Guild]]("guild")
23-
val channelId = column[ID[VoiceChannel]]("channel")
24+
val channelId = column[ID[AudioChannel]]("channel")
2425
val userId = column[ID[User]]("user")
2526
val expiry = column[Long]("expiry_unix_timestamp")
2627
val explicitGrant = column[Boolean]("was_granted_explicitly")
@@ -35,29 +36,29 @@ class VoiceBanExpiryTable(dbConfig: DatabaseConfig[_ <: JdbcProfile], tableName:
3536
TableQuery[VoiceBanExpirySchema](new VoiceBanExpirySchema(_: Tag, tableName))
3637
private type C[T] = ConstColumn[ID[T]]
3738
private val lookupQuery =
38-
Compiled((guildId: C[Guild], vcId: C[VoiceChannel], userId: C[User]) => {
39+
Compiled((guildId: C[Guild], vcId: C[AudioChannel], userId: C[User]) => {
3940
voiceBanExipiryTable
4041
.filter { t => t.guildId === guildId && t.channelId === vcId && t.userId === userId }
4142
.map { row => (row.expiry, row.explicitGrant) }
4243
})
4344
DBUtils.ensureTableCreated(dbConfig, voiceBanExipiryTable, tableName)
4445

45-
override def get(key: (ID[Guild], ID[VoiceChannel], ID[User])): Future[Option[VoiceBanExpiry]] =
46+
override def get(key: (ID[Guild], ID[AudioChannel], ID[User])): Future[Option[VoiceBanExpiry]] =
4647
dbConfig.db.run(lookupQuery(key).result).map(_.headOption.map(VoiceBanExpiry.tupled))
4748

4849
override def update(
49-
key: (ID[Guild], ID[VoiceChannel], ID[User]),
50+
key: (ID[Guild], ID[AudioChannel], ID[User]),
5051
value: VoiceBanExpiry
5152
): Future[Int] =
5253
database.run(
5354
voiceBanExipiryTable
5455
.insertOrUpdate(key._1, key._2, key._3, value.timestamp, value.explicitGrant)
5556
)
5657

57-
override def remove(key: (ID[Guild], ID[VoiceChannel], ID[User])): Future[Int] =
58+
override def remove(key: (ID[Guild], ID[AudioChannel], ID[User])): Future[Int] =
5859
database.run(lookupQuery(key).delete)
5960

60-
override def items: Future[Seq[((ID[Guild], ID[VoiceChannel], ID[User]), VoiceBanExpiry)]] =
61+
override def items: Future[Seq[((ID[Guild], ID[AudioChannel], ID[User]), VoiceBanExpiry)]] =
6162
dbConfig.db
6263
.run(voiceBanExipiryTable.result)
6364
.map(_.map(t => ((t._1, t._2, t._3), VoiceBanExpiry(t._4, t._5))))

project/Dependencies.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import sbt._
22

33
object Dependencies {
44
lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.2.17"
5-
lazy val jda = ("net.dv8tion" % "JDA" % "4.4.1_353")
5+
lazy val jda = ("net.dv8tion" % "JDA" % "5.0.0-beta.15")
66
.exclude("net.java.dev.jna", "jna")
77
.exclude("club.minnced", "opus-java-api")
88
.exclude("club.minnced", "opus-java-natives")

src/main/scala/score/discord/canti/CantiBot.scala

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package score.discord.canti
22

33
import com.typesafe.config.ConfigFactory
44
import net.dv8tion.jda.api.entities.Activity
5-
import net.dv8tion.jda.api.events.ReadyEvent
65
import net.dv8tion.jda.api.hooks.EventListener
76
import net.dv8tion.jda.api.requests.GatewayIntent
87
import net.dv8tion.jda.api.utils.cache.CacheFlag
@@ -27,8 +26,9 @@ import scala.compiletime.uninitialized
2726
import scala.concurrent.duration.*
2827
import scala.jdk.CollectionConverters.*
2928
import scala.language.postfixOps
29+
import net.dv8tion.jda.api.events.session.ReadyEvent
3030

31-
@main def main() =
31+
@main def main(): Unit =
3232
CantiBot().start()
3333

3434
class CantiBot:
@@ -46,7 +46,7 @@ class CantiBot:
4646
config.token, {
4747
import GatewayIntent.*
4848
var intents =
49-
GUILD_EMOJIS :: /* &find */
49+
GUILD_EMOJIS_AND_STICKERS :: /* &find */
5050
GUILD_MESSAGE_REACTIONS :: /* Voice kick, &help, &spoiler, delete owned messages */
5151
GUILD_VOICE_STATES :: /* Voice kick, private voice chats */
5252
DIRECT_MESSAGES :: /* Same as GUILD_MESSAGES, plus spoiler-in-DM */
@@ -59,10 +59,12 @@ class CantiBot:
5959
intents.asJava
6060
}
6161
)
62+
.nn
6263
.disableCache({
6364
import CacheFlag.*
6465
util.Arrays.asList(ACTIVITY, CLIENT_STATUS, ONLINE_STATUS, ROLE_TAGS)
6566
})
67+
.nn
6668
val dbConfig = DatabaseConfig.forConfig[JdbcProfile]("database", rawConfig)
6769
executor = Executors.newScheduledThreadPool(Runtime.getRuntime.nn.availableProcessors).nn
6870
given Scheduler = Scheduler(executor)
@@ -72,7 +74,7 @@ class CantiBot:
7274
given messageCache: MessageCache = MessageCache()
7375
given ReplyCache = ReplyCache()
7476
val userCreatedChannels =
75-
UserByVoiceChannel(dbConfig, "user_created_channels") withCache LruCache.empty(2000)
77+
UserByAudioChannel(dbConfig, "user_created_channels") withCache LruCache.empty(2000)
7678

7779
val eventWaiter = EventWaiter()
7880
val commands = Commands()
@@ -140,17 +142,18 @@ class CantiBot:
140142
e.nn match
141143
case ev: ReadyEvent =>
142144
// TODO: Make configurable?
143-
ev.getJDA.getPresence
145+
val jda = ev.getJDA.nn
146+
jda.getPresence.nn
144147
.setActivity(Activity `playing` s"Usage: ${commands.prefix}${helpCommand.name}")
145-
ev.getJDA.setRequiredScopes("bot", "applications.commands")
148+
jda.setRequiredScopes("bot", "applications.commands")
146149
case _ =>
147150
}: EventListener,
148151
EventLogger()
149152
)
150153

151154
// The discord bot spawns off new threads and its event handlers expect
152155
// everything to have been set up, so this must come last.
153-
discord = Some(bot.build())
156+
discord = Some(bot.build().nn)
154157

155158
case Some(_) =>
156159
throw UnsupportedOperationException(

src/main/scala/score/discord/canti/collections/MessageCache.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package score.discord.canti.collections
22

3-
import net.dv8tion.jda.api.entities.{Message, MessageChannel}
3+
import net.dv8tion.jda.api.entities.Message
4+
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel
45
import net.dv8tion.jda.api.events.GenericEvent
56
import net.dv8tion.jda.api.events.message.{MessageReceivedEvent, MessageUpdateEvent}
67
import net.dv8tion.jda.api.hooks.EventListener
@@ -24,7 +25,7 @@ class MessageCache(capacity: Int = 2000) extends EventListener:
2425
}
2526

2627
protected def toBareMessage(message: Message): BareMessage =
27-
BareMessage(message.id, message.getChannel.id, message.getAuthor.id, message.getContentRaw)
28+
BareMessage(message.id, message.getChannel.nn.id, message.getAuthor.nn.id, message.getContentRaw.nn)
2829

2930
def findOrRetrieve(channel: MessageChannel, id: ID[Message]): Future[Option[BareMessage]] =
3031
this find {
@@ -41,13 +42,14 @@ class MessageCache(capacity: Int = 2000) extends EventListener:
4142

4243
override def onEvent(event: GenericEvent): Unit = event match
4344
case ev: MessageReceivedEvent =>
44-
val bareMessage = toBareMessage(ev.getMessage)
45+
val bareMessage = toBareMessage(ev.getMessage.nn)
4546
messages.synchronized {
4647
messages ::= bareMessage
4748
}
4849
case ev: MessageUpdateEvent =>
49-
val msgId = ev.getMessage.id
50+
val msg = ev.getMessage.nn
51+
val msgId = msg.id
5052
messages.synchronized {
51-
messages.findAndUpdate(_.messageId == msgId)(_.copy(text = ev.getMessage.getContentRaw))
53+
messages.findAndUpdate(_.messageId == msgId)(_.copy(text = msg.getContentRaw.nn))
5254
}
5355
case _ =>

src/main/scala/score/discord/canti/command/BotInfoCommand.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,22 @@ class BotInfoCommand(owner: ID[User]) extends GenericCommand:
3030
async {
3131
val jda = ctx.jda
3232
val allGuilds = jda.guilds
33-
val topGuilds = allGuilds.sortBy(-_.getMemberCache.size).take(10).map { guild =>
34-
val memberCount = guild.getMemberCache.size
35-
val owner = guild.getOwner.?.map(_.getUser).fold(s"unknown user ${guild.getOwnerIdLong}")(
33+
val topGuilds = allGuilds.sortBy(-_.getMemberCache.nn.size).take(10).map { guild =>
34+
val memberCount = guild.getMemberCache.nn.size
35+
val owner = guild.getOwner.?.map(_.getUser.nn).fold(s"unknown user ${guild.getOwnerIdLong}")(
3636
user => s"${user.name}#${user.discriminator}"
3737
)
3838
s"${guild.getName} ($memberCount users; owner: $owner)"
3939
}
40-
val me = await(jda.retrieveApplicationInfo.queueFuture())
40+
val me = await(jda.retrieveApplicationInfo.nn.queueFuture())
4141
await(
4242
ctx.invoker.reply(
4343
BotMessages
4444
.plain("Some basic bot info")
45-
.addField("Owner", s"<@$owner>", true)
46-
.addField("Servers", s"${allGuilds.size}", true)
47-
.addField("Top servers", topGuilds.mkString("\n"), false)
48-
.setThumbnail(me.getIconUrl)
45+
.addField("Owner", s"<@$owner>", true).nn
46+
.addField("Servers", s"${allGuilds.size}", true).nn
47+
.addField("Top servers", topGuilds.mkString("\n"), false).nn
48+
.setThumbnail(me.getIconUrl).nn
4949
)
5050
)
5151
}

0 commit comments

Comments
 (0)