mirror of
https://github.com/InsanusMokrassar/CaptchaPlaguBotPlugin.git
synced 2024-11-22 08:13:55 +00:00
first version
This commit is contained in:
parent
6cb2c7204e
commit
5c3128e58a
12
build.gradle
12
build.gradle
@ -12,12 +12,15 @@ buildscript {
|
|||||||
plugins {
|
plugins {
|
||||||
id 'org.jetbrains.kotlin.jvm' version "$kotlin_version"
|
id 'org.jetbrains.kotlin.jvm' version "$kotlin_version"
|
||||||
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version"
|
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version"
|
||||||
id 'application'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
project.group = "$project_group"
|
||||||
|
project.version = "$project_version"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
mavenLocal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -26,8 +29,5 @@ dependencies {
|
|||||||
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version"
|
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version"
|
||||||
|
|
||||||
api "dev.inmo:plagubot.plugin:$plagubot_version"
|
api "dev.inmo:plagubot.plugin:$plagubot_version"
|
||||||
}
|
api "dev.inmo:micro_utils.repos.exposed:$micro_utils_version"
|
||||||
|
|
||||||
application {
|
|
||||||
mainClassName = 'telegram_bot.AppKt'
|
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,9 @@ kotlin.incremental=true
|
|||||||
kotlin_version=1.4.30
|
kotlin_version=1.4.30
|
||||||
kotlin_coroutines_version=1.4.2
|
kotlin_coroutines_version=1.4.2
|
||||||
kotlin_serialisation_runtime_version=1.1.0-RC
|
kotlin_serialisation_runtime_version=1.1.0-RC
|
||||||
plagubot_version=0.1.0
|
plagubot_version=0.1.1
|
||||||
|
|
||||||
|
micro_utils_version=0.4.25
|
||||||
|
|
||||||
|
project_group=dev.inmo
|
||||||
|
project_version=0.1.1
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package dev.inmo.plagubot.plugins.captcha
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.chat.ChatPermissions
|
||||||
|
|
||||||
|
val authorizedUserChatPermissions = ChatPermissions(
|
||||||
|
canSendMessages = true,
|
||||||
|
canSendMediaMessages = true,
|
||||||
|
canSendPolls = true,
|
||||||
|
canSendOtherMessages = true,
|
||||||
|
canAddWebPagePreviews = true,
|
||||||
|
canChangeInfo = true,
|
||||||
|
canInviteUsers = true,
|
||||||
|
canPinMessages = true,
|
||||||
|
)
|
109
src/main/kotlin/dev/inmo/plagubot/plugins/captcha/Plugin.kt
Normal file
109
src/main/kotlin/dev/inmo/plagubot/plugins/captcha/Plugin.kt
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package dev.inmo.plagubot.plugins.captcha
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
|
||||||
|
import dev.inmo.micro_utils.repos.create
|
||||||
|
import dev.inmo.plagubot.Plugin
|
||||||
|
import dev.inmo.plagubot.plugins.captcha.db.CaptchaChatsSettingsRepo
|
||||||
|
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.members.*
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.send.media.reply
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.send.sendDice
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.send.sendTextMessage
|
||||||
|
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.updateshandlers.FlowsUpdatesFilter
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onNewChatMembers
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.*
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.formatting.buildEntities
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.formatting.regular
|
||||||
|
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.dice.SlotMachineDiceAnimationType
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import kotlinx.coroutines.channels.Channel
|
||||||
|
import kotlinx.coroutines.channels.toList
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.jetbrains.exposed.sql.Database
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class CaptchaBotPlugin : Plugin {
|
||||||
|
override suspend fun BehaviourContext.invoke(
|
||||||
|
database: Database,
|
||||||
|
params: Map<String, Any>
|
||||||
|
) {
|
||||||
|
val repo = CaptchaChatsSettingsRepo(database)
|
||||||
|
onNewChatMembers(
|
||||||
|
additionalFilter = {
|
||||||
|
it.chat.asPublicChat() != null
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
val eventDateTime = it.date
|
||||||
|
val chat = it.chat.requirePublicChat()
|
||||||
|
val newUsers = it.chatEvent.members
|
||||||
|
newUsers.forEach { user ->
|
||||||
|
restrictChatMember(
|
||||||
|
chat,
|
||||||
|
user,
|
||||||
|
permissions = ChatPermissions()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val settings = repo.getById(it.chat.id) ?: repo.create(ChatSettings(it.chat.id)).firstOrNull() ?: return@onNewChatMembers
|
||||||
|
val userBanDateTime = eventDateTime + settings.checkTimeSpan
|
||||||
|
val authorized = Channel<User>(newUsers.size)
|
||||||
|
val subContexts = newUsers.map {
|
||||||
|
doInSubContext {
|
||||||
|
val sentMessage = sendTextMessage(
|
||||||
|
chat,
|
||||||
|
buildEntities {
|
||||||
|
+it.mention(it.firstName)
|
||||||
|
regular(settings.captchaText)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
val sentDice = sendDice(
|
||||||
|
sentMessage.chat,
|
||||||
|
SlotMachineDiceAnimationType,
|
||||||
|
replyToMessageId = sentMessage.messageId,
|
||||||
|
replyMarkup = slotMachineReplyMarkup()
|
||||||
|
)
|
||||||
|
val reels = sentDice.content.dice.calculateSlotMachineResult()!!
|
||||||
|
val leftToClick = mutableListOf(
|
||||||
|
reels.left.asSlotMachineReelImage.text,
|
||||||
|
reels.center.asSlotMachineReelImage.text,
|
||||||
|
reels.right.asSlotMachineReelImage.text
|
||||||
|
)
|
||||||
|
|
||||||
|
launch {
|
||||||
|
while (leftToClick.isNotEmpty()) {
|
||||||
|
val userClicked = waitDataCallbackQuery { if (user.id == it.id) this else null }.first()
|
||||||
|
answerCallbackQuery(userClicked, "⏳")
|
||||||
|
if (userClicked.data == leftToClick.first()) {
|
||||||
|
leftToClick.removeAt(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
authorized.send(it)
|
||||||
|
safelyWithoutExceptions { restrictChatMember(chat, it, permissions = authorizedUserChatPermissions) }
|
||||||
|
stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
this to it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delay((userBanDateTime - eventDateTime).millisecondsLong)
|
||||||
|
|
||||||
|
val authorizedUsers = authorized.toList()
|
||||||
|
authorized.close()
|
||||||
|
|
||||||
|
subContexts.forEach { (context, user) ->
|
||||||
|
if (user !in authorizedUsers) {
|
||||||
|
context.stop()
|
||||||
|
safelyWithoutExceptions { kickChatMember(chat, user) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package dev.inmo.plagubot.plugins.captcha
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.SlotMachineReelImage
|
||||||
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CallbackDataInlineKeyboardButton
|
||||||
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
|
|
||||||
|
infix fun String.startingOf(target: String) = target.startsWith(this)
|
||||||
|
|
||||||
|
fun slotMachineReplyMarkup(
|
||||||
|
first: String? = null,
|
||||||
|
second: String? = null,
|
||||||
|
third: String? = null,
|
||||||
|
): InlineKeyboardMarkup {
|
||||||
|
val texts = when {
|
||||||
|
first == null -> SlotMachineReelImage.values().map {
|
||||||
|
CallbackDataInlineKeyboardButton("${it.text}**", it.text)
|
||||||
|
}
|
||||||
|
second == null -> SlotMachineReelImage.values().map {
|
||||||
|
CallbackDataInlineKeyboardButton("$first${it.text}*", it.text)
|
||||||
|
}
|
||||||
|
third == null -> SlotMachineReelImage.values().map {
|
||||||
|
CallbackDataInlineKeyboardButton("$first$second${it.text}", it.text)
|
||||||
|
}
|
||||||
|
else -> listOf(CallbackDataInlineKeyboardButton("$first$second$third", "$first$second$third"))
|
||||||
|
}
|
||||||
|
return InlineKeyboardMarkup(
|
||||||
|
texts.chunked(2)
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package dev.inmo.plagubot.plugins.captcha.db
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo
|
||||||
|
import dev.inmo.micro_utils.repos.exposed.ExposedCRUDRepo
|
||||||
|
import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo
|
||||||
|
import dev.inmo.plagubot.plugins.captcha.settings.*
|
||||||
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
|
import dev.inmo.tgbotapi.types.toChatId
|
||||||
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.statements.InsertStatement
|
||||||
|
import org.jetbrains.exposed.sql.statements.UpdateStatement
|
||||||
|
|
||||||
|
class CaptchaChatsSettingsRepo(
|
||||||
|
override val database: Database
|
||||||
|
) : AbstractExposedCRUDRepo<ChatSettings, ChatId, ChatSettings>(
|
||||||
|
tableName = "CaptchaChatsSettingsRepo"
|
||||||
|
) {
|
||||||
|
private val chatIdColumn = long("chatId")
|
||||||
|
private val checkTimeSecondsColumn = integer("checkTime")
|
||||||
|
private val solveCaptchaTextColumn = text("checkTime")
|
||||||
|
|
||||||
|
override val primaryKey = PrimaryKey(chatIdColumn)
|
||||||
|
|
||||||
|
override val selectByIds: SqlExpressionBuilder.(List<ChatId>) -> Op<Boolean> = {
|
||||||
|
chatIdColumn.inList(it.map { it.chatId })
|
||||||
|
}
|
||||||
|
override val InsertStatement<Number>.asObject: ChatSettings
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
|
||||||
|
override fun insert(value: ChatSettings, it: InsertStatement<Number>) {
|
||||||
|
it[chatIdColumn] = value.chatId.chatId
|
||||||
|
it[checkTimeSecondsColumn] = value.checkTime
|
||||||
|
it[solveCaptchaTextColumn] = value.captchaText
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(id: ChatId, value: ChatSettings, it: UpdateStatement) {
|
||||||
|
if (id.chatId == value.chatId.chatId) {
|
||||||
|
it[checkTimeSecondsColumn] = value.checkTime
|
||||||
|
it[solveCaptchaTextColumn] = value.captchaText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun InsertStatement<Number>.asObject(value: ChatSettings): ChatSettings = ChatSettings(
|
||||||
|
get(chatIdColumn).toChatId(),
|
||||||
|
get(checkTimeSecondsColumn),
|
||||||
|
get(solveCaptchaTextColumn)
|
||||||
|
)
|
||||||
|
|
||||||
|
override val selectById: SqlExpressionBuilder.(ChatId) -> Op<Boolean> = { chatIdColumn.eq(it.chatId) }
|
||||||
|
override val ResultRow.asObject: ChatSettings
|
||||||
|
get() = ChatSettings(
|
||||||
|
get(chatIdColumn).toChatId(),
|
||||||
|
get(checkTimeSecondsColumn),
|
||||||
|
get(solveCaptchaTextColumn)
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package dev.inmo.plagubot.plugins.captcha.settings
|
||||||
|
|
||||||
|
import com.soywiz.klock.TimeSpan
|
||||||
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
|
import dev.inmo.tgbotapi.types.Seconds
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.Transient
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ChatSettings(
|
||||||
|
val chatId: ChatId,
|
||||||
|
val checkTime: Seconds = 60,
|
||||||
|
val captchaText: String = "solve next captcha:"
|
||||||
|
) {
|
||||||
|
@Transient
|
||||||
|
val checkTimeSpan = TimeSpan(checkTime * 1000.0)
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
package plagubot_plugin
|
|
||||||
|
|
||||||
import dev.inmo.plagubot.Plugin
|
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import org.jetbrains.exposed.sql.Database
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
class PlaguBotPlugin : Plugin {
|
|
||||||
override suspend fun BehaviourContext.invoke(
|
|
||||||
database: Database,
|
|
||||||
params: Map<String, Any>
|
|
||||||
) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user