Skip to content

Commit

Permalink
Add tempban
Browse files Browse the repository at this point in the history
  • Loading branch information
MrPowerGamerBR committed Sep 25, 2024
1 parent e2543bf commit a9d807a
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import net.perfectdreams.loritta.cinnamon.pudding.tables.BannedUsers
import net.perfectdreams.loritta.helper.LorittaHelper
import net.perfectdreams.loritta.helper.LorittaHelperKord
import net.perfectdreams.loritta.helper.tables.EconomyState
import net.perfectdreams.loritta.helper.utils.TimeUtils
import net.perfectdreams.loritta.helper.utils.extensions.await
import net.perfectdreams.loritta.helper.utils.slash.LoriToolsUtils
import net.perfectdreams.loritta.helper.utils.slash.PermissionLevel
Expand Down Expand Up @@ -215,6 +216,8 @@ class LoriToolsCommand(val helper: LorittaHelper) : SlashCommandDeclarationWrapp
val userIds = string("user_ids", "ID do usuário que você deseja banir (pode ser vários)")

val reason = string("reason", "Motivo que irá aparecer no ban")

val duration = optionalString("user_ids", "Por enquanto tempo o usuário está banido")
}

override val options = Options()
Expand All @@ -235,13 +238,17 @@ class LoriToolsCommand(val helper: LorittaHelper) : SlashCommandDeclarationWrapp
}

val reason = args[options.reason]
val durationAsString = args[options.duration]
val duration = if (durationAsString != null) {
TimeUtils.convertToMillisRelativeToNow(durationAsString)
} else null

banUser(
helper,
context,
userIds,
reason,
null
duration
)
}
}
Expand Down
149 changes: 149 additions & 0 deletions src/main/kotlin/net/perfectdreams/loritta/helper/utils/TimeUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package net.perfectdreams.loritta.helper.utils

import java.time.Duration
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit

object TimeUtils {
private val TIME_PATTERN = "(([01]?\\d|2[0-3]):([0-5]\\d?)(:([0-5]\\d))?) ?(am|pm)?".toPattern()
private val DATE_PATTERN = "(0[1-9]|[12][0-9]|3[01])[-/.](0[1-9]|1[012])[-/.]([0-9]+)".toPattern()
private val YEAR_PATTERN = "([0-9]+) ?(y|a)".toPattern()
private val MONTH_PATTERN = "([0-9]+) ?(month(s)?|m(e|ê)s(es)?)".toPattern()
private val WEEK_PATTERN = "([0-9]+) ?(w)".toPattern()
private val DAY_PATTERN = "([0-9]+) ?(d)".toPattern()
private val HOUR_PATTERN = "([0-9]+) ?(h)".toPattern()
private val SHORT_MINUTE_PATTERN = "([0-9]+) ?(m)".toPattern()
private val MINUTE_PATTERN = "([0-9]+) ?(min)".toPattern()
private val SECONDS_PATTERN = "([0-9]+) ?(s)".toPattern()
// TODO: Would be better to not hardcode it
val TIME_ZONE = ZoneId.of("America/Sao_Paulo")

fun convertToMillisRelativeToNow(input: String) = convertToLocalDateTimeRelativeToNow(input)
.toInstant()
.toEpochMilli()

fun convertToLocalDateTimeRelativeToNow(input: String) = convertToLocalDateTimeRelativeToTime(input, ZonedDateTime.now(TIME_ZONE))

fun convertToLocalDateTimeRelativeToTime(input: String, relativeTo: ZonedDateTime): ZonedDateTime {
val content = input.toLowerCase()
var localDateTime = relativeTo
.withNano(0)
var foundViaTime = false

// This is here instead of on the convertToMillisDurationRelative because durations don't have concept of "plus one month" (is it 31 or 30 days?)
val yearsMatcher = YEAR_PATTERN.matcher(content)
if (yearsMatcher.find()) {
val addYears = yearsMatcher.group(1).toLongOrNull() ?: 0
localDateTime = localDateTime.plus(addYears, ChronoUnit.YEARS)
}
val monthMatcher = MONTH_PATTERN.matcher(content)
if (monthMatcher.find()) {
val addMonths = monthMatcher.group(1).toLongOrNull() ?: 0
localDateTime = localDateTime.plus(addMonths, ChronoUnit.MONTHS)
}
val weekMatcher = WEEK_PATTERN.matcher(content)
if (weekMatcher.find()) {
val addWeeks = weekMatcher.group(1).toLongOrNull() ?: 0
localDateTime = localDateTime.plusDays(addWeeks)
}

if (content.contains(":")) { // horário
val matcher = TIME_PATTERN.matcher(content)

if (matcher.find()) { // Se encontrar...
val hour = matcher.group(2).toIntOrNull() ?: 0
val minute = matcher.group(3).toIntOrNull() ?: 0
val seconds = try {
matcher.group(5)?.toIntOrNull() ?: 0
} catch (e: IllegalStateException) {
0
}

var meridiem = try {
matcher.group(6)
} catch (e: IllegalStateException) {
null
}

// Horários que usam o meridiem
if (meridiem != null) {
meridiem = meridiem.replace(".", "").replace(" ", "")
if (meridiem.equals("pm", true)) { // Se for PM, aumente +12
localDateTime = localDateTime.withHour((hour % 12) + 12)
} else { // Se for AM, mantenha do jeito atual
localDateTime = localDateTime.withHour(hour % 12)
}
} else {
localDateTime = localDateTime.withHour(hour)
}
localDateTime = localDateTime
.withMinute(minute)
.withSecond(seconds)

foundViaTime = true
}
}

if (content.contains("/")) { // data
val matcher = DATE_PATTERN.matcher(content)

if (matcher.find()) { // Se encontrar...
val day = matcher.group(1).toIntOrNull() ?: 1
val month = matcher.group(2).toIntOrNull() ?: 1
val year = matcher.group(3).toIntOrNull() ?: 1999

// This is a hack
// This fixes bugs when you use "31/12/2024" on a month that does NOT have 31 days "Invalid date 'JUNE 31'"
localDateTime = localDateTime.withYear(1999)
.withMonth(1)
.withDayOfMonth(1)
.withYear(year)
.withMonth(month)
.withDayOfMonth(day)
}
} else if (foundViaTime && localDateTime.isBefore(LocalDateTime.now().atZone(TIME_ZONE))) {
// If it was found via time but there isn't any day set, we are going to check if it is in the past and, if true, we are going to add one day
localDateTime = localDateTime
.plusDays(1)
}

val duration = convertToMillisDurationRelative(content)
localDateTime = localDateTime.plus(duration)

return localDateTime
}

/**
* Converts a [content] into a [Duration]
*/
fun convertToMillisDurationRelative(content: String): Duration {
var duration = Duration.ZERO

val dayMatcher = DAY_PATTERN.matcher(content)
if (dayMatcher.find()) {
val addDays = dayMatcher.group(1).toLongOrNull() ?: 0
duration = duration.plus(addDays, ChronoUnit.DAYS)
}
val hourMatcher = HOUR_PATTERN.matcher(content)
if (hourMatcher.find()) {
val addHours = hourMatcher.group(1).toLongOrNull() ?: 0
duration = duration.plus(addHours, ChronoUnit.HOURS)
}

val minuteMatcher = MINUTE_PATTERN.matcher(content)
if (minuteMatcher.find()) {
val addMinutes = minuteMatcher.group(1).toLongOrNull() ?: 0
duration = duration.plus(addMinutes, ChronoUnit.MINUTES)
}

val secondsMatcher = SECONDS_PATTERN.matcher(content)
if (secondsMatcher.find()) {
val addSeconds = secondsMatcher.group(1).toLongOrNull() ?: 0
duration = duration.plus(addSeconds, ChronoUnit.SECONDS)
}

return duration
}
}

0 comments on commit a9d807a

Please sign in to comment.