add several opportunities in plugin

This commit is contained in:
InsanusMokrassar 2022-01-05 00:48:35 +06:00
parent 88047703ad
commit 852262853e
5 changed files with 156 additions and 72 deletions

View File

@ -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 "[^/]*$"`"

View File

@ -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

View File

@ -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)
}
}
}
}
}
}

View File

@ -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<User>
newUsers: List<User>,
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<Boolean> = 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<User>
newUsers: List<User>,
leftRestrictionsPermissions: ChatPermissions
) {
val userBanDateTime = eventDateTime + checkTimeSpan
val authorized = Channel<User>(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<User>
newUsers: List<User>,
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<User>
newUsers: List<User>,
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)
}
}
}

View File

@ -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
)