From 849b1647493f0dbdd4080c9379352b321b5d4be4 Mon Sep 17 00:00:00 2001 From: RTAkland Date: Fri, 20 Sep 2024 14:05:20 +0800 Subject: [PATCH] chore: improve use experience --- src/main/kotlin/cn/rtast/fancybot/FancyBot.kt | 2 + .../commands/parse/AsciiArtCommand.kt | 133 ++++++++++-------- 2 files changed, 75 insertions(+), 60 deletions(-) diff --git a/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt b/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt index fe872ff..bb6ae1d 100644 --- a/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt +++ b/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt @@ -65,6 +65,8 @@ class FancyBot : OneBotListener { val messageId = message.messageId println("$sender($senderId: $groupId >>> $messageId): $msg") + AsciiArtCommand.callback(message) + if (message.rawMessage.startsWith("https://github.com/") || message.rawMessage.startsWith("git@github.com:")) { GitHubParseCommand.parse(this, message) } diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/parse/AsciiArtCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/parse/AsciiArtCommand.kt index 53a0d84..f3610e4 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/parse/AsciiArtCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/parse/AsciiArtCommand.kt @@ -22,79 +22,92 @@ import javax.imageio.ImageIO import kotlin.math.roundToInt class AsciiArtCommand : BaseCommand() { - override val commandNames = listOf("/ascii") + override val commandNames = listOf("/ascii", "/asc") - private val fontSize = 12 - private val font = Font("Monospaced", Font.PLAIN, fontSize) + companion object { + private const val FONT_SIZE = 12 + private val font = Font("Monospaced", Font.PLAIN, FONT_SIZE) + val waitingList = mutableListOf() - private fun BufferedImage.convertToAscii(): String { - val width = this.width - val height = this.height - val asciiArt = StringBuilder() - for (y in 0 until height step 2) { - for (x in 0 until width) { - val pixel = Color(this.getRGB(x, y)) - val luminance = (0.2126 * pixel.red + 0.7152 * pixel.green + 0.0722 * pixel.blue).roundToInt() - val asciiChar = when (luminance) { - in 0..15 -> ' ' - in 16..31 -> '.' - in 32..47 -> ':' - in 48..63 -> '-' - in 64..79 -> '=' - in 80..95 -> '+' - in 96..111 -> '*' - in 112..127 -> '#' - in 128..143 -> '%' - in 144..159 -> '@' - in 160..175 -> 'a' - in 176..191 -> 'o' - in 192..207 -> 'e' - in 208..223 -> 'h' - in 224..239 -> 'u' - else -> '$' + private fun BufferedImage.convertToAscii(): String { + val width = this.width + val height = this.height + val asciiArt = StringBuilder() + for (y in 0 until height step 2) { + for (x in 0 until width) { + val pixel = Color(this.getRGB(x, y)) + val luminance = (0.2126 * pixel.red + 0.7152 * pixel.green + 0.0722 * pixel.blue).roundToInt() + val asciiChar = when (luminance) { + in 0..15 -> ' ' + in 16..31 -> '.' + in 32..47 -> ':' + in 48..63 -> '-' + in 64..79 -> '=' + in 80..95 -> '+' + in 96..111 -> '*' + in 112..127 -> '#' + in 128..143 -> '%' + in 144..159 -> '@' + in 160..175 -> 'a' + in 176..191 -> 'o' + in 192..207 -> 'e' + in 208..223 -> 'h' + in 224..239 -> 'u' + else -> '$' + } + asciiArt.append(asciiChar) } - asciiArt.append(asciiChar) + asciiArt.append("\n") } - asciiArt.append("\n") + return asciiArt.toString() } - return asciiArt.toString() - } - private fun String.saveAsciiArtToImage(width: Int, height: Int): String { - val imgWidth = width * fontSize / 2 - val imgHeight = height * fontSize / 2 - val img = BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB) - val g2d = img.createGraphics() - g2d.color = Color.BLACK - g2d.fillRect(0, 0, imgWidth, imgHeight) - g2d.color = Color.WHITE - g2d.font = font - val lines = this.split("\n") - for ((index, line) in lines.withIndex()) { - g2d.drawString(line, 0, (index + 1) * fontSize) + + private fun String.saveAsciiArtToImage(width: Int, height: Int): String { + val imgWidth = width * FONT_SIZE / 2 + val imgHeight = height * FONT_SIZE / 2 + val img = BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB) + val g2d = img.createGraphics() + g2d.color = Color.BLACK + g2d.fillRect(0, 0, imgWidth, imgHeight) + g2d.color = Color.WHITE + g2d.font = font + val lines = this.split("\n") + for ((index, line) in lines.withIndex()) { + g2d.drawString(line, 0, (index + 1) * FONT_SIZE) + } + g2d.dispose() + return img.toByteArray().encodeToBase64() + } + + suspend fun callback(message: GroupMessage) { + if (message.sender.userId in waitingList) { + if (message.message.any { it.type == ArrayMessageType.image }) { + val url = message.message.find { it.type == ArrayMessageType.image }!!.data.file!! + val bufferedImage = ImageIO.read(URI(url).toURL()) + val imageBase64 = + bufferedImage.convertToAscii().saveAsciiArtToImage(bufferedImage.width, bufferedImage.height) + val msg = MessageChain.Builder().addImage(imageBase64, true).build() + message.reply(msg) + } else { + message.reply("回复错误已取消本次操作") + } + waitingList.removeIf { it == message.sender.userId } + } } - g2d.dispose() - return img.toByteArray().encodeToBase64() } override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List) { - if (args.isEmpty()) { - val msg = MessageChain.Builder().addText("发送`/ascii <图片>`可以将图片转成ascii字符").build() - message.reply(msg) - return - } - val image = message.message.find { it.type == ArrayMessageType.image } - if (image == null) { - val msg = MessageChain.Builder().addText("输入一个图片来继续操作").build() + if (message.sender.userId !in waitingList) { + val msg = MessageChain.Builder() + .addText("请继续发送一张图片,如果输入错误则取消本次操作") + .build() message.reply(msg) + waitingList.add(message.sender.userId) return } else { - val url = image.data.file!! - val bufferedImage = ImageIO.read(URI(url).toURL()) - val ascii = bufferedImage.convertToAscii() - val image = ascii.saveAsciiArtToImage(bufferedImage.width, bufferedImage.height) - val msg = MessageChain.Builder().addImage(image, true).build() - message.reply(msg) + message.reply("先发送`/ascii`再继续操作吧~") + return } } } \ No newline at end of file