From c68883a57f603cad0ff709328805c1e2bf72b885 Mon Sep 17 00:00:00 2001 From: StarWishsama Date: Fri, 6 Nov 2020 22:40:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E8=B5=84=E6=BA=90=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor: 修改 ID 格式判断规则 feat: 添加了一些辅助性方法 --- .../io/github/starwishsama/comet/Comet.kt | 10 +-- .../comet/api/command/CommandExecutor.kt | 14 ++--- .../comet/api/thirdparty/r6tab/R6TabApi.kt | 3 +- .../comet/commands/chats/ArkNightCommand.kt | 20 +++++- .../comet/commands/chats/DebugCommand.kt | 15 +++++ ...ctureSearch.kt => PictureSearchCommand.kt} | 2 +- .../comet/commands/chats/R6SCommand.kt | 5 +- .../starwishsama/comet/file/DataSetup.kt | 6 +- .../comet/objects/draw/pool/ArkNightPool.kt | 5 +- .../starwishsama/comet/utils/DrawUtil.kt | 61 +++++++++++++------ .../starwishsama/comet/utils/FileUtil.kt | 8 +++ .../starwishsama/comet/utils/StringUtil.kt | 31 +++++++++- .../starwishsama/comet/utils/TaskUtil.kt | 8 +-- .../comet/utils/network/NetUtil.kt | 56 ++++++++--------- 14 files changed, 160 insertions(+), 84 deletions(-) rename src/main/kotlin/io/github/starwishsama/comet/commands/chats/{PictureSearch.kt => PictureSearchCommand.kt} (98%) diff --git a/src/main/kotlin/io/github/starwishsama/comet/Comet.kt b/src/main/kotlin/io/github/starwishsama/comet/Comet.kt index eb790994d..4b433d18f 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/Comet.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/Comet.kt @@ -19,8 +19,8 @@ import io.github.starwishsama.comet.listeners.ConvertLightAppListener import io.github.starwishsama.comet.listeners.RepeatListener import io.github.starwishsama.comet.pushers.* import io.github.starwishsama.comet.utils.FileUtil +import io.github.starwishsama.comet.utils.StringUtil.getLastingTime import io.github.starwishsama.comet.utils.StringUtil.isNumeric -import io.github.starwishsama.comet.utils.StringUtil.toFriendly import io.github.starwishsama.comet.utils.TaskUtil import io.github.starwishsama.comet.utils.getContext import io.github.starwishsama.comet.utils.network.NetUtil @@ -37,12 +37,10 @@ import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.FileCacheStrategy import net.mamoe.mirai.utils.PlatformLogger import net.mamoe.mirai.utils.secondsToMillis -import java.time.Duration import java.time.LocalDateTime import java.util.* import java.util.concurrent.TimeUnit import kotlin.time.ExperimentalTime -import kotlin.time.toKotlinDuration object Comet { @ExperimentalTime @@ -153,7 +151,7 @@ object Comet { InfoCommand(), MusicCommand(), MuteCommand(), - PictureSearch(), + PictureSearchCommand(), R6SCommand(), RConCommand(), KickCommand(), @@ -183,9 +181,7 @@ object Comet { startUpTask() startAllPusher(bot) - val duration = Duration.between(startTime, LocalDateTime.now()) - - logger.info("彗星 Bot 启动成功, 耗时 ${duration.toKotlinDuration().toFriendly()}") + logger.info("彗星 Bot 启动成功, 耗时 ${startTime.getLastingTime()}") Runtime.getRuntime().addShutdownHook(Thread { logger.info("[Bot] 正在关闭 Bot...") diff --git a/src/main/kotlin/io/github/starwishsama/comet/api/command/CommandExecutor.kt b/src/main/kotlin/io/github/starwishsama/comet/api/command/CommandExecutor.kt index 1616e3000..c40714f95 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/api/command/CommandExecutor.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/api/command/CommandExecutor.kt @@ -11,6 +11,7 @@ import io.github.starwishsama.comet.sessions.Session import io.github.starwishsama.comet.sessions.SessionManager import io.github.starwishsama.comet.utils.BotUtil import io.github.starwishsama.comet.utils.StringUtil.convertToChain +import io.github.starwishsama.comet.utils.StringUtil.getLastingTime import io.github.starwishsama.comet.utils.debugS import io.github.starwishsama.comet.utils.network.NetUtil import net.mamoe.mirai.Bot @@ -19,13 +20,10 @@ import net.mamoe.mirai.event.subscribeMessages import net.mamoe.mirai.message.GroupMessageEvent import net.mamoe.mirai.message.MessageEvent import net.mamoe.mirai.message.data.* -import net.mamoe.mirai.utils.asHumanReadable -import java.time.Duration import java.time.LocalDateTime import java.util.* -import kotlin.time.DurationUnit +import java.util.concurrent.TimeUnit import kotlin.time.ExperimentalTime -import kotlin.time.toKotlinDuration /** * 彗星 Bot 命令处理器 @@ -107,8 +105,8 @@ object CommandExecutor { if (isCommand) { BotVariables.logger.debugS( - "[命令] 命令执行耗时 ${Duration.between(executedTime, LocalDateTime.now()).toKotlinDuration().asHumanReadable}" + - if (result.result.isNotEmpty()) ", 执行结果: ${result.result}" else "" + "[命令] 命令执行耗时 ${executedTime.getLastingTime(builtInMethod = true)}" + + if (result.result.isNotEmpty()) ", 执行结果: ${result.result}" else "" ) } } @@ -225,10 +223,8 @@ object CommandExecutor { } } - val usedTime = Duration.between(time, LocalDateTime.now()) BotVariables.logger.debug( - "[会话] 处理会话耗时 ${usedTime.toKotlinDuration().toLong(DurationUnit.SECONDS)}s${usedTime.toKotlinDuration() - .toLong(DurationUnit.MILLISECONDS)}ms" + "[会话] 处理会话耗时 ${time.getLastingTime(unit = TimeUnit.SECONDS, msMode = true)}" ) return true } diff --git a/src/main/kotlin/io/github/starwishsama/comet/api/thirdparty/r6tab/R6TabApi.kt b/src/main/kotlin/io/github/starwishsama/comet/api/thirdparty/r6tab/R6TabApi.kt index 64e492d9f..517775697 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/api/thirdparty/r6tab/R6TabApi.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/api/thirdparty/r6tab/R6TabApi.kt @@ -10,6 +10,7 @@ import io.github.starwishsama.comet.BotVariables.logger import io.github.starwishsama.comet.enums.R6Rank import io.github.starwishsama.comet.objects.pojo.rainbowsix.R6Player import io.github.starwishsama.comet.utils.BotUtil +import io.github.starwishsama.comet.utils.IDGuidelineType import io.github.starwishsama.comet.utils.StringUtil import io.github.starwishsama.comet.utils.network.NetUtil import java.text.NumberFormat @@ -49,7 +50,7 @@ object R6TabApi { fun getR6SInfo(player: String): String { try { - if (StringUtil.isLegitId(player)) { + if (StringUtil.isLegitId(player, IDGuidelineType.UBISOFT)) { val p: R6Player? = searchPlayer(player) if (p != null && p.found) { var response = String.format( diff --git a/src/main/kotlin/io/github/starwishsama/comet/commands/chats/ArkNightCommand.kt b/src/main/kotlin/io/github/starwishsama/comet/commands/chats/ArkNightCommand.kt index f69c355bb..53030cf63 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/commands/chats/ArkNightCommand.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/commands/chats/ArkNightCommand.kt @@ -34,7 +34,15 @@ class ArkNightCommand : ChatCommand { event.reply("请稍等...") val list = pool.getArkDrawResult(user) if (list.isNotEmpty()) { - val gachaImage = withContext(Dispatchers.Default) { DrawUtil.combineArkOpImage(list).upload(event.subject) } + val result = DrawUtil.combineArkOpImage(list) + event.quoteReply(BotUtil.sendMessage("由于缺失资源文件, 以下干员无法显示 :(\n" + + buildString { + result.lostOps.forEach { + append("${it.name},") + } + removeSuffix(",") + })) + val gachaImage = withContext(Dispatchers.Default) { result.image.upload(event.subject) } gachaImage.asMessageChain() } else { DrawUtil.overTimeMessage.convertToChain() @@ -48,7 +56,15 @@ class ArkNightCommand : ChatCommand { event.reply("请稍等...") val list: List = pool.getArkDrawResult(user, 10) if (list.isNotEmpty()) { - val gachaImage = withContext(Dispatchers.Default) { DrawUtil.combineArkOpImage(list).upload(event.subject) } + val result = DrawUtil.combineArkOpImage(list) + event.quoteReply(BotUtil.sendMessage("由于缺失资源文件, 以下干员无法显示 :(\n" + + buildString { + result.lostOps.forEach { + append("${it.name},") + } + removeSuffix(",") + })) + val gachaImage = withContext(Dispatchers.Default) { result.image.upload(event.subject) } gachaImage.asMessageChain() } else { DrawUtil.overTimeMessage.convertToChain() diff --git a/src/main/kotlin/io/github/starwishsama/comet/commands/chats/DebugCommand.kt b/src/main/kotlin/io/github/starwishsama/comet/commands/chats/DebugCommand.kt index a8137e021..6ebe2ccc3 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/commands/chats/DebugCommand.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/commands/chats/DebugCommand.kt @@ -11,6 +11,7 @@ import io.github.starwishsama.comet.api.thirdparty.youtube.YoutubeApi import io.github.starwishsama.comet.enums.UserLevel import io.github.starwishsama.comet.file.DataSetup import io.github.starwishsama.comet.objects.BotUser +import io.github.starwishsama.comet.objects.draw.items.ArkNightOperator import io.github.starwishsama.comet.pushers.HitokotoUpdater import io.github.starwishsama.comet.pushers.TweetUpdateChecker import io.github.starwishsama.comet.pushers.YoutubeStreamingChecker @@ -143,6 +144,20 @@ class DebugCommand : ChatCommand, UnDisableableCommand { """.trimIndent().convertToChain() } "panic" -> throw RuntimeException("好") + "ark" -> { + var op: ArkNightOperator? = null + + if (args.size > 1) { + BotVariables.arkNight.parallelStream().forEach { + if (args[1] == it.name) { + op = it + return@forEach + } + } + } + + return op.toString().convertToChain() + } "twpic" -> { if (args.isEmpty()) return "/debug twpic [Tweet ID]".convertToChain() else { diff --git a/src/main/kotlin/io/github/starwishsama/comet/commands/chats/PictureSearch.kt b/src/main/kotlin/io/github/starwishsama/comet/commands/chats/PictureSearchCommand.kt similarity index 98% rename from src/main/kotlin/io/github/starwishsama/comet/commands/chats/PictureSearch.kt rename to src/main/kotlin/io/github/starwishsama/comet/commands/chats/PictureSearchCommand.kt index a09064903..d7d436bfa 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/commands/chats/PictureSearch.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/commands/chats/PictureSearchCommand.kt @@ -20,7 +20,7 @@ import net.mamoe.mirai.message.data.queryUrl import java.util.* @CometCommand -class PictureSearch : ChatCommand, SuspendCommand { +class PictureSearchCommand : ChatCommand, SuspendCommand { override suspend fun execute(event: MessageEvent, args: List, user: BotUser): MessageChain { if (BotUtil.hasNoCoolDown(event.sender.id)) { if (args.isEmpty() || SessionManager.isValidSessionById(event.sender.id)) { diff --git a/src/main/kotlin/io/github/starwishsama/comet/commands/chats/R6SCommand.kt b/src/main/kotlin/io/github/starwishsama/comet/commands/chats/R6SCommand.kt index 455ebdc06..ab3d55bec 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/commands/chats/R6SCommand.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/commands/chats/R6SCommand.kt @@ -8,6 +8,7 @@ import io.github.starwishsama.comet.enums.UserLevel import io.github.starwishsama.comet.objects.BotUser import io.github.starwishsama.comet.utils.BotUtil import io.github.starwishsama.comet.utils.BotUtil.hasNoCoolDown +import io.github.starwishsama.comet.utils.IDGuidelineType import io.github.starwishsama.comet.utils.StringUtil.isLegitId import net.mamoe.mirai.message.GroupMessageEvent import net.mamoe.mirai.message.MessageEvent @@ -30,7 +31,7 @@ class R6SCommand : ChatCommand { val result = getR6SInfo(account) event.sender.at() + ("\n" + result) } else { - if (isLegitId(args[1])) { + if (isLegitId(args[1], IDGuidelineType.UBISOFT)) { event.reply(BotUtil.sendMessage("查询中...")) val result = getR6SInfo(args[1]) event.sender.at() + ("\n" + result) @@ -41,7 +42,7 @@ class R6SCommand : ChatCommand { } "bind", "绑定" -> if (args[1].isNotEmpty() && args.size > 1) { - if (isLegitId(args[1])) { + if (isLegitId(args[1], IDGuidelineType.UBISOFT)) { val botUser1 = BotUser.getUser(event.sender.id) if (botUser1 != null) { botUser1.r6sAccount = args[1] diff --git a/src/main/kotlin/io/github/starwishsama/comet/file/DataSetup.kt b/src/main/kotlin/io/github/starwishsama/comet/file/DataSetup.kt index c07ac066c..6f3abb243 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/file/DataSetup.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/file/DataSetup.kt @@ -7,6 +7,7 @@ import com.google.gson.JsonElement import com.google.gson.JsonObject import com.google.gson.JsonParser import io.github.starwishsama.comet.BotVariables +import io.github.starwishsama.comet.BotVariables.arkNight import io.github.starwishsama.comet.BotVariables.cfg import io.github.starwishsama.comet.BotVariables.daemonLogger import io.github.starwishsama.comet.BotVariables.gson @@ -76,8 +77,9 @@ object DataSetup { } if (arkNightData.exists()) { - BotVariables.arkNight = gson.fromJson(arkNightData.getContext()) - daemonLogger.info("成功载入明日方舟游戏数据, 共 ${BotVariables.arkNight.size} 个") + arkNight = gson.fromJson(arkNightData.getContext()) + + daemonLogger.info("成功载入明日方舟游戏数据, 共 ${arkNight.size} 个") if (cfg.arkDrawUseImage) { DrawUtil.downloadArkNightsFile() } diff --git a/src/main/kotlin/io/github/starwishsama/comet/objects/draw/pool/ArkNightPool.kt b/src/main/kotlin/io/github/starwishsama/comet/objects/draw/pool/ArkNightPool.kt index 66d522b8c..a5ba3c86a 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/objects/draw/pool/ArkNightPool.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/objects/draw/pool/ArkNightPool.kt @@ -17,10 +17,7 @@ import java.util.stream.Collectors class ArkNightPool(override val name: String = "标准寻访") : GachaPool() { override val tenjouCount: Int = -1 override val tenjouRare: Int = -1 - override val poolItems: MutableList = - BotVariables.arkNight.parallelStream().filter { - it.obtain.contains("标准寻访") && it.obtain.contains("限定寻访") - }.collect(Collectors.toList()) + override val poolItems: MutableList = BotVariables.arkNight override fun doDraw(time: Int): List { val result = mutableListOf() diff --git a/src/main/kotlin/io/github/starwishsama/comet/utils/DrawUtil.kt b/src/main/kotlin/io/github/starwishsama/comet/utils/DrawUtil.kt index ea3ed3e4b..cee606542 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/utils/DrawUtil.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/utils/DrawUtil.kt @@ -1,15 +1,20 @@ package io.github.starwishsama.comet.utils +import cn.hutool.core.net.URLEncoder import io.github.starwishsama.comet.BotVariables.arkNight import io.github.starwishsama.comet.BotVariables.daemonLogger import io.github.starwishsama.comet.enums.UserLevel +import io.github.starwishsama.comet.exceptions.ApiException import io.github.starwishsama.comet.objects.BotUser import io.github.starwishsama.comet.objects.draw.items.ArkNightOperator +import io.github.starwishsama.comet.utils.StringUtil.getLastingTime import io.github.starwishsama.comet.utils.network.NetUtil import java.awt.Image import java.awt.image.BufferedImage import java.io.File import java.io.InputStream +import java.nio.charset.Charset +import java.time.LocalDateTime import javax.imageio.ImageIO object DrawUtil { @@ -21,18 +26,16 @@ object DrawUtil { "命令条数现在每小时会恢复100次, 封顶1000次" // 干员名称/干员名称.png - const val resourceUrl = "https://cdn.jsdelivr.net/gh/godofhuaye/arknight-assets@master/cg/" + private const val resourceUrl = "https://cdn.jsdelivr.net/gh/godofhuaye/arknight-assets@master/cg" /** * 根据抽卡结果合成图片 */ - fun combineArkOpImage(ops: List): BufferedImage { + fun combineArkOpImage(ops: List): CombinedResult { require(ops.isNotEmpty()) { "传入的干员列表不能为空!" } - /** - * 缩小图片大小,减少流量消耗 - */ - val zoom = 2 + val lostOperators = mutableListOf() + val picSize = 180 val newBufferedImage = BufferedImage(picSize * ops.size, picSize, BufferedImage.TYPE_INT_RGB) @@ -40,27 +43,27 @@ object DrawUtil { val createGraphics = newBufferedImage.createGraphics() var newBufferedImageWidth = 0 - val newBufferedImageHeight = 0 for (i in ops) { val file = File(FileUtil.getResourceFolder().getChildFolder("ark"), i.name + ".png") if (!file.exists()) { + lostOperators.plusAssign(i) daemonLogger.warning("明日方舟: 干员 ${i.name} 的图片不存在") } else { val inStream: InputStream = file.inputStream() val bufferedImage: BufferedImage = ImageIO.read(inStream) - val imageWidth = bufferedImage.width / zoom - val imageHeight = bufferedImage.height / zoom + val imageWidth = bufferedImage.width + val imageHeight = bufferedImage.height createGraphics.drawImage( bufferedImage.getScaledInstance( imageWidth, imageHeight, Image.SCALE_SMOOTH - ), newBufferedImageWidth, newBufferedImageHeight, imageWidth, imageHeight, null + ), newBufferedImageWidth, 0, imageWidth, imageHeight, null ) newBufferedImageWidth += imageWidth @@ -70,10 +73,15 @@ object DrawUtil { createGraphics.dispose() - return newBufferedImage + return CombinedResult(newBufferedImage, lostOperators) } + data class CombinedResult( + val image: BufferedImage, + val lostOps: List + ) + fun getStar(rare: Int): String = StringBuilder().apply { for (i in 0 until rare) { append("★") @@ -84,18 +92,37 @@ object DrawUtil { (user.commandTime >= time || user.compareLevel(UserLevel.ADMIN)) && time <= 10000 fun downloadArkNightsFile() { - if (FileUtil.getResourceFolder().getChildFolder("ark").isEmpty()) { + if (FileUtil.getResourceFolder().getChildFolder("ark").filesCount() < arkNight.size) { + val startTime = LocalDateTime.now() daemonLogger.info("正在下载 明日方舟图片资源文件") + + val arkLoc = FileUtil.getResourceFolder().getChildFolder("ark") + + var successCount = 0 + arkNight.forEach { val fileName = "${it.name}.png" + val pathName = URLEncoder.createDefault().encode("${it.name}/$fileName", Charset.forName("UTF-8")) try { - NetUtil.downloadFile(FileUtil.getResourceFolder().getChildFolder("ark"), "$resourceUrl$it.name/$fileName", fileName) - } catch (e: RuntimeException) { - daemonLogger.warning("下载 $fileName 时出现了意外", e) - return + val file = File(arkLoc, fileName) + if (!file.exists()) { + val result = TaskUtil.executeWithRetry(3) { + NetUtil.downloadFile(arkLoc, "$resourceUrl/$pathName", fileName) + successCount++ + } + if (result != null) throw result + } + } catch (e: Exception) { + if (e !is ApiException) + daemonLogger.warning("下载 $fileName 时出现了意外", e) + return@forEach + } finally { + if (successCount > 0 && successCount % 10 == 0) { + daemonLogger.info("明日方舟 > 已下载 $successCount/${arkNight.size}") + } } } - daemonLogger.info("下载明日方舟资源文件完成!") + daemonLogger.info("明日方舟 > 资源文件下载成功, 耗时 ${startTime.getLastingTime()}") } } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/starwishsama/comet/utils/FileUtil.kt b/src/main/kotlin/io/github/starwishsama/comet/utils/FileUtil.kt index db8f0c52a..9e7f4aba2 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/utils/FileUtil.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/utils/FileUtil.kt @@ -67,6 +67,14 @@ fun File.isEmpty(): Boolean { return files.isEmpty() } +fun File.filesCount(): Int { + if (!isDirectory) return -1 + + val files = listFiles() ?: return -1 + + return files.size +} + object FileUtil { private val dateFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss") diff --git a/src/main/kotlin/io/github/starwishsama/comet/utils/StringUtil.kt b/src/main/kotlin/io/github/starwishsama/comet/utils/StringUtil.kt index a67a9c776..990e36602 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/utils/StringUtil.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/utils/StringUtil.kt @@ -1,12 +1,21 @@ package io.github.starwishsama.comet.utils +import io.github.starwishsama.comet.utils.IDGuidelineType.MINECRAFT +import io.github.starwishsama.comet.utils.IDGuidelineType.UBISOFT import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.PlainText import net.mamoe.mirai.message.data.asMessageChain +import net.mamoe.mirai.utils.asHumanReadable +import java.time.LocalDateTime import java.util.concurrent.TimeUnit import kotlin.time.Duration import kotlin.time.DurationUnit import kotlin.time.ExperimentalTime +import kotlin.time.toKotlinDuration + +enum class IDGuidelineType { + MINECRAFT, UBISOFT +} object StringUtil { /** @@ -16,14 +25,18 @@ object StringUtil { * @param username 用户名 * @return 是否符合规范 */ - fun isLegitId(username: String): Boolean { - return username.matches(Regex("[a-zA-Z0-9_.-]*")) + fun isLegitId(username: String, type: IDGuidelineType): Boolean { + return when (type) { + UBISOFT -> username.matches(Regex("[a-zA-Z0-9_.-]*")) + MINECRAFT -> username.matches(Regex("[a-zA-Z0-9_-]*")) + } } /** * 来自 Mirai 的 asHumanReadable */ - @ExperimentalTime + + @OptIn(ExperimentalTime::class) fun Duration.toFriendly(maxUnit: DurationUnit = TimeUnit.DAYS, msMode: Boolean = true): String { val days = toInt(DurationUnit.DAYS) val hours = toInt(DurationUnit.HOURS) % 24 @@ -57,4 +70,16 @@ object StringUtil { fun String.limitStringSize(size: Int): String { return if (length <= size) this else substring(0, size) + "..." } + + /** + * 获取该 [LocalDateTime] 距今的时间并转换为友好的字符串 + * + * @param msMode 是否精准到毫秒 + * @param builtInMethod 是否使用 Mirai 的 [Duration.asHumanReadable] + */ + @OptIn(ExperimentalTime::class) + fun LocalDateTime.getLastingTime(unit: TimeUnit = TimeUnit.SECONDS, msMode: Boolean = false, builtInMethod: Boolean = false): String { + val duration = java.time.Duration.between(this, LocalDateTime.now()).toKotlinDuration() + return if (builtInMethod) duration.asHumanReadable else duration.toFriendly(maxUnit = unit, msMode = msMode) + } } \ No newline at end of file diff --git a/src/main/kotlin/io/github/starwishsama/comet/utils/TaskUtil.kt b/src/main/kotlin/io/github/starwishsama/comet/utils/TaskUtil.kt index e03dcf6ea..56e9fd00b 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/utils/TaskUtil.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/utils/TaskUtil.kt @@ -2,7 +2,7 @@ package io.github.starwishsama.comet.utils import io.github.starwishsama.comet.BotVariables import io.github.starwishsama.comet.BotVariables.daemonLogger -import io.github.starwishsama.comet.exceptions.RateLimitException +import io.github.starwishsama.comet.exceptions.ApiException import io.github.starwishsama.comet.exceptions.ReachRetryLimitException import io.github.starwishsama.comet.utils.network.NetUtil import java.util.concurrent.ScheduledFuture @@ -27,12 +27,12 @@ object TaskUtil { } else { throw ReachRetryLimitException() } - } catch (e: RuntimeException) { + } catch (e: Exception) { if (NetUtil.isTimeout(e)) { daemonLogger.verbose("Retried $it time(s), connect times out") return@repeat - } else { - if (e !is RateLimitException) return e + } else if (e !is ApiException) { + return e } } } diff --git a/src/main/kotlin/io/github/starwishsama/comet/utils/network/NetUtil.kt b/src/main/kotlin/io/github/starwishsama/comet/utils/network/NetUtil.kt index 733a77565..8a0843350 100644 --- a/src/main/kotlin/io/github/starwishsama/comet/utils/network/NetUtil.kt +++ b/src/main/kotlin/io/github/starwishsama/comet/utils/network/NetUtil.kt @@ -1,8 +1,6 @@ package io.github.starwishsama.comet.utils.network -import cn.hutool.core.io.IORuntimeException import cn.hutool.http.* -import io.github.starwishsama.comet.BotVariables import io.github.starwishsama.comet.BotVariables.cfg import io.github.starwishsama.comet.BotVariables.daemonLogger import io.github.starwishsama.comet.utils.debugS @@ -24,7 +22,6 @@ import java.net.Socket import java.net.URL import java.time.Duration import java.time.LocalDateTime -import java.util.* import kotlin.time.ExperimentalTime fun HttpResponse.getContentLength(): Int { @@ -117,43 +114,38 @@ object NetUtil { */ fun downloadFile(fileFolder: File, address: String, fileName: String): File? { val file = File(fileFolder, fileName) - try { - val response = doHttpRequestGet(address, 2000).executeAsync() - - if (response.isOk) { - val `in` = BufferedInputStream(response.bodyStream()) - if (!file.exists()) file.createNewFile() - val fos = FileOutputStream(file) - val bos = BufferedOutputStream(fos, 2048) - val data = ByteArray(2048) - var x: Int - while (`in`.read(data, 0, 2048).also { x = it } >= 0) { - bos.write(data, 0, x) - } - bos.close() - `in`.close() - fos.close() - } else { - BotVariables.logger.error("在下载时发生了错误, 响应码 ${response.status}") - } - } catch (e: Exception) { - if (!file.delete()) { - BotVariables.logger.error("无法删除损坏文件: $fileName") - } - if (e.cause is IORuntimeException) { - BotVariables.logger.error("在下载时发生了错误: 连接超时") - return null + + val conn = URL(address) + + val connUrl = conn.openConnection() as HttpURLConnection + connUrl.doOutput = true + connUrl.instanceFollowRedirects = true + connUrl.connect() + + if (connUrl.responseCode in 200..300) { + val `in` = BufferedInputStream(connUrl.inputStream) + if (!file.exists()) file.createNewFile() + val fos = FileOutputStream(file) + val bos = BufferedOutputStream(fos, 2048) + val data = ByteArray(2048) + var x: Int + while (`in`.read(data, 0, 2048).also { x = it } >= 0) { + bos.write(data, 0, x) } - BotVariables.logger.error("在下载时发生了错误") + bos.close() + `in`.close() + fos.close() + } else { + throw RuntimeException("在下载时发生了错误, 响应码 ${connUrl.responseCode}") } return file } fun isTimeout(t: Throwable): Boolean { - val msg = t.message?.toLowerCase(Locale.ROOT) ?: return t is IOException + val msg = t.message?.toLowerCase() ?: return t is IOException // FIXME: 这不是一个很好的识别方法 - return t is IOException || (msg.contains("time") && msg.contains("out")) || t.javaClass.simpleName.toLowerCase(Locale.ROOT).contains("timeout") + return (msg.contains("time") && msg.contains("out")) || t.javaClass.simpleName.toLowerCase().contains("timeout") } @Throws(HttpException::class)