diff --git a/build.gradle.kts b/build.gradle.kts index 9b34e92..056b52c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,8 +5,10 @@ plugins { alias(libs.plugins.shadow) } +val fancyBotVersion: String by project + group = "cn.rtast" -version = "1.0-SNAPSHOT" +version = fancyBotVersion repositories { mavenCentral() diff --git a/gradle.properties b/gradle.properties index 7fc6f1f..7de1816 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ kotlin.code.style=official +fancyBotVersion=1.0.0 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 48abe3f..2b7c58e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] kotlinVersion = "2.0.10" -ronebotVersion = "1.2.6" +ronebotVersion = "1.4.1" shadowVersion = "8.3.0" okhttpVersion = "5.0.0-alpha.14" exposedVersion = "0.53.0" diff --git a/settings.gradle.kts b/settings.gradle.kts index 98fb1d9..73d9f0b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,2 @@ -plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" -} rootProject.name = "FancyBot" diff --git a/src/main/kotlin/cn/rtast/fancybot/Const.kt b/src/main/kotlin/cn/rtast/fancybot/Const.kt index dea9b45..b5764a4 100644 --- a/src/main/kotlin/cn/rtast/fancybot/Const.kt +++ b/src/main/kotlin/cn/rtast/fancybot/Const.kt @@ -27,3 +27,7 @@ val DEFAULT_CONFIG = Config( accessToken = "114514", port = 6760 ) + +val ADMINS = listOf( + 3458671395L +) \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt b/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt index 10deb49..975b5d6 100644 --- a/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt +++ b/src/main/kotlin/cn/rtast/fancybot/FancyBot.kt @@ -14,6 +14,7 @@ import cn.rtast.fancybot.commands.JrrpCommand import cn.rtast.fancybot.commands.MusicCommand import cn.rtast.fancybot.commands.MyPointCommand import cn.rtast.fancybot.commands.QRCodeCommand +import cn.rtast.fancybot.commands.RedeemCommand import cn.rtast.fancybot.commands.SignCommand import cn.rtast.fancybot.entity.enums.WSType import cn.rtast.fancybot.util.file.ConfigManager @@ -37,8 +38,7 @@ val commands = listOf( EchoCommand(), JrrpCommand(), MusicCommand(), - SignCommand(), - MyPointCommand(), + SignCommand(), RedeemCommand(), MyPointCommand(), HitokotoCommand(), FKXQSCommand(), QRCodeCommand() diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/FKXQSCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/FKXQSCommand.kt index 0b886c1..768c8ae 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/FKXQSCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/FKXQSCommand.kt @@ -11,6 +11,7 @@ import cn.rtast.fancybot.entity.FKXQS import cn.rtast.fancybot.util.Http import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.util.BaseCommand +import cn.rtast.rob.util.message.MessageChain import cn.rtast.rob.util.ob.OBMessage class FKXQSCommand: BaseCommand() { @@ -18,6 +19,10 @@ class FKXQSCommand: BaseCommand() { override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List) { val response = Http.get("https://api.shadiao.pro/kfc").data.text - listener.sendGroupMessage(message.groupId, response) + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText(response) + .build() + listener.sendGroupMessage(message.groupId, msg) } } \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/HitokotoCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/HitokotoCommand.kt index 1bc86fc..fa5d83b 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/HitokotoCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/HitokotoCommand.kt @@ -10,6 +10,7 @@ package cn.rtast.fancybot.commands import cn.rtast.fancybot.util.Http import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.util.BaseCommand +import cn.rtast.rob.util.message.MessageChain import cn.rtast.rob.util.ob.OBMessage class HitokotoCommand : BaseCommand() { @@ -17,6 +18,10 @@ class HitokotoCommand : BaseCommand() { override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List) { val response = Http.get("https://v1.jinrishici.com/rensheng/mengxiang.txt") - listener.sendGroupMessage(message.groupId, response) + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText(response) + .build() + listener.sendGroupMessage(message.groupId, msg) } } \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/JrrpCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/JrrpCommand.kt index be3955e..6e89980 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/JrrpCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/JrrpCommand.kt @@ -10,6 +10,7 @@ package cn.rtast.fancybot.commands import cn.rtast.fancybot.util.file.JrrpManager import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.util.BaseCommand +import cn.rtast.rob.util.message.MessageChain import cn.rtast.rob.util.ob.OBMessage class JrrpCommand : BaseCommand() { @@ -19,7 +20,11 @@ class JrrpCommand : BaseCommand() { override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List) { if (jrrpManager.isJrrped(message.sender.userId)) { - listener.sendGroupMessage(message.groupId, "你今天已经今日人品过啦, 明天再来吧~") + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("你今天已经今日人品过啦, 明天再来吧~") + .build() + listener.sendGroupMessage(message.groupId, msg) return } val randomPoint = jrrpManager.jrrp(message.sender.userId) @@ -30,6 +35,10 @@ class JrrpCommand : BaseCommand() { in 90..100 -> "人品超级好呢!" else -> "人品还行哦" } - listener.sendGroupMessage(message.groupId, "$scoreDesc($randomPoint)") + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("$scoreDesc($randomPoint)") + .build() + listener.sendGroupMessage(message.groupId, msg) } } \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/MusicCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/MusicCommand.kt index 0976e60..9b9a9ce 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/MusicCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/MusicCommand.kt @@ -14,6 +14,7 @@ import cn.rtast.fancybot.entity.music.SongUrl import cn.rtast.fancybot.util.Http import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.util.BaseCommand +import cn.rtast.rob.util.message.MessageChain import cn.rtast.rob.util.ob.OBMessage import java.time.Instant @@ -35,13 +36,14 @@ class MusicCommand : BaseCommand() { } val method = args.first() when (method) { - "s", "ss", "搜索" -> { + "s", "ss", "search", "搜索" -> { if (searchedResult.containsKey(message.sender.userId)) { searchedResult.remove(message.sender.userId) - listener.sendGroupMessage( - message.groupId, - "你上次的搜索结果还没用呢, 已经帮你把上次的搜索结果清除掉啦~" - ) + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("你上次的搜索结果还没用呢, 已经帮你把上次的搜索结果清除掉啦~") + .build() + listener.sendGroupMessage(message.groupId, msg) } val keyword = args.drop(1).joinToString(" ") val result = Http.get( @@ -59,10 +61,14 @@ class MusicCommand : BaseCommand() { stringResult.append("| $index | 《${searchedResult.name}》-- ${searchedResult.artists}\n") } stringResult.append("输入/music p <序号> 播放\n你有30秒的时间进行操作") - listener.sendGroupMessage(message.groupId, stringResult.toString()) + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText(stringResult.toString()) + .build() + listener.sendGroupMessage(message.groupId, msg) } - "p", "pp", "播放" -> { + "p", "pp", "play", "播放" -> { try { val index = args.drop(1).last().toInt() val searchedResultGet = searchedResult[message.sender.userId]!! @@ -72,11 +78,19 @@ class MusicCommand : BaseCommand() { "${configManager.ncmAPI}/song/url", mapOf("id" to finalResult.id) ).data.first().url - val cqCode = "[CQ:music,type=custom,url=https://music.163.com/#/song?id=${finalResult.id}," + - "audio=$url,title=《${finalResult.name}》-- ${finalResult.artists}]" - listener.sendGroupMessage(message.groupId, cqCode) + val msg = MessageChain.Builder() + .addCustomMusicShare( + "https://music.163.com/#/song?id=${finalResult.id}", + url, + "《${finalResult.name}》-- ${finalResult.artists}" + ).build() + listener.sendGroupMessage(message.groupId, msg) } catch (_: Exception) { - listener.sendGroupMessage(message.groupId, "输入有误请重新搜索本次搜索结果已清除") + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("输入有误请重新搜索本次搜索结果已清除") + .build() + listener.sendGroupMessage(message.groupId, msg) } searchedResult.remove(message.sender.userId) } diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/QRCodeCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/QRCodeCommand.kt index db4ae77..09e8e64 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/QRCodeCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/QRCodeCommand.kt @@ -9,6 +9,7 @@ package cn.rtast.fancybot.commands import cn.rtast.rob.entity.GroupMessage import cn.rtast.rob.util.BaseCommand +import cn.rtast.rob.util.message.MessageChain import cn.rtast.rob.util.ob.OBMessage class QRCodeCommand : BaseCommand() { @@ -16,9 +17,10 @@ class QRCodeCommand : BaseCommand() { override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List) { val content = args.joinToString(" ") - listener.sendGroupMessage( - message.groupId, - "[CQ:at,qq=${message.sender.userId}][CQ:image,file=https://api.rtast.cn/api/generate_qr?data=$content]" - ) + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addImage("https://api.rtast.cn/api/generate_qr?data=$content") + .build() + listener.sendGroupMessage(message.groupId, msg) } } \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/SignCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/SignCommand.kt index 0524e9d..35787de 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/SignCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/SignCommand.kt @@ -7,36 +7,143 @@ package cn.rtast.fancybot.commands +import cn.rtast.fancybot.ADMINS +import cn.rtast.fancybot.entity.Heisi +import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.file.SignManager import cn.rtast.rob.entity.GroupMessage +import cn.rtast.rob.enums.UserRole import cn.rtast.rob.util.BaseCommand +import cn.rtast.rob.util.message.MessageChain import cn.rtast.rob.util.ob.OBMessage private val signManager = SignManager() +private val items = mapOf( + "色图" to 50, + "黑丝" to 60 +) + class SignCommand : BaseCommand() { override val commandNames = listOf("/签到", "/sign") override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List) { if (signManager.isSigned(message.sender.userId)) { - listener.sendGroupMessage(message.groupId, "你今天已经签到, 明天再来吧~") + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("你今天已经签到过啦, 明天再来吧~") + .build() + listener.sendGroupMessage(message.groupId, msg) return } val randomPoint = signManager.sign(message.sender.userId) - listener.sendGroupMessage(message.groupId, "你获得了 $randomPoint 点分数!\n发送‘/我的点数’ 即可查看当前的点数") + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("你获得了 $randomPoint 点分数!") + .addNewLine() + .addText("发送‘/我的点数’ 或者 ‘/mp’ 即可查看当前的点数") + .build() + listener.sendGroupMessage(message.groupId, msg) } } -class MyPointCommand: BaseCommand() { +class MyPointCommand : BaseCommand() { override val commandNames = listOf("/我的点数", "/mp") override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List) { + if (args.isNotEmpty() && (message.sender.role == UserRole.admin || message.sender.userId in ADMINS)) { + val targetId = args.first().toLong() + val targetData = signManager.getStatus(targetId) + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + + if (targetData == null) { + msg.addText("用户不存在") + } else { + msg.addText("用户: ${targetData.id} 的点数有: ${targetData.points}") + } + listener.sendGroupMessage(message.groupId, msg.build()) + return + } val status = signManager.getStatus(message.sender.userId) if (status == null) { - listener.sendGroupMessage(message.groupId, "你还没有签到过呢! 先发送‘/签到’再来查询吧~") + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("你还没有签到过呢! 先发送‘/签到’再来查询吧~") + .build() + listener.sendGroupMessage(message.groupId, msg) return } else { - listener.sendGroupMessage(message.groupId, "你当前的点数为: ${status.points}") + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("你当前的点数为: ${status.points}") + .build() + listener.sendGroupMessage(message.groupId, msg) + } + } +} + +class RedeemCommand : BaseCommand() { + override val commandNames = listOf("/redeem", "/兑换", "/rdm") + + override suspend fun executeGroup(listener: OBMessage, message: GroupMessage, args: List) { + val status = signManager.getStatus(message.sender.userId) + val item = args.first() + if (item == "list" || item == "列表") { + val priceTable = items.entries.joinToString("\n") { (key, value) -> "名称: $key=$value 积分" } + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addNewLine() + .addText(priceTable) + .build() + listener.sendGroupMessage(message.groupId, msg) + return + } + val selectedItemKey = items.keys.find { it == item } + if (selectedItemKey == null) { + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("没有找到你想兑换的东西呢") + .addNewLine() + .addText("你可以输入/兑换 list来查看所有可兑换的物品") + .build() + listener.sendGroupMessage(message.groupId, msg) + return + } + val selectedItemPrice = items[item]!! + if (selectedItemPrice > status?.points!!) { + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("你的积分不够兑换这个物品呢~") + .addNewLine() + .addText("你有: ${status.points}个积分, 兑换需要: $selectedItemPrice 个积分~\"") + .build() + listener.sendGroupMessage(message.groupId, msg) + return + } + signManager.redeemItem(message.sender.userId, selectedItemPrice) + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addText("兑换成功正在发送奖品中~") + .build() + listener.sendGroupMessage(message.groupId, msg) + when (selectedItemKey) { + "黑丝", "hs", "heisi" -> { + val url = Http.get("https://v2.api-m.com/api/heisi").data + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addImage(url) + .build() + listener.sendGroupMessage(message.groupId, msg) + } + + "色图", "st", "setu" -> { + val msg = MessageChain.Builder() + .addAt(message.sender.userId) + .addImage("https://moe.jitsu.top/img/?sort=r18&size=small") + .build() + listener.sendGroupMessage(message.groupId, msg) + } } } } \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/entity/Heisi.kt b/src/main/kotlin/cn/rtast/fancybot/entity/Heisi.kt new file mode 100644 index 0000000..15b21f3 --- /dev/null +++ b/src/main/kotlin/cn/rtast/fancybot/entity/Heisi.kt @@ -0,0 +1,12 @@ +/* + * Copyright © 2024 RTAkland + * Author: RTAkland + * Date: 2024/8/31 + */ + + +package cn.rtast.fancybot.entity + +data class Heisi( + val data: String, +) \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/util/file/SignManager.kt b/src/main/kotlin/cn/rtast/fancybot/util/file/SignManager.kt index 06e2389..e818d02 100644 --- a/src/main/kotlin/cn/rtast/fancybot/util/file/SignManager.kt +++ b/src/main/kotlin/cn/rtast/fancybot/util/file/SignManager.kt @@ -12,8 +12,8 @@ import cn.rtast.fancybot.entity.SignTable import cn.rtast.fancybot.entity.SignTable.point import cn.rtast.fancybot.entity.SignTable.timestamp import cn.rtast.fancybot.entity.SignTable.userId -import cn.rtast.fancybot.util.suspendedTransaction import cn.rtast.fancybot.util.isSameDay +import cn.rtast.fancybot.util.suspendedTransaction import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.update @@ -67,4 +67,13 @@ class SignManager { suspend fun getStatus(id: Long): JrrpRecord? { return getRecord(id) } + + suspend fun redeemItem(id: Long, itemPrice: Int) { + val current = getRecord(id) + suspendedTransaction { + SignTable.update({ userId eq id }) { + it[point] = current?.points!! - itemPrice + } + } + } } \ No newline at end of file