This commit is contained in:
InsanusMokrassar 2021-04-05 23:34:41 +06:00
parent 338e97770d
commit 6fe5f96e4e

View File

@ -31,6 +31,8 @@ import dev.inmo.tgbotapi.types.message.abstracts.Message
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.toList import kotlinx.coroutines.channels.toList
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
import kotlin.random.Random import kotlin.random.Random
@ -256,79 +258,86 @@ data class ExpressionCaptchaProvider(
) { ) {
val userBanDateTime = eventDateTime + checkTimeSpan val userBanDateTime = eventDateTime + checkTimeSpan
newUsers.mapNotNull { user -> newUsers.mapNotNull { user ->
safelyWithoutExceptions { launch {
launch { doInSubContext {
doInSubContext { val callbackData = ExpressionBuilder.createExpression(
val callbackData = ExpressionBuilder.createExpression( maxPerNumber,
maxPerNumber, operations
operations )
) val correctAnswer = callbackData.first.toString()
val correctAnswer = callbackData.first.toString() val answers = (0 until answers - 1).map {
val answers = (0 until answers - 1).map { ExpressionBuilder.generateResult(maxPerNumber, operations)
ExpressionBuilder.generateResult(maxPerNumber, operations) }.toMutableList().also { orderedAnswers ->
}.toMutableList().also { orderedAnswers -> val correctAnswerPosition = Random.nextInt(orderedAnswers.size)
val correctAnswerPosition = Random.nextInt(orderedAnswers.size) orderedAnswers.add(correctAnswerPosition, callbackData.first)
orderedAnswers.add(correctAnswerPosition, callbackData.first) }.toList()
}.toList() val sentMessage = sendTextMessage(
val sentMessage = sendTextMessage( chat,
chat, buildEntities {
buildEntities { +user.mention(user.firstName)
+user.mention(user.firstName) regular(", $captchaText ")
regular(", $captchaText ") bold(callbackData.second)
bold(callbackData.second) },
}, replyMarkup = dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup(
replyMarkup = dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup( answers.map {
answers.map { CallbackDataInlineKeyboardButton(it.toString(), it.toString())
CallbackDataInlineKeyboardButton(it.toString(), it.toString()) }.chunked(3)
}.chunked(3)
)
) )
)
suspend fun removeRedundantMessages() { suspend fun removeRedundantMessages() {
safelyWithoutExceptions { safelyWithoutExceptions {
deleteMessage(sentMessage) deleteMessage(sentMessage)
}
} }
}
var passed = true var passed: Boolean? = null
val callback: suspend (Boolean) -> Unit = { val passedMutex = Mutex()
removeRedundantMessages() val callback: suspend (Boolean) -> Unit = {
passed = it passedMutex.withLock {
if (it) { if (passed == null) {
safelyWithoutExceptions { restrictChatMember(chat, user, permissions = LeftRestrictionsChatPermissions) } removeRedundantMessages()
} else { passed = it
if (kick) { if (it) {
safelyWithoutExceptions { kickChatMember(chat, user) } safelyWithoutExceptions { restrictChatMember(chat, user, permissions = LeftRestrictionsChatPermissions) }
} } else {
} if (kick) {
} safelyWithoutExceptions { kickChatMember(chat, user) }
val job = parallel {
var leftAttempts = attempts
waitDataCallbackQuery {
when {
this.user.id != user.id -> null
this.data != correctAnswer -> {
leftAttempts--
if (leftAttempts < 1) {
this
} else {
launch { answerCallbackQuery(this@waitDataCallbackQuery, leftRetriesText + leftAttempts) }
null
}
} }
else -> this
} }
}.first() }
callback(leftAttempts > 0)
} }
}
val banJob = launch {
delay((userBanDateTime - eventDateTime).millisecondsLong) delay((userBanDateTime - eventDateTime).millisecondsLong)
if (job.isActive) job.cancel() if (passed == null) {
callback(passed) callback(false)
stop()
}
} }
var leftAttempts = attempts
waitDataCallbackQuery {
when {
this.user.id != user.id -> null
this.data != correctAnswer -> {
leftAttempts--
if (leftAttempts < 1) {
this
} else {
answerCallbackQuery(this@waitDataCallbackQuery, leftRetriesText + leftAttempts)
null
}
}
else -> this
}
}.first()
banJob.cancel()
callback(leftAttempts > 0)
} }
} }
}.joinAll() }.joinAll()