diff --git a/src/main/kotlin/net/taehui/twilight/BaseCompiler.kt b/src/main/kotlin/net/taehui/twilight/BaseCompiler.kt index d2c9f0b..6f15166 100644 --- a/src/main/kotlin/net/taehui/twilight/BaseCompiler.kt +++ b/src/main/kotlin/net/taehui/twilight/BaseCompiler.kt @@ -188,7 +188,7 @@ try { targetCompiler = BMSONCompiler(noteFileData, format) targetCompiler.handleCompile(defaultComputer) - } catch (e: Throwable) { + } catch (e: JacksonException) { targetCompiler = BMSCompiler(noteFileData, format) targetCompiler.handleCompile(defaultComputer) } diff --git a/src/main/kotlin/net/taehui/twilight/Component.kt b/src/main/kotlin/net/taehui/twilight/Component.kt index e400652..cb56b5f 100644 --- a/src/main/kotlin/net/taehui/twilight/Component.kt +++ b/src/main/kotlin/net/taehui/twilight/Component.kt @@ -38,7 +38,8 @@ BAND1(2), F(4), HIGHER_CLEAR(5), - HIGHEST_CLEAR(6); + HIGHEST_CLEAR(6), + ASSIST_CLEAR(7); @JsonValue fun getValue(): Int { @@ -58,6 +59,7 @@ 4 -> F 5 -> HIGHER_CLEAR 6 -> HIGHEST_CLEAR + 7 -> ASSIST_CLEAR else -> throw IllegalArgumentException(value.toString()) } } diff --git a/src/main/kotlin/net/taehui/twilight/Twilight.kt b/src/main/kotlin/net/taehui/twilight/Twilight.kt index e4285af..c71a997 100644 --- a/src/main/kotlin/net/taehui/twilight/Twilight.kt +++ b/src/main/kotlin/net/taehui/twilight/Twilight.kt @@ -35,7 +35,7 @@ Files.createDirectories(TwilightComponent.ABILITY_ENTRY_PATH) Files.createDirectories(TwilightComponent.EDGE_ENTRY_PATH) } catch (e: IOException) { - System.err.println("Cannot run Twilight from ${Paths.get("").absolute()}") + System.err.println("Cannot run Twilight from ${Paths.get(".").absolute()}") Runtime.getRuntime().exit(1) } diff --git a/src/main/kotlin/net/taehui/twilight/Utility.kt b/src/main/kotlin/net/taehui/twilight/Utility.kt index e7e00ae..1bca3f2 100644 --- a/src/main/kotlin/net/taehui/twilight/Utility.kt +++ b/src/main/kotlin/net/taehui/twilight/Utility.kt @@ -105,4 +105,22 @@ fun getDataID(noteID: String): Int { return noteID.split(':')[1].toInt() } + + fun isDefaultHandled( + autoMode: Int, + judgmentMode: Int, + hitPointsMode: Int, + longNoteMode: Int, + inputFavorMode: Int, + noteModifyMode: Int, + lowestAudioMultiplier: Double + ): Boolean { + return autoMode == Component.DEFAULT_AUTO_MODE && + (judgmentMode == Component.DEFAULT_JUDGMENT_MODE || judgmentMode == Component.HIGHER_JUDGMENT_MODE || judgmentMode == Component.HIGHEST_JUDGMENT_MODE) && + (hitPointsMode == Component.DEFAULT_HIT_POINTS_MODE || hitPointsMode == Component.HIGHER_HIT_POINTS_MODE || hitPointsMode == Component.HIGHEST_HIT_POINTS_MODE || hitPointsMode == Component.FAILED_HIT_POINTS_MODE) && + longNoteMode == Component.DEFAULT_LONG_NOTE_MODE && + inputFavorMode == Component.DEFAULT_INPUT_FAVOR_MODE && + noteModifyMode == Component.DEFAULT_NOTE_MODIFY_MODE && + lowestAudioMultiplier >= 1.0 + } } \ No newline at end of file diff --git a/src/main/kotlin/net/taehui/twilight/qwilight/QwilightAvatar.kt b/src/main/kotlin/net/taehui/twilight/qwilight/QwilightAvatar.kt index f7b7112..f28cb0c 100644 --- a/src/main/kotlin/net/taehui/twilight/qwilight/QwilightAvatar.kt +++ b/src/main/kotlin/net/taehui/twilight/qwilight/QwilightAvatar.kt @@ -863,9 +863,18 @@ } } } - if ((judgmentMode == Component.DEFAULT_JUDGMENT_MODE || judgmentMode == Component.HIGHER_JUDGMENT_MODE || judgmentMode == Component.HIGHEST_JUDGMENT_MODE) && (hitPointsMode == Component.DEFAULT_HIT_POINTS_MODE || hitPointsMode == Component.HIGHER_HIT_POINTS_MODE || hitPointsMode == Component.HIGHEST_HIT_POINTS_MODE || hitPointsMode == Component.FAILED_HIT_POINTS_MODE) && longNoteMode == Component.DEFAULT_LONG_NOTE_MODE && inputFavorMode == Component.DEFAULT_INPUT_FAVOR_MODE && noteModifyMode == Component.DEFAULT_NOTE_MODIFY_MODE && lowestAudioMultiplier >= 1.0) { - DB.saveHandled(avatarID, targetComputing.noteID, isP, hitPointsMode) - } + DB.saveHandled( + avatarID, + targetComputing.noteID, + isP, + autoMode, + judgmentMode, + hitPointsMode, + longNoteMode, + inputFavorMode, + noteModifyMode, + lowestAudioMultiplier + ) if (SiteHandler.hasAvatar(this, SiteHandler.commentSiteID)) { SiteHandler.putSiteYell( SiteHandler.commentSiteID, diff --git a/src/main/kotlin/net/taehui/twilight/system/DB.kt b/src/main/kotlin/net/taehui/twilight/system/DB.kt index 15b6936..856e4d6 100644 --- a/src/main/kotlin/net/taehui/twilight/system/DB.kt +++ b/src/main/kotlin/net/taehui/twilight/system/DB.kt @@ -546,31 +546,35 @@ return logFuture { pool.connection.use { it.autoCommit = false - val pmsNoteID = "${Utility.getNoteID512(noteID)}:1" - it.prepareStatement( - """ + try { + val pmsNoteID = "${Utility.getNoteID512(noteID)}:1" + it.prepareStatement( + """ DELETE FROM tw_note WHERE Note_ID = ? """.trimIndent() - ).use { dbStatement -> - dbStatement.setString(1, noteID) - if (dbStatement.executeUpdate() > 0) { - logger.logInfo("Wiped Note") + ).use { dbStatement -> + dbStatement.setString(1, noteID) + if (dbStatement.executeUpdate() > 0) { + logger.logInfo("Wiped Note") + } } - } - it.prepareStatement( - """ + it.prepareStatement( + """ UPDATE tw_comment SET Note_ID = ? WHERE Note_ID = ? """.trimIndent() - ).use { dbStatement -> - dbStatement.setString(1, pmsNoteID) - dbStatement.setString(2, noteID) - logger.logInfo("PMSed ${dbStatement.executeUpdate()} Comments") + ).use { dbStatement -> + dbStatement.setString(1, pmsNoteID) + dbStatement.setString(2, noteID) + logger.logInfo("PMSed ${dbStatement.executeUpdate()} Comments") + } + it.commit() + } catch (e: Throwable) { + it.rollback() } - it.commit() } } } @@ -745,19 +749,21 @@ } fun learnHandled(futureLearnHandledStatus: AtomicInteger) { - data class Comment(val avatar: String, val noteID: String, val hitPointsMode: Int, val isP: Boolean) + data class Comment( + val avatar: String, + val noteID: String, + val hitPointsMode: Int, + val isP: Boolean, + val isDefaultHandled: Boolean + ) val comments = mutableListOf() pool.connection.use { it.prepareStatement( """ - SELECT Avatar, Note_ID, Hit_Points_Mode, Is_P + SELECT Auto_Mode, Judgment_Mode, Hit_Points_Mode, Long_Note_Mode, Input_Favor_Mode, Note_Modify_Mode, Lowest_Audio_Multiplier, Avatar, Note_ID, Hit_Points_Mode, Is_P FROM tw_comment - WHERE Lowest_Audio_Multiplier >= 1.0 AND Auto_Mode = ${Component.DEFAULT_AUTO_MODE} AND ${ - getAbilityFilter( - Component.DEFAULT_INPUT_FAVOR_MODE - ) - } + WHERE Avatar IS NOT NULL """.trimIndent() ).use { dbStatement -> dbStatement.executeQuery().use { rows -> @@ -767,16 +773,42 @@ rows.getString("Avatar"), rows.getString("Note_ID"), rows.getInt("Hit_Points_Mode"), - rows.getBoolean("Is_P") + rows.getBoolean("Is_P"), + Utility.isDefaultHandled( + rows.getInt("Auto_Mode"), + rows.getInt("Judgment_Mode"), + rows.getInt("Hit_Points_Mode"), + rows.getInt("Long_Note_Mode"), + rows.getInt("Input_Favor_Mode"), + rows.getInt("Note_Modify_Mode"), + rows.getDouble("Lowest_Audio_Multiplier") + ) ) ) } } } } - StreamSupport.stream(comments.groupBy { Pair(it.avatar, it.noteID) }.toList().spliterator(), true) - .use { parallel -> - parallel.forEach { (avatarNoteID, comments) -> + StreamSupport.stream( + comments.groupBy { comment -> Pair(comment.avatar, comment.noteID) }.toList().spliterator(), true + ).use { parallel -> + parallel.forEach { (avatarNoteID, comments) -> + val defaultHandledComments = comments.filter { it.isDefaultHandled } + if (defaultHandledComments.isEmpty()) { + pool.connection.use { + it.prepareStatement( + """ + REPLACE INTO tw_handled + VALUES(?, ?, ?) + """.trimIndent() + ).use { dbStatement -> + dbStatement.setString(1, avatarNoteID.first) + dbStatement.setString(2, avatarNoteID.second) + dbStatement.setInt(3, Component.Handled.ASSIST_CLEAR.value) + dbStatement.execute() + } + } + } else { pool.connection.use { it.prepareStatement( """ @@ -787,8 +819,8 @@ dbStatement.setString(1, avatarNoteID.first) dbStatement.setString(2, avatarNoteID.second) dbStatement.setInt( - 3, (if (comments.any { comment -> comment.isP }) Component.Handled.BAND1 else { - when (comments.maxBy { comment -> + 3, (if (defaultHandledComments.any { comment -> comment.isP }) Component.Handled.BAND1 else { + when (defaultHandledComments.maxBy { comment -> when (comment.hitPointsMode) { Component.HIGHEST_HIT_POINTS_MODE, Component.FAILED_HIT_POINTS_MODE -> 2 Component.HIGHER_HIT_POINTS_MODE -> 1 @@ -799,16 +831,17 @@ Component.HIGHEST_HIT_POINTS_MODE, Component.FAILED_HIT_POINTS_MODE -> Component.Handled.HIGHEST_CLEAR Component.HIGHER_HIT_POINTS_MODE -> Component.Handled.HIGHER_CLEAR Component.DEFAULT_HIT_POINTS_MODE -> Component.Handled.CLEAR - else -> Component.Handled.NOT + else -> throw NotImplementedError() } }).value ) dbStatement.execute() } } - futureLearnHandledStatus.incrementAndGet() } + futureLearnHandledStatus.incrementAndGet() } + } } fun getWipeBundles(): CompletableFuture> { @@ -1861,108 +1894,151 @@ var commentID: String? = null pool.connection.use { it.autoCommit = false - it.prepareStatement( - """ + try { + it.prepareStatement( + """ SELECT Stand, Comment_ID FROM tw_comment WHERE Note_ID = ? AND Avatar = ? AND Is_Max = true """.trimIndent() - ).use { dbStatement -> - dbStatement.setString(1, noteID) - dbStatement.setString(2, avatarID) - dbStatement.executeQuery().use { rows -> - if (rows.next()) { - if (rows.getInt("Stand") <= stand) { - commentID = rows.getString("Comment_ID") + ).use { dbStatement -> + dbStatement.setString(1, noteID) + dbStatement.setString(2, avatarID) + dbStatement.executeQuery().use { rows -> + if (rows.next()) { + if (rows.getInt("Stand") <= stand) { + commentID = rows.getString("Comment_ID") + } + } else { + commentID = "" } - } else { - commentID = "" } } - } - if (!commentID.isNullOrEmpty()) { - it.prepareStatement( - """ + if (!commentID.isNullOrEmpty()) { + it.prepareStatement( + """ UPDATE tw_comment SET Is_Max = false WHERE Comment_ID = ? """.trimIndent() - ).use { dbStatement -> - dbStatement.setString(1, commentID) - dbStatement.execute() + ).use { dbStatement -> + dbStatement.setString(1, commentID) + dbStatement.execute() + } } - } - it.prepareStatement( - """ + it.prepareStatement( + """ INSERT INTO tw_comment VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """.trimIndent() - ).use { dbStatement -> - dbStatement.setTimestamp(1, Timestamp(System.currentTimeMillis())) - dbStatement.setString(2, noteID) - dbStatement.setString(3, avatarID) - dbStatement.setDouble(4, multiplier) - dbStatement.setInt(5, autoMode) - dbStatement.setInt(6, noteSaltMode) - dbStatement.setDouble(7, audioMultiplier) - dbStatement.setInt(8, faintNoteMode) - dbStatement.setInt(9, judgmentMode) - dbStatement.setInt(10, hitPointsMode) - dbStatement.setInt(11, noteMobilityMode) - dbStatement.setInt(12, longNoteMode) - dbStatement.setInt(13, inputFavorMode) - dbStatement.setInt(14, noteModifyMode) - dbStatement.setInt(15, lowestJudgmentConditionMode) - dbStatement.setInt(16, stand) - dbStatement.setInt(17, band) - dbStatement.setBoolean(18, isP) - dbStatement.setDouble(19, point) - dbStatement.setInt(20, salt) - dbStatement.setString(21, commentIDNew) - dbStatement.setBoolean(22, commentID != null) - dbStatement.setBoolean(23, isPaused) - dbStatement.setInt(24, inputFlags) - dbStatement.setDouble(25, lowestAudioMultiplier) - dbStatement.setDouble(26, highestAudioMultiplier) - dbStatement.execute() + ).use { dbStatement -> + dbStatement.setTimestamp(1, Timestamp(System.currentTimeMillis())) + dbStatement.setString(2, noteID) + dbStatement.setString(3, avatarID) + dbStatement.setDouble(4, multiplier) + dbStatement.setInt(5, autoMode) + dbStatement.setInt(6, noteSaltMode) + dbStatement.setDouble(7, audioMultiplier) + dbStatement.setInt(8, faintNoteMode) + dbStatement.setInt(9, judgmentMode) + dbStatement.setInt(10, hitPointsMode) + dbStatement.setInt(11, noteMobilityMode) + dbStatement.setInt(12, longNoteMode) + dbStatement.setInt(13, inputFavorMode) + dbStatement.setInt(14, noteModifyMode) + dbStatement.setInt(15, lowestJudgmentConditionMode) + dbStatement.setInt(16, stand) + dbStatement.setInt(17, band) + dbStatement.setBoolean(18, isP) + dbStatement.setDouble(19, point) + dbStatement.setInt(20, salt) + dbStatement.setString(21, commentIDNew) + dbStatement.setBoolean(22, commentID != null) + dbStatement.setBoolean(23, isPaused) + dbStatement.setInt(24, inputFlags) + dbStatement.setDouble(25, lowestAudioMultiplier) + dbStatement.setDouble(26, highestAudioMultiplier) + dbStatement.execute() + } + it.commit() + } catch (e: Throwable) { + it.rollback() } - it.commit() } return commentID } - fun saveHandled(avatarID: String, noteID: String, isP: Boolean, hitPointsMode: Int) { + fun saveHandled( + avatarID: String, + noteID: String, + isP: Boolean, + autoMode: Int, + judgmentMode: Int, + hitPointsMode: Int, + longNoteMode: Int, + inputFavorMode: Int, + noteModifyMode: Int, + lowestAudioMultiplier: Double + ) { var handled = getHandled(avatarID, noteID) - if (handled != Component.Handled.BAND1) { - if (isP) { - handled = Component.Handled.BAND1 - } else { - when (hitPointsMode) { - Component.HIGHEST_HIT_POINTS_MODE -> handled = Component.Handled.HIGHEST_CLEAR - Component.HIGHER_HIT_POINTS_MODE -> { - if (handled != Component.Handled.HIGHEST_CLEAR) { - handled = Component.Handled.HIGHER_CLEAR + if (Utility.isDefaultHandled( + autoMode, + judgmentMode, + hitPointsMode, + longNoteMode, + inputFavorMode, + noteModifyMode, + lowestAudioMultiplier + ) + ) { + if (handled != Component.Handled.BAND1) { + if (isP) { + handled = Component.Handled.BAND1 + } else { + when (hitPointsMode) { + Component.HIGHEST_HIT_POINTS_MODE -> handled = Component.Handled.HIGHEST_CLEAR + Component.HIGHER_HIT_POINTS_MODE -> { + if (handled != Component.Handled.HIGHEST_CLEAR) { + handled = Component.Handled.HIGHER_CLEAR + } } - } - Component.DEFAULT_HIT_POINTS_MODE -> { - if (handled != Component.Handled.HIGHER_CLEAR && handled != Component.Handled.HIGHEST_CLEAR) { - handled = Component.Handled.CLEAR + Component.DEFAULT_HIT_POINTS_MODE -> { + if (handled != Component.Handled.HIGHER_CLEAR && handled != Component.Handled.HIGHEST_CLEAR) { + handled = Component.Handled.CLEAR + } } } } + pool.connection.use { + it.prepareStatement( + """ + REPLACE INTO tw_handled + VALUES(?, ?, ?) + """.trimIndent() + ).use { dbStatement -> + dbStatement.setString(1, avatarID) + dbStatement.setString(2, noteID) + dbStatement.setInt(3, handled.value) + dbStatement.execute() + } + } } - pool.connection.use { - it.prepareStatement( - """ - REPLACE INTO tw_handled - VALUES(?, ?, ?) - """.trimIndent() - ).use { dbStatement -> - dbStatement.setString(1, avatarID) - dbStatement.setString(2, noteID) - dbStatement.setInt(3, handled.value) - dbStatement.execute() + } else { + if (handled == Component.Handled.NOT || handled == Component.Handled.F) { + handled = Component.Handled.ASSIST_CLEAR + pool.connection.use { + it.prepareStatement( + """ + REPLACE INTO tw_handled + VALUES(?, ?, ?) + """.trimIndent() + ).use { dbStatement -> + dbStatement.setString(1, avatarID) + dbStatement.setString(2, noteID) + dbStatement.setInt(3, handled.value) + dbStatement.execute() + } } } } @@ -2876,6 +2952,8 @@ handledAvatarHandledItemMap.getOrDefault(Component.Handled.HIGHER_CLEAR, emptyList()).size val handledClearCount = handledAvatarHandledItemMap.getOrDefault(Component.Handled.CLEAR, emptyList()).size + val handledAssistClearCount = + handledAvatarHandledItemMap.getOrDefault(Component.Handled.ASSIST_CLEAR, emptyList()).size val noteIDCount = AbilitySystem.getNoteIDCount(levelName, levelID) val avatarHandledItems = handledAvatarHandledItemMap.map { Pair(it.key, it.value.sortedByDescending { it.stand }.take(50)) diff --git a/src/main/kotlin/net/taehui/twilight/system/IO.kt b/src/main/kotlin/net/taehui/twilight/system/IO.kt index f231753..e4e60ec 100644 --- a/src/main/kotlin/net/taehui/twilight/system/IO.kt +++ b/src/main/kotlin/net/taehui/twilight/system/IO.kt @@ -229,7 +229,12 @@ "future" -> { fun getFutureText(futureStatus: AtomicInteger, future: CompletableFuture?): String { return if (future != null) { - "${future.state()} (${futureStatus})" + val futureState = future.state() + if (futureState == Future.State.FAILED) { + "$futureState (${future.exceptionNow()})" + } else { + "$futureState ($futureStatus)" + } } else { Future.State.CANCELLED.toString() } diff --git a/src/main/resources/Language.json b/src/main/resources/Language.json index 8c07793..a499a0e 100644 --- a/src/main/resources/Language.json +++ b/src/main/resources/Language.json @@ -11,10 +11,6 @@ "ko-KR": "이미 친구입니다.", "en-US": "We're already friends." }, - "availableAvatarNote": { - "ko-KR": "읽지 않은 %d개의 메시지를 불로그에서 확인하세요", - "en-US": "Check your blog for %d unread messages" - }, "bannedIP": { "ko-KR": "차단된 IP 입니다.", "en-US": "Blocked IP."