From 852262853e242d6f75d272caeea1bc962b0329c5 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 5 Jan 2022 00:48:35 +0600 Subject: [PATCH] add several opportunities in plugin --- .github/workflows/publish_package.yml | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../inmo/plagubot/plugins/captcha/Plugin.kt | 190 ++++++++++++------ .../captcha/provider/CaptchaProvider.kt | 30 +-- .../plugins/captcha/settings/ChatSettings.kt | 4 +- 5 files changed, 156 insertions(+), 72 deletions(-) diff --git a/.github/workflows/publish_package.yml b/.github/workflows/publish_package.yml index 6e92767..3e88795 100644 --- a/.github/workflows/publish_package.yml +++ b/.github/workflows/publish_package.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 11 - name: Update version run: | branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e750102..2e6e589 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/Plugin.kt b/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/Plugin.kt index bcd26b7..ff699df 100644 --- a/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/Plugin.kt +++ b/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/Plugin.kt @@ -2,55 +2,43 @@ package dev.inmo.plagubot.plugins.captcha import dev.inmo.micro_utils.coroutines.* import dev.inmo.micro_utils.repos.create -import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo -import dev.inmo.micro_utils.repos.versions.KeyValueBasedVersionsRepoProxy -import dev.inmo.micro_utils.repos.versions.StandardVersionsRepo import dev.inmo.plagubot.Plugin import dev.inmo.plagubot.plugins.captcha.db.CaptchaChatsSettingsRepo import dev.inmo.plagubot.plugins.captcha.provider.* import dev.inmo.plagubot.plugins.captcha.settings.ChatSettings -import dev.inmo.tgbotapi.bot.TelegramBot -import dev.inmo.tgbotapi.extensions.api.answers.answerCallbackQuery +import dev.inmo.tgbotapi.extensions.api.chat.get.getChat import dev.inmo.tgbotapi.extensions.api.chat.members.* import dev.inmo.tgbotapi.extensions.api.deleteMessage -import dev.inmo.tgbotapi.extensions.api.edit.ReplyMarkup.editMessageReplyMarkup import dev.inmo.tgbotapi.extensions.api.send.* import dev.inmo.tgbotapi.extensions.behaviour_builder.* -import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitBaseInlineQuery -import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitDataCallbackQuery import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand -import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onNewChatMembers import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat -import dev.inmo.tgbotapi.extensions.utils.formatting.buildEntities -import dev.inmo.tgbotapi.extensions.utils.formatting.regular -import dev.inmo.tgbotapi.extensions.utils.shortcuts.executeUnsafe import dev.inmo.tgbotapi.libraries.cache.admins.* -import dev.inmo.tgbotapi.requests.DeleteMessage import dev.inmo.tgbotapi.types.BotCommand -import dev.inmo.tgbotapi.types.MessageEntity.textsources.mention -import dev.inmo.tgbotapi.types.User -import dev.inmo.tgbotapi.types.chat.ChatPermissions -import dev.inmo.tgbotapi.types.chat.LeftRestrictionsChatPermissions +import dev.inmo.tgbotapi.types.chat.RestrictionsChatPermissions import dev.inmo.tgbotapi.types.chat.abstracts.Chat -import dev.inmo.tgbotapi.types.chat.abstracts.PublicChat -import dev.inmo.tgbotapi.types.dice.SlotMachineDiceAnimationType -import dev.inmo.tgbotapi.types.message.abstracts.* -import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent +import dev.inmo.tgbotapi.types.chat.abstracts.extended.ExtendedGroupChat import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.toList import kotlinx.serialization.Serializable import org.jetbrains.exposed.sql.Database private const val enableAutoDeleteCommands = "captcha_auto_delete_commands_on" private const val disableAutoDeleteCommands = "captcha_auto_delete_commands_off" +private const val enableAutoDeleteServiceMessages = "captcha_auto_delete_events_on" +private const val disableAutoDeleteServiceMessages = "captcha_auto_delete_events_off" private const val enableSlotMachineCaptcha = "captcha_use_slot_machine" private const val enableSimpleCaptcha = "captcha_use_simple" private const val enableExpressionCaptcha = "captcha_use_expression" +private const val disableCaptcha = "disable_captcha" +private const val enableCaptcha = "enable_captcha" + +private val enableDisableKickOnUnsuccess = Regex("captcha_(enable|disable)_kick") +private const val enableKickOnUnsuccess = "captcha_enable_kick" +private const val disableKickOnUnsuccess = "captcha_disable_kick" private val changeCaptchaMethodCommandRegex = Regex( "captcha_use_((slot_machine)|(simple)|(expression))" @@ -67,6 +55,14 @@ class CaptchaBotPlugin : Plugin { disableAutoDeleteCommands, "Disable auto removing of commands addressed to captcha plugin" ), + BotCommand( + enableAutoDeleteServiceMessages, + "Enable auto removing of users joined messages" + ), + BotCommand( + disableAutoDeleteServiceMessages, + "Disable auto removing of users joined messages" + ), BotCommand( enableSlotMachineCaptcha, "Change captcha method to slot machine" @@ -75,9 +71,25 @@ class CaptchaBotPlugin : Plugin { enableSimpleCaptcha, "Change captcha method to simple button" ), + BotCommand( + disableCaptcha, + "Disable captcha for chat" + ), + BotCommand( + enableCaptcha, + "Enable captcha for chat" + ), BotCommand( enableExpressionCaptcha, "Change captcha method to expressions" + ), + BotCommand( + enableKickOnUnsuccess, + "Not solved captcha users will be kicked from the chat" + ), + BotCommand( + disableKickOnUnsuccess, + "Not solved captcha users will NOT be kicked from the chat" ) ) @@ -96,20 +108,28 @@ class CaptchaBotPlugin : Plugin { subcontextUpdatesFilter = { m, u -> u.sourceChat() == m.chat }, ) { launchSafelyWithoutExceptions { - safelyWithoutExceptions { deleteMessage(it) } + val settings = it.chat.settings() + if (!settings.enabled) return@launchSafelyWithoutExceptions + + safelyWithoutExceptions { + if (settings.autoRemoveEvents) { + deleteMessage(it) + } + } val chat = it.chat.requireGroupChat() val newUsers = it.chatEvent.members newUsers.forEach { user -> restrictChatMember( chat, user, - permissions = ChatPermissions() + permissions = RestrictionsChatPermissions ) } - val settings = it.chat.settings() + val defaultChatPermissions = (getChat(it.chat) as ExtendedGroupChat).permissions + doInSubContext(stopOnCompletion = false) { launch { - settings.captchaProvider.apply { doAction(it.date, chat, newUsers) } + settings.captchaProvider.apply { doAction(it.date, chat, newUsers, defaultChatPermissions) } } } } @@ -117,35 +137,33 @@ class CaptchaBotPlugin : Plugin { if (adminsAPI != null) { onCommand(changeCaptchaMethodCommandRegex) { - if (adminsAPI.sentByAdmin(it) != true) { - return@onCommand - } - - val settings = it.chat.settings() - if (settings.autoRemoveCommands) { - safelyWithoutExceptions { deleteMessage(it) } - } - val commands = it.parseCommandsWithParams() - val changeCommand = commands.keys.first { - println(it) - changeCaptchaMethodCommandRegex.matches(it) - } - println(changeCommand) - val captcha = when { - changeCommand.startsWith(enableSimpleCaptcha) -> SimpleCaptchaProvider() - changeCommand.startsWith(enableExpressionCaptcha) -> ExpressionCaptchaProvider() - changeCommand.startsWith(enableSlotMachineCaptcha) -> SlotMachineCaptchaProvider() - else -> return@onCommand - } - val newSettings = settings.copy(captchaProvider = captcha) - if (repo.contains(it.chat.id)) { - repo.update(it.chat.id, newSettings) - } else { - repo.create(newSettings) - } - sendMessage(it.chat, "Settings updated").also { sent -> - delay(5000L) - deleteMessage(sent) + it.doAfterVerification(adminsAPI) { + val settings = it.chat.settings() + if (settings.autoRemoveCommands) { + safelyWithoutExceptions { deleteMessage(it) } + } + val commands = it.parseCommandsWithParams() + val changeCommand = commands.keys.first { + println(it) + changeCaptchaMethodCommandRegex.matches(it) + } + println(changeCommand) + val captcha = when { + changeCommand.startsWith(enableSimpleCaptcha) -> SimpleCaptchaProvider() + changeCommand.startsWith(enableExpressionCaptcha) -> ExpressionCaptchaProvider() + changeCommand.startsWith(enableSlotMachineCaptcha) -> SlotMachineCaptchaProvider() + else -> return@doAfterVerification + } + val newSettings = settings.copy(captchaProvider = captcha) + if (repo.contains(it.chat.id)) { + repo.update(it.chat.id, newSettings) + } else { + repo.create(newSettings) + } + sendMessage(it.chat, "Settings updated").also { sent -> + delay(5000L) + deleteMessage(sent) + } } } @@ -177,6 +195,66 @@ class CaptchaBotPlugin : Plugin { ) } } + + onCommand(disableCaptcha) { message -> + message.doAfterVerification(adminsAPI) { + val settings = message.chat.settings() + + repo.update( + message.chat.id, + settings.copy(enabled = false) + ) + + if (settings.autoRemoveCommands) { + deleteMessage(message) + } + } + } + + onCommand(enableCaptcha) { message -> + message.doAfterVerification(adminsAPI) { + val settings = message.chat.settings() + + repo.update( + message.chat.id, + settings.copy(enabled = true) + ) + + if (settings.autoRemoveCommands) { + deleteMessage(message) + } + } + } + + onCommand(enableAutoDeleteServiceMessages) { message -> + message.doAfterVerification(adminsAPI) { + val settings = message.chat.settings() + + repo.update( + message.chat.id, + settings.copy(autoRemoveEvents = true) + ) + + if (settings.autoRemoveCommands) { + deleteMessage(message) + } + } + } + + onCommand(disableAutoDeleteServiceMessages) { message -> + message.doAfterVerification(adminsAPI) { + val settings = message.chat.settings() + + repo.update( + message.chat.id, + settings.copy(autoRemoveEvents = false) + ) + + if (settings.autoRemoveCommands) { + deleteMessage(message) + } + } + } } } } diff --git a/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/provider/CaptchaProvider.kt b/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/provider/CaptchaProvider.kt index a5012cd..14d0daa 100644 --- a/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/provider/CaptchaProvider.kt +++ b/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/provider/CaptchaProvider.kt @@ -3,7 +3,6 @@ package dev.inmo.plagubot.plugins.captcha.provider import com.benasher44.uuid.uuid4 import com.soywiz.klock.DateTime import com.soywiz.klock.seconds -import dev.inmo.micro_utils.common.joinTo import dev.inmo.micro_utils.coroutines.safelyWithResult import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions import dev.inmo.plagubot.plugins.captcha.slotMachineReplyMarkup @@ -23,8 +22,8 @@ import dev.inmo.tgbotapi.extensions.utils.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.requests.DeleteMessage import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.MessageEntity.textsources.mention -import dev.inmo.tgbotapi.types.MessageEntity.textsources.plus import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CallbackDataInlineKeyboardButton +import dev.inmo.tgbotapi.types.chat.ChatPermissions import dev.inmo.tgbotapi.types.chat.LeftRestrictionsChatPermissions import dev.inmo.tgbotapi.types.chat.abstracts.* import dev.inmo.tgbotapi.types.dice.SlotMachineDiceAnimationType @@ -43,13 +42,15 @@ sealed class CaptchaProvider { abstract suspend fun BehaviourContext.doAction( eventDateTime: DateTime, chat: GroupChat, - newUsers: List + newUsers: List, + leftRestrictionsPermissions: ChatPermissions ) } private suspend fun BehaviourContext.banUser( chat: PublicChat, user: User, + leftRestrictionsPermissions: ChatPermissions, onFailure: suspend BehaviourContext.(Throwable) -> Unit = { safelyWithResult { sendTextMessage( @@ -68,7 +69,7 @@ private suspend fun BehaviourContext.banUser( } } ): Result = safelyWithResult { - restrictChatMember(chat, user, permissions = LeftRestrictionsChatPermissions) + restrictChatMember(chat, user, permissions = leftRestrictionsPermissions) banChatMember(chat, user) }.onFailure { onFailure(it) @@ -86,7 +87,8 @@ data class SlotMachineCaptchaProvider( override suspend fun BehaviourContext.doAction( eventDateTime: DateTime, chat: GroupChat, - newUsers: List + newUsers: List, + leftRestrictionsPermissions: ChatPermissions ) { val userBanDateTime = eventDateTime + checkTimeSpan val authorized = Channel(newUsers.size) @@ -132,7 +134,7 @@ data class SlotMachineCaptchaProvider( } } authorized.send(it) - safelyWithoutExceptions { restrictChatMember(chat, it, permissions = LeftRestrictionsChatPermissions) } + safelyWithoutExceptions { restrictChatMember(chat, it, permissions = leftRestrictionsPermissions) } stop() } @@ -149,7 +151,7 @@ data class SlotMachineCaptchaProvider( if (user !in authorizedUsers) { context.stop() if (kick) { - banUser(chat, user) + banUser(chat, user, leftRestrictionsPermissions) } } } @@ -173,7 +175,8 @@ data class SimpleCaptchaProvider( override suspend fun BehaviourContext.doAction( eventDateTime: DateTime, chat: GroupChat, - newUsers: List + newUsers: List, + leftRestrictionsPermissions: ChatPermissions ) { val userBanDateTime = eventDateTime + checkTimeSpan newUsers.mapNotNull { @@ -208,7 +211,7 @@ data class SimpleCaptchaProvider( }.first() removeRedundantMessages() - safelyWithoutExceptions { restrictChatMember(chat, it, permissions = LeftRestrictionsChatPermissions) } + safelyWithoutExceptions { restrictChatMember(chat, it, permissions = leftRestrictionsPermissions) } stop() } @@ -217,7 +220,7 @@ data class SimpleCaptchaProvider( if (job.isActive) { job.cancel() if (kick) { - banUser(chat, it) + banUser(chat, it, leftRestrictionsPermissions) } } stop() @@ -285,7 +288,8 @@ data class ExpressionCaptchaProvider( override suspend fun BehaviourContext.doAction( eventDateTime: DateTime, chat: GroupChat, - newUsers: List + newUsers: List, + leftRestrictionsPermissions: ChatPermissions ) { val userBanDateTime = eventDateTime + checkTimeSpan newUsers.map { user -> @@ -330,10 +334,10 @@ data class ExpressionCaptchaProvider( removeRedundantMessages() passed = it if (it) { - safelyWithoutExceptions { restrictChatMember(chat, user, permissions = LeftRestrictionsChatPermissions) } + safelyWithoutExceptions { restrictChatMember(chat, user, permissions = leftRestrictionsPermissions) } } else { if (kick) { - banUser(chat, user) + banUser(chat, user, leftRestrictionsPermissions) } } } diff --git a/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/settings/ChatSettings.kt b/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/settings/ChatSettings.kt index 4548b0a..9a9b1d0 100644 --- a/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/settings/ChatSettings.kt +++ b/src/main/kotlin/dev/inmo/plagubot/plugins/captcha/settings/ChatSettings.kt @@ -9,5 +9,7 @@ import kotlinx.serialization.Serializable data class ChatSettings( val chatId: ChatId, val captchaProvider: CaptchaProvider = SimpleCaptchaProvider(), - val autoRemoveCommands: Boolean = false + val autoRemoveCommands: Boolean = false, + val autoRemoveEvents: Boolean = true, + val enabled: Boolean = true )