Skip to content

Commit

Permalink
Merge pull request #268 from HyacinthBots/develop
Browse files Browse the repository at this point in the history
Release 4.1.0
  • Loading branch information
tempest15 committed Sep 29, 2022
2 parents b522b8e + 4c4d244 commit 08b755a
Show file tree
Hide file tree
Showing 44 changed files with 1,671 additions and 1,061 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ plugins {
}

group = "org.hyacinthbots.lilybot"
version = "4.0.1"
version = "4.1.0"

repositories {
mavenCentral()
Expand Down
29 changes: 29 additions & 0 deletions docs/changelogs/4.1.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# LilyBot 4.1.0

This release tracks down many old bugs, fixes a lot of errors, and adds a nice new feature or two.
You can find the full changelog below.

New:
* message edit logging
* add an announcements system to allow distribution of messages across every guild Lily is in
* command to completely reset the database for a guild
* command to view set configs
* log when message tags are sent

Change:
* require only the bare minimum config for each feature,
with additional functionality coming with additional configs
* re-add member counts to member logging
* images can now be attached to commands directly rather than providing a link
* check that Lily can view and send messages in configured channels
* check that roles can be pinged before adding them to the database

Fix:
* "required content missing" errors in log uploading
* broken reminder interval field
* missing parameter on log uploading command
* log channel name instead of enabled or disabled when setting a utility log
* inconsistent timestamps when editing messages sent through Lily
* pk;e being logged as a deleted message

You can find a list of all the commits in this update [here](https://github.com/hyacinthbots/LilyBot/compare/v4.0.1...v4.1.0)
46 changes: 46 additions & 0 deletions docs/changelogs/changelog-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# LilyBot X.X.X

Throughout this file, examples are placed in code blocks.

X.X.X above should be replaced with the version number where
* breaking versions are something that requires a significant change in the environment to run Lily
* major versions have a fair few features, changes, and fixes
* minor versions are simply a patch

Next should be a description of the features of the update.
```
This long-awaited update rewrites Lily in Rust. This will be the last update, as the bot is now perfect.
```

It's important that this end with the following statement.
```
You can find the full changelog below.
```

The changelog should then be split into three categories: New, Change, & Fix.
These are fairly self-explanatory buckets, with new features going in the first,
changes to existing functionality going in the second, and restorations of intended functionality in the third.

```
New:
* very memory safe
* lots of crabs
Change:
* use rust instead of Kotlin
* auto-ban anyone who says the word Kotlin
Fix:
* literally every bug, Rust is perfect
* we've even fixed bugs Discord hasn't thought of
```

The changelog should then end with the following
```
You can find a list of all the commits in this update [here](https://github.com/hyacinthbots/LilyBot/compare/vP.P.P...vX.X.X)
```
where P.P.P is replaced with the previous version number and X.X.X is the new version number.

The changelog should be copied and pasted into the GitHub release, excepting the header.
This changelog can then be trimmed or adjusted if necessary for publication on Discord.
If need be, a more concise version can be sent out via the Lily's announcement system.
18 changes: 12 additions & 6 deletions docs/commanddocs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ name = "config clear"
args = "* `config-type` - The type of config to clear, 'support', 'moderation', 'logging', 'miscellaneous', 'all' - String Choice"
result = "Clears the config of the specified type."
permissions = "Manage Guild"

[[command]]
category = "Administration commands"
name = "announcement"
result = "Produces a modal for inputting the announcement content, then sends it to every guild the bot is in. Only works in the bots `TEST_GUILD_ID`"
permissions = "Administrator"
# End administration commands

# Moderation commands
Expand All @@ -54,35 +60,35 @@ permissions = "Manage Messages"
[[command]]
category = "Moderation commands"
name = "ban"
args = "* `user` – Person to ban - User\n* `messages` - Number of days of messages to delete - Integer\n* `reason` - Reason for the ban - Optional String\n* `image` - The URL to an image to provide extra context for the action - Optional String\n* `dm` - Whether to DM the user or not. Default: True - Optional Boolean"
args = "* `user` – Person to ban - User\n* `messages` - Number of days of messages to delete - Integer\n* `reason` - Reason for the ban - Optional String\n* `image` - An image to provide extra context for the action - Optional Attachment\n* `dm` - Whether to DM the user or not. Default: True - Optional Boolean"
result = "Bans `banUser` from the server with reason `reason` and deletes any messages they sent in the last `messages` day(s)."
permissions = "Ban Members"

[[command]]
category = "Moderation commands"
name = "unban"
args = "* `user ` - The Discord ID of the person to unban - User ID"
args = "* `user ` - The Discord ID (Snowflake) of the person to unban - User ID"
result = "The user with the ID `unbanUserId` is unbanned."
permissions = "Ban Members"

[[command]]
category = "Moderation commands"
name = "soft-ban"
args = "* `user` - Person to soft ban - User\n* `messages` - Number of days of messages to delete - Integer (default 3)\n* `reason` - Reason for the ban - Optional String\n* `image` - The URL to an image to provide extra context for the action - Optional String\n* `dm` - Whether to DM the user or not. Default: True - Optional Boolean"
args = "* `user` - Person to soft ban - User\n* `messages` - Number of days of messages to delete - Integer (default 3)\n* `reason` - Reason for the ban - Optional String\n* `image` - An image to provide extra context for the action - Optional Attachment\n* `dm` - Whether to DM the user or not. Default: True - Optional Boolean"
result = "Bans `softBanUser`, deletes the last `messages` days of messages from them, and unbans them."
permissions = "Ban Members"

[[command]]
category = "Moderation commands"
name = "warn"
args = "* `user` - Person to warn - User\n* `reason` - Reason for warn - Optional String\n* `image` - The URL to an image to provide extra context for the action - Optional String\n* `dm` - Whether to DM the user or not. Default: True - Optional Boolean"
args = "* `user` - Person to warn - User\n* `reason` - Reason for warn - Optional String\n* `image` - An image to provide extra context for the action - Optional Attachment\n* `dm` - Whether to DM the user or not. Default: True - Optional Boolean"
result = "Warns `warnUser` with a DM and adds a strike to their points total. Depending on their new points total, action is taken based on the below table.\n\n| Points | Sanction |\n|:------:|:----------------:|\n| 1 | None. |\n| 2 | 3 hour timeout. |\n| 3 | 12 hour timeout. |\n| 3+ | 3 day timeout. |"
permissions = "Moderate Members"

[[command]]
category = "Moderation commands"
name = "timeout"
args = "* `user` - Person to timeout - User\n* `duration` - Duration of timeout - Duration [e.g. 6h or 30s] (default 6h)\n* `reason` - Reason for timeout - Optional String\n* `image` - The URL to an image to provide extra context for the action - Optional String\n* `dm` - Whether to DM the user or not. Default: True - Optional Boolean"
args = "* `user` - Person to timeout - User\n* `duration` - Duration of timeout - Duration [e.g. 6h or 30s] (default 6h)\n* `reason` - Reason for timeout - Optional String\n* `image` - An image to provide extra context for the action - Optional Attachment\n* `dm` - Whether to DM the user or not. Default: True - Optional Boolean"
result = "Times `timeoutUser` out for `duration`. A timeout is Discord's built-in mute function."
permissions = "Moderate Members"

Expand Down Expand Up @@ -156,7 +162,7 @@ permissions = "Moderate Members"
[[command]]
category = "Utility commands"
name = "edit-say"
args = "(Moderators only)\n* `message-to-edit` - The ID of the message contain the embed you'd like to edit - Snowflake\n* `new-content` - The new content for the message - Optional String\n* `new-color` - The new color for the embed - Optional Color (default: Blurple)\n* `channel-of-message` - The channel the embed was originally sent in - Optional channel (default: Channel command was executed in)\n* `timestamp` - Whether to add the timestamp of when the message was originally sent or not - Optional boolean (default: true)"
args = "(Moderators only)\n* `message-to-edit` - The ID of the message contain the embed you'd like to edit - Snowflake\n* `new-content` - The new content for the message - Optional String\n* `new-color` - The new color for the embed - Optional Color (default: Blurple)\n* `channel-of-message` - The channel the embed was originally sent in - Optional channel (default: Channel command was executed in)\n* `timestamp` - Whether to add the timestamp of when the message was originally sent or not - Optional boolean"
result = "Edited message/embed"
permissions = "Moderate Members"

Expand Down
24 changes: 18 additions & 6 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ These are commands for the maintenance of LilyBot. The can only be run by Server

---

### Name: `announcement`
**Arguments**:
None

**Result**: Produces a modal for inputting the announcement content, then sends it to every guild the bot is in. Only works in the bots `TEST_GUILD_ID`

**Required Permissions**: `Administrator`

**Command category**: `Administration commands`

---


## Moderation commands
These commands are for use by moderators. They utilize built-in permission checks. All moderation commands are logged to the modActionLog established in the config. A Direct Message is sent to the target user containing the sanction they received and the provided reason. If Lily fails to DM them, this failure will be noted in the logging embed.
Expand All @@ -99,7 +111,7 @@ These commands are for use by moderators. They utilize built-in permission check
* `user` – Person to ban - User
* `messages` - Number of days of messages to delete - Integer
* `reason` - Reason for the ban - Optional String
* `image` - The URL to an image to provide extra context for the action - Optional String
* `image` - An image to provide extra context for the action - Optional Attachment
* `dm` - Whether to DM the user or not. Default: True - Optional Boolean

**Result**: Bans `banUser` from the server with reason `reason` and deletes any messages they sent in the last `messages` day(s).
Expand All @@ -112,7 +124,7 @@ These commands are for use by moderators. They utilize built-in permission check

### Name: `unban`
**Arguments**:
* `user ` - The Discord ID of the person to unban - User ID
* `user ` - The Discord ID (Snowflake) of the person to unban - User ID

**Result**: The user with the ID `unbanUserId` is unbanned.

Expand All @@ -127,7 +139,7 @@ These commands are for use by moderators. They utilize built-in permission check
* `user` - Person to soft ban - User
* `messages` - Number of days of messages to delete - Integer (default 3)
* `reason` - Reason for the ban - Optional String
* `image` - The URL to an image to provide extra context for the action - Optional String
* `image` - An image to provide extra context for the action - Optional Attachment
* `dm` - Whether to DM the user or not. Default: True - Optional Boolean

**Result**: Bans `softBanUser`, deletes the last `messages` days of messages from them, and unbans them.
Expand All @@ -142,7 +154,7 @@ These commands are for use by moderators. They utilize built-in permission check
**Arguments**:
* `user` - Person to warn - User
* `reason` - Reason for warn - Optional String
* `image` - The URL to an image to provide extra context for the action - Optional String
* `image` - An image to provide extra context for the action - Optional Attachment
* `dm` - Whether to DM the user or not. Default: True - Optional Boolean

**Result**: Warns `warnUser` with a DM and adds a strike to their points total. Depending on their new points total, action is taken based on the below table.
Expand All @@ -165,7 +177,7 @@ These commands are for use by moderators. They utilize built-in permission check
* `user` - Person to timeout - User
* `duration` - Duration of timeout - Duration [e.g. 6h or 30s] (default 6h)
* `reason` - Reason for timeout - Optional String
* `image` - The URL to an image to provide extra context for the action - Optional String
* `image` - An image to provide extra context for the action - Optional Attachment
* `dm` - Whether to DM the user or not. Default: True - Optional Boolean

**Result**: Times `timeoutUser` out for `duration`. A timeout is Discord's built-in mute function.
Expand Down Expand Up @@ -306,7 +318,7 @@ None
* `new-content` - The new content for the message - Optional String
* `new-color` - The new color for the embed - Optional Color (default: Blurple)
* `channel-of-message` - The channel the embed was originally sent in - Optional channel (default: Channel command was executed in)
* `timestamp` - Whether to add the timestamp of when the message was originally sent or not - Optional boolean (default: true)
* `timestamp` - Whether to add the timestamp of when the message was originally sent or not - Optional boolean

**Result**: Edited message/embed

Expand Down
10 changes: 5 additions & 5 deletions libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[versions]
kotlin = "1.7.10" # Note: Plugin versions must be updated in the settings.gradle.kts too

groovy = "3.0.12"
kord-extensions = "1.5.5-20220831.110202-26"
logging = "2.1.23"
groovy = "3.0.13"
kord-extensions = "1.5.5-20220925.092000-32"
logging = "2.1.23" # Cannot be updated to 3.0.0 because we need newer logback, which requires an XML file, which throws errors I cannot fix
logback = "1.2.8"
github-api = "1.308"
kmongo = "4.7.0"
github-api = "1.313"
kmongo = "4.7.1"
detekt = "1.21.0"
koma = "1.1.0"

Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/org/hyacinthbots/lilybot/LilyBot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ import org.hyacinthbots.lilybot.extensions.config.GuildLogging
import org.hyacinthbots.lilybot.extensions.events.LogUploading
import org.hyacinthbots.lilybot.extensions.events.MemberLogging
import org.hyacinthbots.lilybot.extensions.events.MessageDelete
import org.hyacinthbots.lilybot.extensions.events.MessageEdit
import org.hyacinthbots.lilybot.extensions.events.ThreadInviter
import org.hyacinthbots.lilybot.extensions.moderation.Report
import org.hyacinthbots.lilybot.extensions.moderation.TemporaryModeration
import org.hyacinthbots.lilybot.extensions.moderation.TerminalModeration
import org.hyacinthbots.lilybot.extensions.util.GalleryChannel
import org.hyacinthbots.lilybot.extensions.util.Github
import org.hyacinthbots.lilybot.extensions.util.GuildAnnouncements
import org.hyacinthbots.lilybot.extensions.util.InfoCommands
import org.hyacinthbots.lilybot.extensions.util.ModUtilities
import org.hyacinthbots.lilybot.extensions.util.PublicUtilities
Expand Down Expand Up @@ -76,10 +78,12 @@ suspend fun main() {
add(::Github)
add(::GalleryChannel)
add(::InfoCommands)
add(::GuildAnnouncements)
add(::GuildLogging)
add(::LogUploading)
add(::MemberLogging)
add(::MessageDelete)
add(::MessageEdit)
add(::ModUtilities)
add(::PublicUtilities)
add(::Reminders)
Expand Down
10 changes: 7 additions & 3 deletions src/main/kotlin/org/hyacinthbots/lilybot/database/Cleanups.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ package org.hyacinthbots.lilybot.database

import com.kotlindiscord.kord.extensions.koin.KordExKoinComponent
import dev.kord.core.Kord
import dev.kord.core.behavior.getChannelOf
import dev.kord.core.entity.channel.thread.ThreadChannel
import dev.kord.rest.request.KtorRequestException
import kotlinx.datetime.Clock
import mu.KotlinLogging
import org.hyacinthbots.lilybot.database.Cleanups.cleanupGuildData
import org.hyacinthbots.lilybot.database.Cleanups.cleanupThreadData
import org.hyacinthbots.lilybot.database.collections.LoggingConfigCollection
import org.hyacinthbots.lilybot.database.collections.ModerationConfigCollection
import org.hyacinthbots.lilybot.database.collections.RoleMenuCollection
import org.hyacinthbots.lilybot.database.collections.SupportConfigCollection
import org.hyacinthbots.lilybot.database.collections.TagsCollection
import org.hyacinthbots.lilybot.database.collections.ThreadsCollection
import org.hyacinthbots.lilybot.database.collections.UtilityConfigCollection
import org.hyacinthbots.lilybot.database.collections.WarnCollection
import org.hyacinthbots.lilybot.database.entities.GuildLeaveTimeData
Expand Down Expand Up @@ -82,15 +86,15 @@ object Cleanups : KordExKoinComponent {
var deletedThreads = 0
for (it in threads) {
try {
val thread = kordInstance.getChannelOf<ThreadChannel>(it.threadId) ?: continue
val thread = kordInstance.getGuild(it.guildId!!)?.getChannelOf<ThreadChannel>(it.threadId) ?: continue
val latestMessage = thread.getLastMessage() ?: continue
val timeSinceLatestMessage = Clock.System.now() - latestMessage.id.timestamp
if (timeSinceLatestMessage.inWholeDays > 7) {
threadDataCollection.deleteOne(ThreadData::threadId eq thread.id)
ThreadsCollection().removeThread(thread.id)
deletedThreads++
}
} catch (e: KtorRequestException) {
threadDataCollection.deleteOne(ThreadData::threadId eq it.threadId)
ThreadsCollection().removeThread(it.threadId)
deletedThreads++
continue
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,14 @@ class GalleryChannelCollection : KordExKoinComponent {
GalleryChannelData::channelId eq inputChannelId,
GalleryChannelData::guildId eq inputGuildId
)

/**
* Removes all gallery channels from this guild.
*
* @param inputGuildId The guild to clear the gallery channels from
* @author NoComment1105
* @since 4.1.0
*/
suspend inline fun removeAll(inputGuildId: Snowflake) =
collection.deleteMany(GalleryChannelData::guildId eq inputGuildId)
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,14 @@ class LogUploadingBlacklistCollection : KordExKoinComponent {
*/
suspend inline fun getLogUploadingBlacklist(inputGuildId: Snowflake): List<LogUploadingBlacklistData> =
collection.find(LogUploadingBlacklistData::guildId eq inputGuildId).toList()

/**
* Removes all data of the log upload blacklist for a given guild.
*
* @param inputGuildId The guild to clear the data from
* @author NoComment1105
* @since 4.1.0
*/
suspend inline fun clearBlacklist(inputGuildId: Snowflake) =
collection.deleteMany(LogUploadingBlacklistData::guildId eq inputGuildId)
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,15 @@ class RemindMeCollection : KordExKoinComponent {
RemindMeData::userId eq inputUserId,
RemindMeData::id eq id
)

/**
* Removes all reminders associated with a guild.
*
* @param inputGuildId The guild to remove reminders for
*
* @author NoComment1105
* @since 4.1.0
*/
suspend inline fun removeGuildReminders(inputGuildId: Snowflake) =
collection.deleteMany(RemindMeData::guildId eq inputGuildId)
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ class ThreadsCollection : KordExKoinComponent {
* @since 3.2.0
*/
suspend inline fun setThreadOwner(
inputGuildId: Snowflake?,
inputThreadId: Snowflake,
newOwnerId: Snowflake,
preventArchiving: Boolean = false
) {
collection.deleteOne(ThreadData::threadId eq inputThreadId)
collection.insertOne(ThreadData(inputThreadId, newOwnerId, preventArchiving))
collection.insertOne(ThreadData(inputGuildId, inputThreadId, newOwnerId, preventArchiving))
}

/**
Expand All @@ -88,4 +89,15 @@ class ThreadsCollection : KordExKoinComponent {
*/
suspend inline fun removeThread(inputThreadId: Snowflake) =
collection.deleteOne(ThreadData::threadId eq inputThreadId)

/**
* This function deletes the ownership data stored in database for the given [inputGuildId].
*
* @param inputGuildId The ID of the guild whose threads to delete
*
* @author NoComment1105
* @since 4.1.0
*/
suspend inline fun removeGuildThreads(inputGuildId: Snowflake) =
collection.deleteMany(ThreadData::guildId eq inputGuildId)
}
Loading

0 comments on commit 08b755a

Please sign in to comment.