diff --git a/assets/stickers/fail.png b/assets/stickers/fail.png new file mode 100644 index 0000000..82604c2 Binary files /dev/null and b/assets/stickers/fail.png differ diff --git a/assets/stickers/success.png b/assets/stickers/success.png new file mode 100644 index 0000000..944f3cc Binary files /dev/null and b/assets/stickers/success.png differ diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/Configuration.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/Configuration.kt index 8036af9..eb9e7f3 100644 --- a/src/main/kotlin/com/github/pool_party/resistance_bot/Configuration.kt +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/Configuration.kt @@ -5,6 +5,7 @@ import com.github.pool_party.resistance_bot.utils.ConfigurationUtils.boolean import com.github.pool_party.resistance_bot.utils.ConfigurationUtils.int import com.github.pool_party.resistance_bot.utils.ConfigurationUtils.seconds import com.github.pool_party.resistance_bot.utils.ConfigurationUtils.string +import com.github.pool_party.resistance_bot.sticker.AssetSticker object Configuration { @@ -50,6 +51,15 @@ object Configuration { val PLAYERS_GAME_MAXIMUM = BOARDS.keys.maxOrNull()!! + val STICKER_SET_UPDATE by boolean() + + object Stickers { + + val FAIL = AssetSticker("fail", """❌""") + + val SUCCESS = AssetSticker("success", """✔️""") + } + init { check((PLAYERS_GAME_MINIMUM..PLAYERS_GAME_MAXIMUM).all { it in BOARDS }) if (DEBUG) { diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/Main.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/Main.kt index 4788cb0..2ff553b 100644 --- a/src/main/kotlin/com/github/pool_party/resistance_bot/Main.kt +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/Main.kt @@ -2,6 +2,7 @@ package com.github.pool_party.resistance_bot import com.elbekD.bot.Bot import com.elbekD.bot.server +import com.github.pool_party.resistance_bot.sticker.updateSet import com.github.pool_party.resistance_bot.utils.initHandlers fun main() { @@ -22,5 +23,6 @@ fun main() { } bot.initHandlers() + if (Configuration.STICKER_SET_UPDATE) bot.updateSet() bot.start() } diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/callback/MissionVoteCallback.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/callback/MissionVoteCallback.kt index 02519c7..30c1f47 100644 --- a/src/main/kotlin/com/github/pool_party/resistance_bot/callback/MissionVoteCallback.kt +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/callback/MissionVoteCallback.kt @@ -2,11 +2,13 @@ package com.github.pool_party.resistance_bot.callback import com.elbekD.bot.Bot import com.github.pool_party.resistance_bot.Configuration +import com.github.pool_party.resistance_bot.Configuration.Stickers import com.github.pool_party.resistance_bot.state.GameState import com.github.pool_party.resistance_bot.state.RoundResult import com.github.pool_party.resistance_bot.state.StateStorage import com.github.pool_party.resistance_bot.state.Vote import com.github.pool_party.resistance_bot.utils.sendMessageLogging +import com.github.pool_party.resistance_bot.utils.sendStickerLogging import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -29,6 +31,7 @@ class MissionVoteCallback(stateStorage: StateStorage) : AbstractVoteCallback(sta val result = votes.asSequence().map { it.second }.all { it } if (result) { + sendStickerLogging(chatId, Stickers.SUCCESS) sendMessageLogging(chatId, "TODO: mission has completed successfully").join() if (++state.resistancePoints >= Configuration.WIN_NUMBER) { @@ -37,6 +40,7 @@ class MissionVoteCallback(stateStorage: StateStorage) : AbstractVoteCallback(sta return } } else { + sendStickerLogging(chatId, Stickers.FAIL) sendMessageLogging(chatId, "TODO: mission has failed").join() if (++state.spyPoints >= Configuration.WIN_NUMBER) { diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/AssetSticker.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/AssetSticker.kt new file mode 100644 index 0000000..aef842d --- /dev/null +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/AssetSticker.kt @@ -0,0 +1,27 @@ +package com.github.pool_party.resistance_bot.sticker + +import com.elbekD.bot.Bot +import com.elbekD.bot.types.Message +import com.github.pool_party.resistance_bot.utils.resolveName +import java.util.concurrent.CompletableFuture + +data class AssetSticker(val fileName: String, val emojis: String) { + + private var fileId: String? = null + + fun Bot.send(chatId: Long): CompletableFuture? { + if (fileId == null) { + val setName = resolveName(StickerSetConfiguration.STICKER_SET_NAME) + + val stickerSet = getStickerSet(setName) + .handle { value, _ -> value } + .join() + ?: return null + + fileId = stickerSet.stickers[StickerSetConfiguration.STICKERS.indexOf(this@AssetSticker)].file_id + } + + return fileId?.let { sendSticker(chatId, it) } + } +} + diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/CreatePack.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/CreatePack.kt new file mode 100644 index 0000000..e215f6e --- /dev/null +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/CreatePack.kt @@ -0,0 +1,48 @@ +package com.github.pool_party.resistance_bot.sticker + +import com.elbekD.bot.Bot +import com.elbekD.bot.types.StickerSet +import com.github.pool_party.resistance_bot.sticker.StickerSetConfiguration.file +import com.github.pool_party.resistance_bot.utils.resolveName +import mu.KotlinLogging +import kotlin.system.exitProcess + +private val logger = KotlinLogging.logger {} + +fun Bot.updateSet() { + val setName = resolveName(StickerSetConfiguration.STICKER_SET_NAME) + val stickers = StickerSetConfiguration.STICKERS + if (stickers.isEmpty()) return + val firstSticker = stickers.first() + + val stickerSet: StickerSet? = getStickerSet(setName) + .handle { value, _ -> value } + .join() + + if (stickerSet != null) { + logger.info("Using existing sticker set, deleting all stickers") + stickerSet.stickers.forEach { deleteStickerFromSet(it.file_id).join() } + } else { + logger.info("Creating new sticker set") + val result = createNewStickerSet( + StickerSetConfiguration.DEV_USER_ID, + setName, + StickerSetConfiguration.TITLE, + firstSticker.emojis, + firstSticker.file, + ).join() + + if (!result) { + println("Failed") + exitProcess(1) + } + } + + logger.info("Adding the rest of the stickers") + stickers.asSequence() + .drop(if (stickerSet != null) 0 else 1) + .forEach { + addStickerToSet(StickerSetConfiguration.DEV_USER_ID, setName, it.emojis, it.file).join() + } + logger.info("Sticker pack successfully updated") +} diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/StickerSetConfiguration.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/StickerSetConfiguration.kt new file mode 100644 index 0000000..4f15dfd --- /dev/null +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/sticker/StickerSetConfiguration.kt @@ -0,0 +1,21 @@ +package com.github.pool_party.resistance_bot.sticker + +import com.github.pool_party.resistance_bot.Configuration.Stickers +import com.github.pool_party.resistance_bot.utils.ConfigurationUtils.long +import com.github.pool_party.resistance_bot.utils.ConfigurationUtils.string +import java.io.File +import kotlin.reflect.full.memberProperties + +object StickerSetConfiguration { + + val STICKERS = Stickers::class.memberProperties.mapNotNull { it.get(Stickers) as? AssetSticker } + + const val TITLE = "@ResistanceOnlineBot Stickers" + + val DEV_USER_ID by long() + + val STICKER_SET_NAME by string() + + val AssetSticker.file + get() = File("assets/stickers/$fileName.png") +} diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/utils/BotUtils.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/utils/BotUtils.kt index fec7fdf..8de67a9 100644 --- a/src/main/kotlin/com/github/pool_party/resistance_bot/utils/BotUtils.kt +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/utils/BotUtils.kt @@ -1,5 +1,6 @@ package com.github.pool_party.resistance_bot.utils +import com.elbekD.bot.Bot import com.elbekD.bot.types.InlineKeyboardButton import com.elbekD.bot.types.InlineKeyboardMarkup import com.elbekD.bot.types.Message @@ -45,3 +46,5 @@ fun makeStopVoteMarkup(chatId: Long, votes: Map): InlineKeyboardMa makeButton(""" Continue 😎""", false), ).toMarkUp() } + +fun Bot.resolveName(stickerSetName: String) = "${stickerSetName}_by_${getMe().join().username!!}" diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/utils/ConfigurationUtils.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/utils/ConfigurationUtils.kt index cab0329..be94647 100644 --- a/src/main/kotlin/com/github/pool_party/resistance_bot/utils/ConfigurationUtils.kt +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/utils/ConfigurationUtils.kt @@ -6,6 +6,7 @@ import com.natpryce.konfig.Key import com.natpryce.konfig.PropertyLocation import com.natpryce.konfig.booleanType import com.natpryce.konfig.intType +import com.natpryce.konfig.longType import com.natpryce.konfig.overriding import com.natpryce.konfig.stringType import kotlin.reflect.KProperty @@ -26,6 +27,8 @@ object ConfigurationUtils { fun int() = Configured(intType) + fun long() = Configured(longType) + fun string() = Configured(stringType) fun seconds() = ConfiguredDuration("seconds", Duration::seconds) diff --git a/src/main/kotlin/com/github/pool_party/resistance_bot/utils/MessageUtils.kt b/src/main/kotlin/com/github/pool_party/resistance_bot/utils/MessageUtils.kt index d215d57..71c8b22 100644 --- a/src/main/kotlin/com/github/pool_party/resistance_bot/utils/MessageUtils.kt +++ b/src/main/kotlin/com/github/pool_party/resistance_bot/utils/MessageUtils.kt @@ -4,6 +4,7 @@ import com.elbekD.bot.Bot import com.elbekD.bot.types.InlineKeyboardMarkup import com.elbekD.bot.types.Message import com.elbekD.bot.types.ReplyKeyboard +import com.github.pool_party.resistance_bot.sticker.AssetSticker import mu.KotlinLogging import java.util.concurrent.CompletableFuture @@ -55,3 +56,5 @@ fun Bot.editMessageReplyMarkupLogging( return editMessageReplyMarkup(chatId, messageId, markup = markup) .logging("Failed to edit reply markup \"$markup\"") } + +fun Bot.sendStickerLogging(chatId: Long, sticker: AssetSticker) = with(sticker) { send(chatId)?.logging() } diff --git a/src/main/resources/default.properties b/src/main/resources/default.properties index c01f0f6..db0f508 100644 --- a/src/main/resources/default.properties +++ b/src/main/resources/default.properties @@ -8,3 +8,5 @@ registration.extend.seconds=30 stop.game.voting.seconds=30 rejections.number=5 debug=false +sticker.set.name=ResistanceOnlineBotStickers +sticker.set.update=false