Skip to content

Commit 03c824c

Browse files
authored
Merge pull request #49 from the-programmers-hangout/fix/ban
feat: initialise existing bans upon bot restart
2 parents e0b337e + c6dd10a commit 03c824c

File tree

6 files changed

+63
-22
lines changed

6 files changed

+63
-22
lines changed

src/main/kotlin/me/ddivad/judgebot/Main.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import com.gitlab.kordlib.gateway.Intent
44
import com.gitlab.kordlib.gateway.PrivilegedIntent
55
import me.ddivad.judgebot.dataclasses.Configuration
66
import me.ddivad.judgebot.services.BotStatsService
7+
import me.ddivad.judgebot.services.LoggingService
78
import me.ddivad.judgebot.services.infractions.MuteService
89
import me.ddivad.judgebot.services.PermissionsService
10+
import me.ddivad.judgebot.services.infractions.BanService
911
import me.ddivad.judgebot.services.requiredPermissionLevel
1012
import me.jakejmattson.discordkt.api.dsl.bot
1113
import me.jakejmattson.discordkt.api.extensions.addInlineField
@@ -81,8 +83,9 @@ suspend fun main(args: Array<String>) {
8183
}
8284

8385
onStart {
84-
val muteService = this.getInjectionObjects(MuteService::class)
86+
val (muteService, banService, loggingService) = this.getInjectionObjects(MuteService::class, BanService::class, LoggingService::class)
8587
muteService.initGuilds()
88+
banService.initialiseBanTimers()
8689
}
8790

8891
intents {

src/main/kotlin/me/ddivad/judgebot/commands/InfractionCommands.kt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,24 @@ import me.jakejmattson.discordkt.api.dsl.commands
1818

1919
@Suppress("unused")
2020
fun createInfractionCommands(databaseService: DatabaseService,
21-
config: Configuration,
22-
infractionService: InfractionService,
23-
badPfpService: BadPfpService) = commands("Infraction") {
21+
config: Configuration,
22+
infractionService: InfractionService,
23+
badPfpService: BadPfpService) = commands("Infraction") {
2424
guildCommand("strike", "s") {
2525
description = "Strike a user."
2626
requiredPermissionLevel = PermissionLevel.Staff
2727
execute(LowerMemberArg, IntegerArg.makeOptional(1), EveryArg) {
2828
val (targetMember, weight, reason) = args
29+
val guildConfiguration = config[guild.id.longValue] ?: return@execute
30+
val maxStrikes = guildConfiguration.infractionConfiguration.pointCeiling / 10
31+
if (weight > maxStrikes) {
32+
respond("Maximum strike weight is **$maxStrikes (${guildConfiguration.infractionConfiguration.pointCeiling} points)**")
33+
return@execute
34+
}
2935
try {
3036
targetMember.testDmStatus()
3137
} catch (ex: RequestException) {
32-
respond("Unable to contact the target user. Infraction cancelled.")
38+
respond("Target user has DM's disabled. Infraction cancelled.")
3339
return@execute
3440
}
3541
StrikeConversation(databaseService, config, infractionService)
@@ -46,7 +52,7 @@ fun createInfractionCommands(databaseService: DatabaseService,
4652
try {
4753
targetMember.testDmStatus()
4854
} catch (ex: RequestException) {
49-
respond("Unable to contact the target user. Infraction cancelled.")
55+
respond("Target user has DM's disabled. Infraction cancelled.")
5056
return@execute
5157
}
5258
val guildConfiguration = config[guild.id.longValue] ?: return@execute
@@ -67,7 +73,7 @@ fun createInfractionCommands(databaseService: DatabaseService,
6773
try {
6874
targetMember.testDmStatus()
6975
} catch (ex: RequestException) {
70-
respond("Unable to contact the target user. Infraction cancelled.")
76+
respond("Target user has DM's disabled. Infraction cancelled.")
7177
return@execute
7278
}
7379
val minutesUntilBan = 30L

src/main/kotlin/me/ddivad/judgebot/services/LoggingService.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,11 @@ class LoggingService(private val configuration: Configuration) {
6262
suspend fun badPfpBan(guild: Guild, user: Member) =
6363
log(guild, "**Info ::** User ${user.mention} banned for not changing their avatar")
6464

65-
suspend fun muteSetup(guild: Guild, role: Role) =
66-
log(guild, "**Info ::** Adding muted role overrides for ${role.mention} :: ${role.id.value}")
65+
suspend fun initialiseMutes(guild: Guild, role: Role) =
66+
log(guild, "**Info ::** Existing mute timers initialized using ${role.mention} :: ${role.id}")
67+
68+
suspend fun initialiseBans(guild: Guild) =
69+
log(guild, "**Info ::** Existing ban timers initialized.")
6770

6871
private suspend fun log(guild: Guild, message: String) = getLoggingChannel(guild)?.createMessage(message)
6972

src/main/kotlin/me/ddivad/judgebot/services/infractions/BanService.kt

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,21 @@ import kotlinx.coroutines.GlobalScope
88
import kotlinx.coroutines.Job
99
import kotlinx.coroutines.delay
1010
import kotlinx.coroutines.launch
11-
import me.ddivad.judgebot.dataclasses.Ban
12-
import me.ddivad.judgebot.dataclasses.InfractionType
13-
import me.ddivad.judgebot.dataclasses.Punishment
11+
import me.ddivad.judgebot.dataclasses.*
1412
import me.ddivad.judgebot.services.DatabaseService
1513
import me.ddivad.judgebot.services.LoggingService
14+
import me.jakejmattson.discordkt.api.Discord
1615
import me.jakejmattson.discordkt.api.annotations.Service
16+
import me.jakejmattson.discordkt.api.extensions.toSnowflake
17+
import org.joda.time.DateTime
1718

1819
@Service
1920
class BanService(private val databaseService: DatabaseService,
20-
private val loggingService: LoggingService) {
21-
private val banTracker = hashMapOf<Int, Job>()
22-
private suspend fun toKey(member: Member): Pair<GuildID, UserId> = member.guild.id.value to member.asUser().id.value
21+
private val loggingService: LoggingService,
22+
private val configuration: Configuration,
23+
private val discord: Discord) {
24+
private val banTracker = hashMapOf<Pair<UserId, GuildID>, Job>()
25+
private fun toKey(user: User, guild: Guild): Pair<GuildID, UserId> = user.id.value to guild.id.value
2326

2427
suspend fun banUser(target: Member, guild: Guild, punishment: Punishment, deleteDays: Int = 1) {
2528
guild.ban(target.id) {
@@ -29,7 +32,8 @@ class BanService(private val databaseService: DatabaseService,
2932
databaseService.guilds.addBan(guild, Ban(target.id.value, punishment.moderator, punishment.reason))
3033
if (punishment.clearTime != null) {
3134
databaseService.guilds.addPunishment(guild.asGuild(), punishment)
32-
banTracker[punishment.id] = GlobalScope.launch {
35+
val key = toKey(target.asUser(), guild)
36+
banTracker[key] = GlobalScope.launch {
3337
delay(punishment.clearTime)
3438
guild.unban(target.id)
3539
}
@@ -38,13 +42,33 @@ class BanService(private val databaseService: DatabaseService,
3842
}
3943

4044
suspend fun unbanUser(guild: Guild, user: User) {
45+
val key = toKey(user, guild)
4146
if (databaseService.guilds.getPunishmentsForUser(guild, user).any { it.type == InfractionType.Ban }) {
42-
val punishment = databaseService.guilds.getPunishmentByType(guild, user.id.value, InfractionType.Ban).first()
4347
databaseService.guilds.removePunishment(guild, user.id.value, InfractionType.Ban)
44-
banTracker[punishment.id]?.cancel()
48+
banTracker[key]?.cancel()
4549
}
4650
guild.unban(user.id)
4751
databaseService.guilds.removeBan(guild, user.id.value)
4852
loggingService.userUnbanned(guild, user)
4953
}
54+
55+
suspend fun initialiseBanTimers() {
56+
configuration.guildConfigurations.forEach { config ->
57+
val guild = config.value.id.toSnowflake().let { discord.api.getGuild(it) } ?: return@forEach
58+
databaseService.guilds.getPunishmentsForGuild(guild, InfractionType.Ban).forEach() {
59+
if (it.clearTime != null) {
60+
val difference = it.clearTime - DateTime.now().millis
61+
guild.kord.getUser(it.userId.toSnowflake())?.let { user ->
62+
val key = toKey(user, guild)
63+
banTracker[key] = GlobalScope.launch {
64+
delay(difference)
65+
guild.unban(user.id)
66+
}
67+
}
68+
loggingService.initialiseBans(guild)
69+
}
70+
}
71+
}
72+
73+
}
5074
}

src/main/kotlin/me/ddivad/judgebot/services/infractions/InfractionService.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package me.ddivad.judgebot.services.infractions
22

33
import com.gitlab.kordlib.core.entity.Guild
44
import com.gitlab.kordlib.core.entity.Member
5+
import kotlinx.coroutines.Job
56
import me.ddivad.judgebot.dataclasses.*
67
import me.ddivad.judgebot.embeds.createInfractionEmbed
78
import me.ddivad.judgebot.services.DatabaseService
@@ -16,6 +17,10 @@ class InfractionService(private val configuration: Configuration,
1617
private val loggingService: LoggingService,
1718
private val banService: BanService,
1819
private val muteService: MuteService) {
20+
21+
private val punishmentTimerMap = hashMapOf<Pair<Int, GuildID>, Job>()
22+
private fun toKey(punishment: Punishment, guild: Guild) = punishment.id to guild.id.value
23+
1924
suspend fun infract(target: Member, guild: Guild, userRecord: GuildMember, infraction: Infraction): Infraction {
2025
var rule: Rule? = null
2126
if (infraction.ruleNumber != null) {

src/main/kotlin/me/ddivad/judgebot/services/infractions/MuteService.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class MuteService(val configuration: Configuration,
4444
suspend fun initGuilds() {
4545
configuration.guildConfigurations.forEach { config ->
4646
val guild = config.value.id.toSnowflake().let { discord.api.getGuild(it) } ?: return@forEach
47-
handleExistingMutes(guild)
47+
initialiseMuteTimers(guild)
4848
setupMutedRole(guild)
4949
}
5050
}
@@ -95,7 +95,7 @@ class MuteService(val configuration: Configuration,
9595
}
9696
}
9797

98-
private suspend fun handleExistingMutes(guild: Guild) {
98+
private suspend fun initialiseMuteTimers(guild: Guild) {
9999
databaseService.guilds.getPunishmentsForGuild(guild, InfractionType.Mute).forEach {
100100
if (it.clearTime != null) {
101101
val difference = it.clearTime - DateTime.now().millis
@@ -106,6 +106,7 @@ class MuteService(val configuration: Configuration,
106106
removeMute(guild, user)
107107
}
108108
}
109+
loggingService.initialiseMutes(guild, getMutedRole(guild))
109110
}
110111
}
111112

@@ -129,7 +130,6 @@ class MuteService(val configuration: Configuration,
129130

130131
private suspend fun setupMutedRole(guild: Guild) {
131132
val mutedRole = guild.getRole(configuration[guild.id.longValue]!!.mutedRole.toSnowflake())
132-
loggingService.muteSetup(guild, mutedRole)
133133
guild.channels.toList().forEach {
134134
val deniedPermissions = it.getPermissionOverwritesForRole(mutedRole.id)?.denied ?: Permissions()
135135
if (!deniedPermissions.contains(Permission.SendMessages) || !deniedPermissions.contains(Permission.AddReactions)) {
@@ -140,7 +140,7 @@ class MuteService(val configuration: Configuration,
140140
denied = deniedPermissions.plus(Permission.SendMessages).plus(Permission.AddReactions))
141141
)
142142
} catch (ex: RequestException) {
143-
println("No permssions to add overwrite to ${it.id.value}")
143+
println("No permssions to add overwrite to ${it.id.value} - ${it.name}")
144144
}
145145

146146
}

0 commit comments

Comments
 (0)