Skip to content

Commit b580f29

Browse files
committed
Add guild premium key support
1 parent 9c5bdea commit b580f29

File tree

9 files changed

+97
-14
lines changed

9 files changed

+97
-14
lines changed

foxy/src/main/kotlin/net/cakeyfox/foxy/database/DatabaseClient.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import net.cakeyfox.foxy.FoxyInstance
99
import net.cakeyfox.foxy.database.data.FoxyUser
1010
import net.cakeyfox.foxy.database.data.FoxyverseGuild
1111
import net.cakeyfox.foxy.database.data.Guild
12+
import net.cakeyfox.foxy.database.data.Key
1213
import net.cakeyfox.foxy.database.data.YouTubeWebhook
1314
import net.cakeyfox.foxy.database.utils.BotUtils
1415
import net.cakeyfox.foxy.database.utils.GuildUtils
@@ -29,6 +30,7 @@ class DatabaseClient(
2930
lateinit var users: MongoCollection<FoxyUser>
3031
lateinit var foxyverseGuilds: MongoCollection<FoxyverseGuild>
3132
lateinit var youtubeWebhooks: MongoCollection<YouTubeWebhook>
33+
lateinit var premiumKeys: MongoCollection<Key>
3234
lateinit var database: MongoDatabase
3335

3436
val profile = ProfileUtils(this)
@@ -48,6 +50,7 @@ class DatabaseClient(
4850
guilds = database.getCollection("guilds")
4951
foxyverseGuilds = database.getCollection("foxyverses")
5052
youtubeWebhooks = database.getCollection("youtubeWebhooks")
53+
premiumKeys = database.getCollection("keys")
5154

5255
logger.info { "Connected to ${foxy.config.database.databaseName} database" }
5356
} catch (e: Exception) {

foxy/src/main/kotlin/net/cakeyfox/foxy/database/utils/GuildUtils.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class GuildUtils(
3333
}
3434
}
3535

36+
suspend fun getKeyByGuildId(guildId: String): Key? {
37+
return client.withRetry {
38+
val query = Document("usedBy", guildId)
39+
client.premiumKeys.find(query).firstOrNull()
40+
}
41+
}
3642

3743
suspend fun getGuild(guildId: String): Guild {
3844
return updateGuildWithNewFields(guildId)
@@ -79,6 +85,7 @@ class GuildUtils(
7985
antiRaidModule = AntiRaidModule(),
8086
AutoRoleModule = AutoRoleModule(),
8187
guildSettings = GuildSettings(),
88+
musicSettings = MusicSettings(),
8289
)
8390

8491
val documentToJSON = client.foxy.json.encodeToString(newGuild)
@@ -153,6 +160,7 @@ class GuildUtils(
153160
AutoRoleModule::class -> AutoRoleModule()
154161
WelcomerModule::class -> WelcomerModule()
155162
GuildSettings::class -> GuildSettings()
163+
MusicSettings::class -> MusicSettings()
156164
else -> null
157165
}
158166
}

foxy/src/main/kotlin/net/cakeyfox/foxy/database/utils/UserUtils.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ class UserUtils(
2929
private val client: DatabaseClient,
3030
private val foxy: FoxyInstance
3131
) {
32+
suspend fun getUserByPremiumKey(key: String): FoxyUser? {
33+
return client.withRetry {
34+
val collection = client.database.getCollection<Document>("keys")
35+
val userCollection = client.database.getCollection<Document>("users")
36+
val keyInfo = collection.find(eq("key", key)).firstOrNull()
37+
?: return@withRetry null
38+
val keyToJSON = keyInfo.toJson()
39+
val keyData = client.foxy.json.decodeFromString<Key>(keyToJSON)
40+
val user = userCollection.find(eq("_id", keyData.ownedBy)).firstOrNull()
41+
?: return@withRetry null
42+
val documentToJSON = user.toJson()
43+
44+
client.foxy.json.decodeFromString<FoxyUser>(documentToJSON)
45+
}
46+
}
47+
3248
suspend fun getFoxyProfile(userId: String): FoxyUser {
3349
return client.withRetry {
3450
val collection = client.database.getCollection<Document>("users")
@@ -44,8 +60,7 @@ class UserUtils(
4460
suspend fun getUserByToken(token: String): FoxyUser? {
4561
return client.withRetry {
4662
val collection = client.database.getCollection<Document>("users")
47-
val user = collection.find(eq("publicApiAccessToken", token)).firstOrNull() ?:
48-
return@withRetry null
63+
val user = collection.find(eq("publicApiAccessToken", token)).firstOrNull() ?: return@withRetry null
4964
val documentToJSON = user.toJson()
5065

5166
client.foxy.json.decodeFromString<FoxyUser>(documentToJSON)
@@ -208,7 +223,6 @@ class UserUtils(
208223
userSettings = UserSettings(language = "pt-br"),
209224
petInfo = PetInfo(),
210225
userTransactions = emptyList(),
211-
premiumKeys = emptyList(),
212226
roulette = Roulette(),
213227
)
214228

foxy/src/main/kotlin/net/cakeyfox/foxy/interactions/vanilla/music/PlayExecutor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class PlayExecutor : UnleashedCommandExecutor() {
1616
val query = context.getOption("query", 0, String::class.java, true)
1717

1818
if (query.isNullOrBlank()) {
19-
context.reply() {
19+
context.reply {
2020
content = pretty(FoxyEmotes.FoxyCry, context.locale["music.play.youMustProvideASong"])
2121
}
2222
return

foxy/src/main/kotlin/net/cakeyfox/foxy/interactions/vanilla/music/QueueExecutor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import net.cakeyfox.common.FoxyEmotes
66
import net.cakeyfox.foxy.interactions.commands.CommandContext
77
import net.cakeyfox.foxy.interactions.commands.UnleashedCommandExecutor
88
import net.cakeyfox.foxy.interactions.pretty
9+
import net.cakeyfox.foxy.utils.PremiumUtils
910
import net.dv8tion.jda.api.components.buttons.ButtonStyle
1011

1112
class QueueExecutor : UnleashedCommandExecutor() {
@@ -38,6 +39,7 @@ class QueueExecutor : UnleashedCommandExecutor() {
3839

3940
val trackList = StringBuilder()
4041
val currentTrack = manager.getPlayer()?.track
42+
val maximumQueueSize = PremiumUtils.getMaxQueueSize(context)
4143
trackList.append("➤ **${currentTrack?.info?.author}** - ${currentTrack?.info?.title}\n\n")
4244

4345
for ((index, track) in tracks.withIndex()) {
@@ -56,7 +58,7 @@ class QueueExecutor : UnleashedCommandExecutor() {
5658
thumbnail = currentTrack?.info?.artworkUrl ?: Constants.FOXY_FUMO
5759

5860
footer {
59-
name = context.locale["music.queue.totalTracks", "${tracks.size}"]
61+
name = context.locale["music.queue.totalTracks", "${tracks.size}/$maximumQueueSize"]
6062
}
6163
}
6264

foxy/src/main/kotlin/net/cakeyfox/foxy/listeners/GuildListener.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,19 @@ class GuildListener(private val foxy: FoxyInstance) : ListenerAdapter() {
3636
override fun onGuildVoiceUpdate(event: GuildVoiceUpdateEvent) {
3737
coroutineScope.launch(foxy.coroutineDispatcher) {
3838
val isFoxyConnected = event.guild.selfMember.voiceState?.inAudioChannel() == true
39+
val guild = foxy.database.guild.getGuild(event.guild.id)
3940

4041
if (isFoxyConnected) {
4142
val members = event.guild.selfMember.voiceState?.channel?.members ?: return@launch
4243
val channelMembers = members.filterNot { it.user.isBot }
4344

45+
guild.musicSettings?.leaveOnEmptyChannel?.let {
46+
if (!it) {
47+
logger.info { "Not leaving voice channel in guild ${event.guild.name} - ${event.guild.id} because 24/7 mode is enabled" }
48+
return@launch
49+
}
50+
}
51+
4452
if (channelMembers.isEmpty()) {
4553
logger.info { "Starting inactivity timer in guild ${event.guild.name} - ${event.guild.id}" }
4654
delay(30_000)

foxy/src/main/kotlin/net/cakeyfox/foxy/listeners/MessageListener.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ import net.cakeyfox.foxy.FoxyInstance
1212
import net.cakeyfox.foxy.interactions.MessageCommandContext
1313
import net.cakeyfox.foxy.utils.locales.FoxyLocale
1414
import net.cakeyfox.foxy.interactions.pretty
15+
import net.cakeyfox.foxy.utils.PremiumUtils
1516
import net.cakeyfox.foxy.utils.discord.NitroUtils
17+
import net.cakeyfox.foxy.utils.joinInAVoiceChannel
18+
import net.cakeyfox.foxy.utils.music.AudioLoader
19+
import net.cakeyfox.foxy.utils.music.getOrCreateMusicManager
20+
import net.cakeyfox.foxy.utils.music.processQuery
1621
import net.dv8tion.jda.api.entities.channel.ChannelType
1722
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
1823
import net.dv8tion.jda.api.hooks.ListenerAdapter
@@ -28,12 +33,37 @@ class MessageListener(val foxy: FoxyInstance) : ListenerAdapter() {
2833

2934
scope.launch {
3035
processCommandOrMention(event)
36+
processDjFoxyMessage(event)
3137
// if (event.member?.isBoosting == true) {
3238
// processNitroBoost(event)
3339
// }
3440
}
3541
}
3642

43+
private suspend fun processDjFoxyMessage(event: MessageReceivedEvent) {
44+
val guild = foxy.database.guild.getGuild(event.guild.id)
45+
if (guild.musicSettings?.requstMusicChannel != event.channel.id) return
46+
47+
val raw = event.message.contentRaw
48+
if (raw.startsWith(guild.guildSettings.prefix)) return
49+
50+
val context = MessageCommandContext(event, foxy)
51+
val channel = joinInAVoiceChannel(context) ?: return
52+
val maximumQueueSize = PremiumUtils.getMaxQueueSize(context)
53+
val link = context.foxy.lavalink.getOrCreateLink(context.guild.idLong)
54+
val manager = getOrCreateMusicManager(context.guild.idLong, context.foxy.lavalink, context, channel)
55+
val queueSize = manager.scheduler.queue.size + 1
56+
57+
if (queueSize >= maximumQueueSize) {
58+
context.reply(true) {
59+
content = pretty(FoxyEmotes.FoxyCry, context.locale["music.play.queueLimitReached", "100"])
60+
}
61+
return
62+
}
63+
64+
link.loadItem(processQuery(raw)).subscribe(AudioLoader(context, manager))
65+
}
66+
3767
private suspend fun processNitroBoost(event: MessageReceivedEvent) {
3868
val member = event.member ?: return
3969
val guildAsFoxyverseGuild = foxy.database.guild.getFoxyverseGuildOrNull(event.guild.id) ?: return

foxy/src/main/kotlin/net/cakeyfox/foxy/utils/PremiumUtils.kt

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,36 @@ import net.cakeyfox.foxy.database.data.FoxyUser
66
import kotlin.time.Duration.Companion.days
77

88
object PremiumUtils {
9+
suspend fun getMaxQueueSize(context: CommandContext): Int {
10+
val guildKey = context.database.guild.getKeyByGuildId(context.guildId!!) ?: return 100
11+
val user = context.database.user.getUserByPremiumKey(guildKey.key)
12+
13+
if (user != null && isUserPremium(user)) {
14+
return when (getPremiumType(user)) {
15+
1 -> 200
16+
2 -> 300
17+
3 -> 500
18+
else -> 100
19+
}
20+
}
21+
22+
return 100
23+
}
24+
925
suspend fun maximumYouTubeChannels(context: CommandContext): Int {
10-
val user = context.database.user.getFoxyProfile(context.user.id)
26+
val guildKey = context.database.guild.getKeyByGuildId(context.guildId!!) ?: return 3
27+
val user = context.database.user.getUserByPremiumKey(guildKey.key)
1128

12-
if (isUserPremium(user)) {
13-
val premiumType = getPremiumType(user)
14-
return when(premiumType) {
15-
1 -> 5 // Max 5 channels
16-
2 -> 10 // Max 10 channels
17-
3 -> 15 // Max 15 channels
29+
if (user != null && isUserPremium(user)) {
30+
return when (getPremiumType(user)) {
31+
1 -> 5
32+
2 -> 10
33+
3 -> 15
1834
else -> 3
1935
}
20-
} else return 3
36+
}
37+
38+
return 3
2139
}
2240

2341
suspend fun eligibleForEarlyAccess(context: CommandContext): Boolean {

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ dependencyResolutionManagement {
3030
// Database
3131
library("mongodb-bson", "org.mongodb", "bson-kotlinx").version("5.5.0")
3232
library("mongodb-coroutine-driver", "org.mongodb", "mongodb-driver-kotlin-coroutine").version("5.5.0")
33-
library("foxy-databaseutils", "com.github.CakeyFox", "DatabaseUtils").version("1.1.8")
33+
library("foxy-databaseutils", "com.github.CakeyFox", "DatabaseUtils").version("1.2.1")
3434

3535
// Ktor
3636
library("ktor-htmx", "io.ktor", "ktor-htmx").versionRef(ktor)

0 commit comments

Comments
 (0)