diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index e805548..ae3f30a 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 8194073..4cbb3ab 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,7 +1,7 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
- kotlin("jvm") version "1.9.20"
+ kotlin("jvm") version "1.9.21"
application
id("io.ktor.plugin") version "2.3.6"
}
@@ -33,10 +33,10 @@
implementation("net.dv8tion:JDA:5.0.0-beta.16")
implementation("org.apache.commons:commons-compress:1.25.0")
implementation("org.apache.commons:commons-dbcp2:2.11.0")
- implementation("org.apache.commons:commons-lang3:3.13.0")
- implementation("org.apache.httpcomponents.client5:httpclient5:5.2.1")
- implementation("org.apache.logging.log4j:log4j-core:2.21.1")
- implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.21.1")
+ implementation("org.apache.commons:commons-lang3:3.14.0")
+ implementation("org.apache.httpcomponents.client5:httpclient5:5.2.2")
+ implementation("org.apache.logging.log4j:log4j-core:2.22.0")
+ implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.22.0")
implementation("org.jline:jline:3.24.1")
implementation("org.jline:jline-terminal-jansi:3.24.1")
implementation("org.jsoup:jsoup:1.16.2")
diff --git a/src/main/kotlin/net/taehui/twilight/BMSCompiler.kt b/src/main/kotlin/net/taehui/twilight/BMSCompiler.kt
index ff711ab..d19ea88 100644
--- a/src/main/kotlin/net/taehui/twilight/BMSCompiler.kt
+++ b/src/main/kotlin/net/taehui/twilight/BMSCompiler.kt
@@ -9,7 +9,7 @@
import kotlin.math.abs
import kotlin.math.floor
-class BMSCompiler(noteFileContents: ByteArray, format: String) : BaseCompiler(noteFileContents, format) {
+class BMSCompiler(noteFileData: ByteArray, format: String) : BaseCompiler(noteFileData, format) {
private open class BMSInputItem(val inputNote: InputNote, val bmsPosition: Double) : Comparable {
override fun compareTo(other: BMSInputItem): Int {
return inputNote.compareTo(other.inputNote)
@@ -43,7 +43,7 @@
val meterMeterMultiplierMap = LinkedHashMap()
meterMeterMultiplierMap[-1] = 1.0
val bmsIDBPMMap = mutableMapOf()
- BufferedReader(InputStreamReader(ByteArrayInputStream(noteFileContents), format)).use {
+ BufferedReader(InputStreamReader(ByteArrayInputStream(noteFileData), format)).use {
val saltComputer = Random()
var lastBin = 0
var isValidStatement = true
@@ -174,7 +174,8 @@
if (rawInput[1] == '6') {
targetComputing.autoableNotes += 1
}
- positionStandNoteCountMap[bmsPosition] = positionStandNoteCountMap.getOrDefault(bmsPosition, 0) + 1
+ positionStandNoteCountMap[bmsPosition] =
+ positionStandNoteCountMap.getOrDefault(bmsPosition, 0) + 1
highestPosition = highestPosition.coerceAtLeast(bmsPosition)
} else {
earlyBMSLongInputItemSet.getOrPut(rawInput) {
@@ -293,10 +294,12 @@
}
var bmsPosition = lastEarlyBMSLongInputItem.bmsPosition
highestPosition = highestPosition.coerceAtLeast(bmsPosition)
- positionStandNoteCountMap[bmsPosition] = positionStandNoteCountMap.getOrDefault(bmsPosition, 0) + 1
+ positionStandNoteCountMap[bmsPosition] =
+ positionStandNoteCountMap.getOrDefault(bmsPosition, 0) + 1
bmsPosition = earlyBMSLongInputItem.bmsPosition
highestPosition = highestPosition.coerceAtLeast(bmsPosition)
- positionStandNoteCountMap[bmsPosition] = positionStandNoteCountMap.getOrDefault(bmsPosition, 0) + 1
+ positionStandNoteCountMap[bmsPosition] =
+ positionStandNoteCountMap.getOrDefault(bmsPosition, 0) + 1
lastEarlyBMSLongInputItem = null
continue
}
@@ -308,7 +311,8 @@
}
val bmsPosition = lastEarlyBMSLongInputItem.bmsPosition
highestPosition = highestPosition.coerceAtLeast(bmsPosition)
- positionStandNoteCountMap[bmsPosition] = positionStandNoteCountMap.getOrDefault(bmsPosition, 0) + 1
+ positionStandNoteCountMap[bmsPosition] =
+ positionStandNoteCountMap.getOrDefault(bmsPosition, 0) + 1
}
}
lastEarlyBMSLongInputItem = earlyBMSLongInputItem
@@ -422,20 +426,7 @@
}
}
}
- targetComputing.inputMode = getInputMode(inputSet)
- if (targetComputing.inputMode == Component.InputMode.INPUT_MODE_10_2 && (targetComputing.title.contains(
- "9B",
- true
- ) || targetComputing.title.contains(
- "9K",
- true
- ) || targetComputing.title.contains(
- "PMS",
- true
- ))
- ) {
- targetComputing.inputMode = Component.InputMode.INPUT_MODE_9
- }
+ targetComputing.inputMode = getInputMode(inputSet, Utility.getDataID(targetComputing.noteID))
for (i in 0..highestMeter + 1) {
bmsPositionSet.add(i.toDouble())
}
@@ -654,7 +645,10 @@
}
}
- private fun getInputMode(inputSet: Collection): Component.InputMode {
+ private fun getInputMode(inputSet: Collection, dataID: Int): Component.InputMode {
+ if (dataID == 1) {
+ return Component.InputMode.INPUT_MODE_9
+ }
if (is4K) {
return Component.InputMode.INPUT_MODE_4
}
diff --git a/src/main/kotlin/net/taehui/twilight/BMSONCompiler.kt b/src/main/kotlin/net/taehui/twilight/BMSONCompiler.kt
index 7bec5c1..2d68576 100644
--- a/src/main/kotlin/net/taehui/twilight/BMSONCompiler.kt
+++ b/src/main/kotlin/net/taehui/twilight/BMSONCompiler.kt
@@ -11,14 +11,14 @@
import java.util.*
import kotlin.math.abs
-class BMSONCompiler(noteFileContents: ByteArray, format: String) : BaseCompiler(noteFileContents, format) {
+class BMSONCompiler(noteFileData: ByteArray, format: String) : BaseCompiler(noteFileData, format) {
private val bmsonPositionLogicalYMap = TreeMap()
private val bmsonPositionBPMMap = TreeMap()
private lateinit var text: JSON.Bmson
private var res = 0L
override fun handleCompile(targetComputing: Computing) {
- text = ObjectMapper().readValue(String(noteFileContents, Charset.forName(format)), JSON.Bmson::class.java)
+ text = ObjectMapper().readValue(String(noteFileData, Charset.forName(format)), JSON.Bmson::class.java)
val title = text.info.title
val titleAssister0 = text.info.subtitle
val titleAssister1 = text.info.chart_name
diff --git a/src/main/kotlin/net/taehui/twilight/BaseCompiler.kt b/src/main/kotlin/net/taehui/twilight/BaseCompiler.kt
index 7123268..3469e37 100644
--- a/src/main/kotlin/net/taehui/twilight/BaseCompiler.kt
+++ b/src/main/kotlin/net/taehui/twilight/BaseCompiler.kt
@@ -10,7 +10,7 @@
import kotlin.math.max
-abstract class BaseCompiler(val noteFileContents: ByteArray, val format: String) : Logger {
+abstract class BaseCompiler(val noteFileData: ByteArray, val format: String) : Logger {
val notes = mutableListOf()
val waitBPMMap = TreeMap()
val waitStopMap = TreeMap()
@@ -144,38 +144,52 @@
abstract fun handleCompile(defaultComputer: DefaultCompute)
companion object {
- fun handleCompile(noteFileContents: ByteArray): Computing {
- val targetComputing = Computing()
- ByteArrayInputStream(noteFileContents).use {
+ fun handleCompile(noteFileData: ByteArray, dataID: Int): Array {
+ val noteID512 = Utility.getID512(noteFileData)
+ val targetComputings = mutableListOf()
+ ByteArrayInputStream(noteFileData).use {
val formatComputer = CharsetDetector()
formatComputer.setText(it)
val formats = formatComputer.detectAll()
val format = if (formats[0].confidence >= 87.5) formats[0].name else Configure.db.format
var targetCompiler: BaseCompiler
try {
- targetCompiler = BMSONCompiler(noteFileContents, format)
+ val targetComputing = Computing("$noteID512:0")
+ targetCompiler = BMSONCompiler(noteFileData, format)
targetCompiler.handleCompile(targetComputing)
+ targetCompiler.onCompiled(targetComputing)
+ targetComputings.add(targetComputing)
} catch (e: JacksonException) {
- targetCompiler = BMSCompiler(noteFileContents, format)
- targetCompiler.handleCompile(targetComputing)
+ fun handleBMSCompile(dataID: Int): Computing {
+ val targetComputing = Computing("$noteID512:$dataID")
+ targetCompiler = BMSCompiler(noteFileData, format)
+ targetCompiler.handleCompile(targetComputing)
+ targetCompiler.onCompiled(targetComputing)
+ targetComputings.add(targetComputing)
+ return targetComputing
+ }
+
+ if (handleBMSCompile(if (dataID == -1) 0 else dataID).inputMode == Component.InputMode.INPUT_MODE_10_2 && dataID == -1) {
+ handleBMSCompile(1)
+ }
}
- targetCompiler.onCompiled(targetComputing)
+ Unit
}
- return targetComputing
+ return targetComputings.toTypedArray()
}
- fun handleCompile(defaultComputer: DefaultCompute, noteFileContents: ByteArray) {
- ByteArrayInputStream(noteFileContents).use {
+ fun handleCompile(defaultComputer: DefaultCompute, noteFileData: ByteArray) {
+ ByteArrayInputStream(noteFileData).use {
val formatComputer = CharsetDetector()
formatComputer.setText(it)
val formats = formatComputer.detectAll()
val format = if (formats[0].confidence > 50) formats[0].name else Configure.db.format
var targetCompiler: BaseCompiler
try {
- targetCompiler = BMSONCompiler(noteFileContents, format)
+ targetCompiler = BMSONCompiler(noteFileData, format)
targetCompiler.handleCompile(defaultComputer)
} catch (e: Throwable) {
- targetCompiler = BMSCompiler(noteFileContents, format)
+ targetCompiler = BMSCompiler(noteFileData, format)
targetCompiler.handleCompile(defaultComputer)
}
targetCompiler.onCompiled(defaultComputer as Computing)
diff --git a/src/main/kotlin/net/taehui/twilight/Computing.kt b/src/main/kotlin/net/taehui/twilight/Computing.kt
index 87bf08b..35026a4 100644
--- a/src/main/kotlin/net/taehui/twilight/Computing.kt
+++ b/src/main/kotlin/net/taehui/twilight/Computing.kt
@@ -1,7 +1,6 @@
package net.taehui.twilight
-open class Computing {
- var noteID = ""
+open class Computing(val noteID: String) {
var noteVariety = Component.NoteVariety.BMS
var title = ""
var artist = ""
diff --git a/src/main/kotlin/net/taehui/twilight/JSON.kt b/src/main/kotlin/net/taehui/twilight/JSON.kt
index ecfc58a..54d10b6 100644
--- a/src/main/kotlin/net/taehui/twilight/JSON.kt
+++ b/src/main/kotlin/net/taehui/twilight/JSON.kt
@@ -227,7 +227,7 @@
var isNetSite = false
var data: Any? = null
var noteID = ""
- var noteIDs: Array? = null
+ var noteIDs: Array = emptyArray()
var title = ""
var artist = ""
var genre = ""
diff --git a/src/main/kotlin/net/taehui/twilight/Logger.kt b/src/main/kotlin/net/taehui/twilight/Logger.kt
index 4e93f66..cde3524 100644
--- a/src/main/kotlin/net/taehui/twilight/Logger.kt
+++ b/src/main/kotlin/net/taehui/twilight/Logger.kt
@@ -11,7 +11,7 @@
}
fun logFault(e: Throwable) {
- LoggerFactory.getLogger(javaClass).error(Utility.getFault(e))
+ LoggerFactory.getLogger(javaClass).error(Utility.getFaultText(e))
}
fun logValueFuture(onHandle: () -> T): CompletableFuture {
diff --git a/src/main/kotlin/net/taehui/twilight/QwilightLogging.kt b/src/main/kotlin/net/taehui/twilight/QwilightLogging.kt
index b5ddba3..ac202d7 100644
--- a/src/main/kotlin/net/taehui/twilight/QwilightLogging.kt
+++ b/src/main/kotlin/net/taehui/twilight/QwilightLogging.kt
@@ -30,6 +30,6 @@
}
override fun logFault(e: Throwable) {
- LoggerFactory.getLogger(javaClass).error("[{}] {}", loggerID, Utility.getFault(e))
+ LoggerFactory.getLogger(javaClass).error("[{}] {}", loggerID, Utility.getFaultText(e))
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/Site.kt b/src/main/kotlin/net/taehui/twilight/Site.kt
index 70fd3ed..67ba3c6 100644
--- a/src/main/kotlin/net/taehui/twilight/Site.kt
+++ b/src/main/kotlin/net/taehui/twilight/Site.kt
@@ -15,6 +15,7 @@
import java.util.concurrent.*
import java.util.stream.Collectors
import java.util.stream.Stream
+import kotlin.random.Random
class Site : Logger {
enum class AvatarConfigure(val value: Int) {
@@ -62,7 +63,7 @@
}
private val siteYells = LinkedList()
private val platformSiteYells = mutableMapOf>()
- private val targetComputing = Computing()
+ private val targetComputing = Computing("")
private val isCallable: Boolean
private val isGetNotify: Boolean
private val isEnterQuitAware: Boolean
@@ -838,7 +839,7 @@
this.siteHand = siteHand
doCallSiteAvatar(true)
if (siteHandQueue.remove(siteHand)) {
- siteHandQueue.offerLast(siteHand)
+ siteHandQueue.offer(siteHand)
}
}
}
@@ -850,7 +851,7 @@
avatarConfigures.replace(it.avatarID, AvatarConfigure.LEVYING, AvatarConfigure.DEFAULT)
siteHand = it
doCallSiteAvatar(true)
- siteHandQueue.offerLast(it)
+ siteHandQueue.offer(it)
}
}
}
@@ -1347,10 +1348,10 @@
}
}
- fun setNoteFileContents(avatar: Avatar, noteFileContents: JSON.QwilightSetNoteFile) {
+ fun setNoteFileContents(avatar: Avatar, noteFileData: JSON.QwilightSetNoteFile) {
synchronized(avatarsCSX) {
if (siteMode == SiteMode.NET && siteHand == avatar && siteSituation == SiteSituation.DEFAULT) {
- if (Arrays.compare(noteFileContents.noteIDs, noteIDs) != 0) {
+ if (Arrays.compare(noteFileData.noteIDs, noteIDs) != 0) {
synchronized(avatarsCSX) {
avatars.forEach {
avatarConfigures[it.avatarID] = AvatarConfigure.DEFAULT
@@ -1358,34 +1359,34 @@
}
doCallSiteAvatar(false)
}
- setNoteFileContents(noteFileContents)
+ setNoteFileContents(noteFileData)
}
}
}
- fun setNoteFileContents(noteFileContents: JSON.QwilightSetNoteFile) {
- noteID = noteFileContents.noteID
- noteIDs = noteFileContents.noteIDs
- bundleEntryPath = noteFileContents.bundleEntryPath
- targetComputing.title = noteFileContents.title
- targetComputing.artist = noteFileContents.artist
- targetComputing.genre = noteFileContents.genre
- targetComputing.levelText = noteFileContents.levelText
- targetComputing.level = noteFileContents.level
- targetComputing.wantLevelID = noteFileContents.wantLevelID
- targetComputing.bpm = noteFileContents.bpm
- targetComputing.lowestBPM = noteFileContents.lowestBPM
- targetComputing.highestBPM = noteFileContents.highestBPM
- targetComputing.judgmentStage = noteFileContents.judgmentStage
- targetComputing.hitPointsValue = noteFileContents.hitPointsValue
- targetComputing.totalNotes = noteFileContents.totalNotes
- targetComputing.longNotes = noteFileContents.longNotes
- targetComputing.autoableNotes = noteFileContents.autoableNotes
- targetComputing.trapNotes = noteFileContents.trapNotes
- targetComputing.highestInputCount = noteFileContents.highestInputCount
- targetComputing.length = noteFileContents.length
- targetComputing.isAutoLongNote = noteFileContents.isAutoLongNote
- targetComputing.inputMode = noteFileContents.inputMode
+ fun setNoteFileContents(noteFileData: JSON.QwilightSetNoteFile) {
+ noteID = noteFileData.noteID
+ noteIDs = noteFileData.noteIDs
+ bundleEntryPath = noteFileData.bundleEntryPath
+ targetComputing.title = noteFileData.title
+ targetComputing.artist = noteFileData.artist
+ targetComputing.genre = noteFileData.genre
+ targetComputing.levelText = noteFileData.levelText
+ targetComputing.level = noteFileData.level
+ targetComputing.wantLevelID = noteFileData.wantLevelID
+ targetComputing.bpm = noteFileData.bpm
+ targetComputing.lowestBPM = noteFileData.lowestBPM
+ targetComputing.highestBPM = noteFileData.highestBPM
+ targetComputing.judgmentStage = noteFileData.judgmentStage
+ targetComputing.hitPointsValue = noteFileData.hitPointsValue
+ targetComputing.totalNotes = noteFileData.totalNotes
+ targetComputing.longNotes = noteFileData.longNotes
+ targetComputing.autoableNotes = noteFileData.autoableNotes
+ targetComputing.trapNotes = noteFileData.trapNotes
+ targetComputing.highestInputCount = noteFileData.highestInputCount
+ targetComputing.length = noteFileData.length
+ targetComputing.isAutoLongNote = noteFileData.isAutoLongNote
+ targetComputing.inputMode = noteFileData.inputMode
doCallSiteNet()
}
@@ -1415,7 +1416,7 @@
fun audioInput(avatar: Avatar, data: ByteString) {
synchronized(avatarsCSX) {
- if (siteMode != SiteMode.DEFAULT && (avatar == null || isAvatarJoined(avatar))) {
+ if (siteMode != SiteMode.DEFAULT && isAvatarJoined(avatar)) {
val avatarID = avatar.avatarID
val event = EventOuterClass.Event.newBuilder().apply {
eventID = EventOuterClass.Event.EventID.AUDIO_INPUT
@@ -1455,7 +1456,7 @@
handlerID = this@Site.handlerID
avatarName = avatar.avatarName
postedItem = qwilightPostItem.postedItem
- wait = Utility.getSaltedItem(qwilightPostItem.lowestWait, qwilightPostItem.highestWait)
+ wait = Random.nextDouble(qwilightPostItem.lowestWait, qwilightPostItem.highestWait)
}.build()
}.build())
}
@@ -1476,7 +1477,7 @@
}
override fun logFault(e: Throwable) {
- LoggerFactory.getLogger(javaClass).error("[{}] {}", siteName, Utility.getFault(e))
+ LoggerFactory.getLogger(javaClass).error("[{}] {}", siteName, Utility.getFaultText(e))
}
companion object {
diff --git a/src/main/kotlin/net/taehui/twilight/Twilight.kt b/src/main/kotlin/net/taehui/twilight/Twilight.kt
index 36911af..69c2ebc 100644
--- a/src/main/kotlin/net/taehui/twilight/Twilight.kt
+++ b/src/main/kotlin/net/taehui/twilight/Twilight.kt
@@ -56,7 +56,7 @@
AbilityClassSystem.loadAbilityClasses()
AbilitySystem.loadAbility()
BannedIP.loadBannedIP()
- BannedNote.loadBannedNote()
+ BannedNoteFile.loadBannedNoteFile()
EdgeSystem.loadEdge()
AvatarIPSystem.loadAvatarIP()
LevelSystem.loadLevel()
@@ -96,7 +96,7 @@
AutoSystem.dispose()
AvatarIPSystem.saveAvatarIP()
BannedIP.saveBannedIP()
- BannedNote.saveBannedNote()
+ BannedNoteFile.saveBannedNoteFile()
Configure.saveConfigure()
eventLoopGroup.shutdownGracefully()
}
diff --git a/src/main/kotlin/net/taehui/twilight/Utility.kt b/src/main/kotlin/net/taehui/twilight/Utility.kt
index ddd9995..50c1f74 100644
--- a/src/main/kotlin/net/taehui/twilight/Utility.kt
+++ b/src/main/kotlin/net/taehui/twilight/Utility.kt
@@ -3,9 +3,11 @@
import io.netty.handler.codec.DecoderException
import io.netty.handler.ssl.NotSslRecordException
import net.taehui.twilight.system.PlatformIDSystem
+import org.apache.commons.codec.binary.Hex
import java.net.MalformedURLException
import java.net.SocketException
import java.net.URI
+import java.security.MessageDigest
import java.util.*
object Utility {
@@ -39,7 +41,7 @@
return PlatformIDSystem.getAvatarID(avatarID.substring(avatarID.indexOf("@") + 1))
}
- fun getFault(e: Throwable): String {
+ fun getFaultText(e: Throwable): String {
return StringBuilder(e.localizedMessage ?: "").apply {
e.stackTrace.forEach {
append(System.lineSeparator())
@@ -48,14 +50,6 @@
}.toString()
}
- fun getSaltedItem(toSaltItems: List, defaultValue: T): T {
- return if (toSaltItems.isEmpty()) defaultValue else toSaltItems[(Math.random() * toSaltItems.size).toInt()]
- }
-
- fun getSaltedItem(lowestWait: Double, highestWait: Double): Double {
- return lowestWait + Math.random() * (highestWait - lowestWait)
- }
-
fun getQuitStatusValue(point: Double, stand: Int): Int {
if (point < 0.8) {
return 6
@@ -83,4 +77,30 @@
fun isValidFault(e: Throwable): Boolean {
return !(e is SocketException && e.localizedMessage?.contains("Connection reset") == true) && !(e is DecoderException && e.cause is NotSslRecordException)
}
+
+ fun getID512(noteFileData: ByteArray): String {
+ val hashComputer = MessageDigest.getInstance("SHA-512")
+ hashComputer.update(noteFileData)
+ return Hex.encodeHexString(hashComputer.digest())
+ }
+
+ fun getID256(noteFileData: ByteArray): String {
+ val hashComputer = MessageDigest.getInstance("SHA-256")
+ hashComputer.update(noteFileData)
+ return Hex.encodeHexString(hashComputer.digest())
+ }
+
+ fun getID128(noteFileData: ByteArray): String {
+ val hashComputer = MessageDigest.getInstance("MD5")
+ hashComputer.update(noteFileData)
+ return Hex.encodeHexString(hashComputer.digest())
+ }
+
+ fun getNoteID512(noteID: String): String {
+ return noteID.split(':')[0]
+ }
+
+ fun getDataID(noteID: String): Int {
+ return noteID.split(':')[1].toInt()
+ }
}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/awilight/AwilightAvatar.kt b/src/main/kotlin/net/taehui/twilight/awilight/AwilightAvatar.kt
index 03ccd6c..e3bc0f2 100644
--- a/src/main/kotlin/net/taehui/twilight/awilight/AwilightAvatar.kt
+++ b/src/main/kotlin/net/taehui/twilight/awilight/AwilightAvatar.kt
@@ -124,7 +124,7 @@
enteredSites[siteID]?.let {
if (it.isSiteHand) {
NoteFilesSystem.noteFile?.let { (noteID, noteFilePath) ->
- val targetComputing = BaseCompiler.handleCompile(Files.readAllBytes(noteFilePath))
+ val targetComputing = BaseCompiler.handleCompile(Files.readAllBytes(noteFilePath), -1).random()
send(
EventOuterClass.Event.EventID.SET_NOTE_FILE,
object {
@@ -169,7 +169,7 @@
}
override fun logFault(e: Throwable) {
- LoggerFactory.getLogger(javaClass).error("[{}] {}", this.qwilightName, Utility.getFault(e))
+ LoggerFactory.getLogger(javaClass).error("[{}] {}", this.qwilightName, Utility.getFaultText(e))
}
override fun channelActive(ctx: ChannelHandlerContext) {
@@ -237,18 +237,15 @@
send(
EventOuterClass.Event.EventID.ENTER_SITE,
object {
- val siteID = Utility.getSaltedItem(siteIDs, null)
+ val siteID = siteIDs.random()
val siteCipher = ""
}
)
} else {
- NoteFilesSystem.noteFile?.let { (noteID, noteFilePath) ->
- val targetComputing = BaseCompiler.handleCompile(
- Files.readAllBytes(
- noteFilePath
- )
- )
- targetComputing.noteID = noteID
+ NoteFilesSystem.noteFile?.let { noteFile ->
+ val targetComputing =
+ BaseCompiler.handleCompile(Files.readAllBytes(noteFile.value), -1)
+ .random()
val modeComponentValue = ModeComponent()
send(
EventOuterClass.Event.EventID.NEW_SITE,
@@ -351,18 +348,16 @@
enteredSites[text.siteID]?.let {
synchronized(defaultComputerCSX) {
defaultComputer?.stop()
- defaultComputer = DefaultCompute(this, text.handlerID, it).also { tmpComputer ->
- tmpComputer.noteID =
- if (NoteFilesSystem.hasNoteFile(it.noteID)) {
- it.noteID
- } else {
- Arrays.stream(text.noteIDs)
- .filter {
- NoteFilesSystem.hasNoteFile(
- it
- )
- }.findAny().orElse(null)
- }
+ defaultComputer = DefaultCompute(
+ if (NoteFilesSystem.hasNoteFile(it.noteID)) {
+ it.noteID
+ } else {
+ Arrays.stream(text.noteIDs)
+ .filter {
+ NoteFilesSystem.hasNoteFile(it)
+ }.findAny().orElse("")
+ }, this, text.handlerID, it
+ ).also { tmpComputer ->
Thread {
var isOK = false
try {
diff --git a/src/main/kotlin/net/taehui/twilight/awilight/DefaultCompute.kt b/src/main/kotlin/net/taehui/twilight/awilight/DefaultCompute.kt
index 642d123..5689948 100644
--- a/src/main/kotlin/net/taehui/twilight/awilight/DefaultCompute.kt
+++ b/src/main/kotlin/net/taehui/twilight/awilight/DefaultCompute.kt
@@ -16,7 +16,7 @@
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.math.abs
-class DefaultCompute(val avatar: AwilightAvatar, val handlerID: String, val site: AwilightSite) : Computing() {
+class DefaultCompute(noteID: String, val avatar: AwilightAvatar, val handlerID: String, val site: AwilightSite) : Computing(noteID) {
val ioAvatarIDs = mutableListOf()
val pendingIOAvatarIDs = mutableListOf()
private val sentIOAvatarIDs = mutableListOf()
@@ -30,7 +30,7 @@
val waitBPMMap = TreeMap()
val netDrawings = mutableListOf()
private val r = Random()
- private lateinit var noteFileContents: ByteArray
+ private lateinit var noteFileData: ByteArray
var setStop = false
var targetStand = 0
var isF = false
@@ -112,8 +112,8 @@
}
fun handleCompile(noteFilePath: Path) {
- noteFileContents = Files.readAllBytes(noteFilePath)
- BaseCompiler.handleCompile(this, noteFileContents)
+ noteFileData = Files.readAllBytes(noteFilePath)
+ BaseCompiler.handleCompile(this, noteFileData)
avatar.send(EventOuterClass.Event.EventID.COMPILED, object {
val siteID = site.siteID
val handlerID = this@DefaultCompute.handlerID
diff --git a/src/main/kotlin/net/taehui/twilight/qwilight/QwilightAvatar.kt b/src/main/kotlin/net/taehui/twilight/qwilight/QwilightAvatar.kt
index 7ac660f..64f0246 100644
--- a/src/main/kotlin/net/taehui/twilight/qwilight/QwilightAvatar.kt
+++ b/src/main/kotlin/net/taehui/twilight/qwilight/QwilightAvatar.kt
@@ -10,7 +10,6 @@
import net.taehui.twilight.BundleIO.BundleVariety.Companion.getBundleVariety
import net.taehui.twilight.Component
import net.taehui.twilight.system.*
-import org.apache.commons.codec.binary.Hex
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream
import org.apache.commons.io.FilenameUtils
import org.apache.commons.io.IOUtils
@@ -23,7 +22,6 @@
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
-import java.security.MessageDigest
import java.time.LocalDateTime
import java.util.*
import java.util.concurrent.ConcurrentHashMap
@@ -797,27 +795,18 @@
val inputFlags = text.inputFlags
val commentFileContents = eventData[1]
if (longNoteMode != INPUT_LONG_NOTE_MODE && judgmentMode != FAVOR_JUDGMENT_MODE && hitPointsMode != FAVOR_HIT_POINTS_MODE && hitPointsMode != TEST_HIT_POINTS_MODE && noteModifyMode != LONG_NOTE_NOTE_MODIFY_MODE) {
- val noteFileContents = eventData[0].toByteArray()
- val hashComputer512 = MessageDigest.getInstance("SHA-512")
- hashComputer512.update(noteFileContents)
- val hashComputer128 = MessageDigest.getInstance("MD5")
- hashComputer128.update(noteFileContents)
- val hashComputer256 = MessageDigest.getInstance("SHA-256")
- hashComputer256.update(noteFileContents)
- val noteID512 = Hex.encodeHexString(hashComputer512.digest())
- val noteID128 = Hex.encodeHexString(hashComputer128.digest())
- val noteID256 = Hex.encodeHexString(hashComputer256.digest())
- val targetComputing = BaseCompiler.handleCompile(noteFileContents)
- if (!targetComputing.isBanned && !BannedNote.isBanned(noteID512)) {
+ val noteFileData = eventData[0].toByteArray()
+ val targetComputing = BaseCompiler.handleCompile(noteFileData, dataID).single()
+ val noteID512 = Utility.getID512(noteFileData)
+ if (!targetComputing.isBanned && !BannedNoteFile.isBanned(targetComputing.noteID)) {
logFuture {
- Files.write(TwilightComponent.NOTE_ENTRY_PATH.resolve(noteID512), noteFileContents)
+ Files.write(TwilightComponent.NOTE_ENTRY_PATH.resolve(noteID512), noteFileData)
DB.setNote(
- "$noteID512:$dataID",
- noteID128,
- noteID256,
+ targetComputing.noteID,
+ Utility.getID128(noteFileData),
+ Utility.getID256(noteFileData),
targetComputing
)
- hashComputer512.reset()
val lastTitles = DB.getTitleItems(it)
val inputMode = text.inputMode
@@ -831,7 +820,7 @@
val comment = CommentOuterClass.Comment.parseFrom(commentFileContents)
val commentFileData = commentFileContents.toByteArray()
- val commentID = Hex.encodeHexString(hashComputer512.digest(commentFileData))
+ val commentID = Utility.getID512(commentFileData)
if (DB.saveComment(
multiplier,
autoMode,
@@ -852,7 +841,7 @@
salt,
commentID,
it,
- "$noteID512:$dataID",
+ targetComputing.noteID,
isPaused,
inputFlags
)
@@ -922,7 +911,10 @@
}
if (lastAvatarLevel < avatarLevel) {
- send(EventOuterClass.Event.EventID.LEVEL_UP, null)
+ send(EventOuterClass.Event.EventID.LEVEL_UP, object {
+ val from = lastAvatarLevel
+ val to = avatarLevel
+ })
}
}
}
@@ -931,31 +923,10 @@
EventOuterClass.Event.EventID.VALVE_COMMENT -> wantNotSignedIn {
val text = jm.readValue(eventText, JSON.QwilightValveComment::class.java)
- val noteFileContents = eventData[0].toByteArray()
- val hashComputer512 = MessageDigest.getInstance("SHA-512")
- hashComputer512.update(noteFileContents)
- val hashComputer128 = MessageDigest.getInstance("MD5")
- hashComputer128.update(noteFileContents)
- val hashComputer256 = MessageDigest.getInstance("SHA-256")
- hashComputer256.update(noteFileContents)
- val noteID512 = Hex.encodeHexString(hashComputer512.digest())
- val noteID128 = Hex.encodeHexString(hashComputer128.digest())
- val noteID256 = Hex.encodeHexString(hashComputer256.digest())
- val targetComputing = BaseCompiler.handleCompile(noteFileContents)
- if (!targetComputing.isBanned) {
+ val targetComputing = BaseCompiler.handleCompile(eventData[0].toByteArray(), text.dataID).single()
+ if (!targetComputing.isBanned && !BannedNoteFile.isBanned(targetComputing.noteID)) {
logFuture {
- Files.write(TwilightComponent.NOTE_ENTRY_PATH.resolve(noteID512), noteFileContents)
- DB.setNote(
- "$noteID512:${text.dataID}",
- noteID128,
- noteID256,
- targetComputing
- )
- if (SiteHandler.hasAvatar(
- this,
- SiteHandler.commentSiteID
- )
- ) {
+ if (SiteHandler.hasAvatar(this, SiteHandler.commentSiteID)) {
SiteHandler.putSiteYell(
SiteHandler.commentSiteID,
JSON.TwilightCommentSiteYell(
@@ -1504,7 +1475,7 @@
override fun logFault(e: Throwable) {
if (Utility.isValidFault(e)) {
- LoggerFactory.getLogger(javaClass).error("[{}] {}", loggerID, Utility.getFault(e))
+ LoggerFactory.getLogger(javaClass).error("[{}] {}", loggerID, Utility.getFaultText(e))
}
}
diff --git a/src/main/kotlin/net/taehui/twilight/site/SiteAvatar.kt b/src/main/kotlin/net/taehui/twilight/site/SiteAvatar.kt
index da2f69a..ba5ac9d 100644
--- a/src/main/kotlin/net/taehui/twilight/site/SiteAvatar.kt
+++ b/src/main/kotlin/net/taehui/twilight/site/SiteAvatar.kt
@@ -259,7 +259,7 @@
override fun logFault(e: Throwable) {
if (Utility.isValidFault(e)) {
- LoggerFactory.getLogger(javaClass).error("[{}] {}", loggerID, Utility.getFault(e))
+ LoggerFactory.getLogger(javaClass).error("[{}] {}", loggerID, Utility.getFaultText(e))
}
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/system/BannedNote.kt b/src/main/kotlin/net/taehui/twilight/system/BannedNote.kt
deleted file mode 100644
index c75d0cc..0000000
--- a/src/main/kotlin/net/taehui/twilight/system/BannedNote.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.taehui.twilight.system
-
-import com.fasterxml.jackson.core.type.TypeReference
-import com.fasterxml.jackson.databind.ObjectMapper
-import net.taehui.twilight.Logger
-import java.io.IOException
-import java.nio.file.Paths
-import java.util.concurrent.ConcurrentHashMap
-
-object BannedNote : Logger {
- private var bannedNoteStore = mutableMapOf()
-
- fun loadBannedNote() {
- try {
- bannedNoteStore.putAll(
- ObjectMapper().readValue(
- Paths.get("Banned Note.json").toFile(),
- object : TypeReference>() {})
- )
- logInfo("Loaded Banned Note")
- saveBannedNote()
- } catch (e: IOException) {
- logFault(e)
- }
- }
-
- fun saveBannedNote() {
- ObjectMapper().writerWithDefaultPrettyPrinter()
- .writeValue(Paths.get("Banned Note.json").toFile(), bannedNoteStore)
- logInfo("Saved Banned Note")
- }
-
- fun putBannedIP(noteID: String, comment: String) {
- bannedNoteStore[noteID] = comment
- }
-
- fun wipeBannedNote(noteID: String) {
- bannedNoteStore.remove(noteID)
- }
-
- fun isBanned(noteID: String): Boolean {
- return bannedNoteStore.contains(noteID)
- }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/system/BannedNoteFile.kt b/src/main/kotlin/net/taehui/twilight/system/BannedNoteFile.kt
new file mode 100644
index 0000000..d636e0b
--- /dev/null
+++ b/src/main/kotlin/net/taehui/twilight/system/BannedNoteFile.kt
@@ -0,0 +1,44 @@
+package net.taehui.twilight.system
+
+import com.fasterxml.jackson.core.type.TypeReference
+import com.fasterxml.jackson.databind.ObjectMapper
+import net.taehui.twilight.Logger
+import java.io.IOException
+import java.nio.file.Paths
+import java.util.concurrent.ConcurrentHashMap
+
+object BannedNoteFile : Logger {
+ private var bannedNoteFileStore = mutableMapOf()
+
+ fun loadBannedNoteFile() {
+ try {
+ bannedNoteFileStore.putAll(
+ ObjectMapper().readValue(
+ Paths.get("Banned Note File.json").toFile(),
+ object : TypeReference>() {})
+ )
+ logInfo("Loaded Banned Note File")
+ saveBannedNoteFile()
+ } catch (e: IOException) {
+ logFault(e)
+ }
+ }
+
+ fun saveBannedNoteFile() {
+ ObjectMapper().writerWithDefaultPrettyPrinter()
+ .writeValue(Paths.get("Banned Note File.json").toFile(), bannedNoteFileStore)
+ logInfo("Saved Banned Note File")
+ }
+
+ fun putBannedNoteFile(noteID: String, comment: String) {
+ bannedNoteFileStore[noteID] = comment
+ }
+
+ fun wipeBannedNoteFile(noteID: String) {
+ bannedNoteFileStore.remove(noteID)
+ }
+
+ fun isBanned(noteID: String): Boolean {
+ return bannedNoteFileStore.contains(noteID)
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/system/DB.kt b/src/main/kotlin/net/taehui/twilight/system/DB.kt
index 77778dd..a5fea98 100644
--- a/src/main/kotlin/net/taehui/twilight/system/DB.kt
+++ b/src/main/kotlin/net/taehui/twilight/system/DB.kt
@@ -10,9 +10,7 @@
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
-import java.sql.PreparedStatement
-import java.sql.SQLIntegrityConstraintViolationException
-import java.sql.Timestamp
+import java.sql.*
import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
@@ -20,6 +18,7 @@
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.stream.Stream
+import kotlin.collections.ArrayList
import kotlin.math.pow
object DB : Logger {
@@ -64,7 +63,7 @@
dbStatement.executeUpdate(
"""
CREATE TABLE IF NOT EXISTS tw_comment (
- Date TIMESTAMP,
+ Date DATETIME,
Note_ID VARCHAR(139),
Avatar VARCHAR(20),
Multiplier REAL,
@@ -121,7 +120,7 @@
"""
CREATE TABLE IF NOT EXISTS tw_bundle (
Avatar VARCHAR(20),
- Date TIMESTAMP,
+ Date DATETIME,
Name VARCHAR(191),
Length LONG,
Competence INTEGER,
@@ -205,7 +204,7 @@
CREATE TABLE IF NOT EXISTS tw_level (
Avatar VARCHAR(20),
Level_ID CHAR(36),
- Date TIMESTAMP,
+ Date DATETIME,
PRIMARY KEY (Avatar, Level_ID),
FOREIGN KEY (Avatar) REFERENCES tn_avatar(Avatar_ID) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB
@@ -237,7 +236,7 @@
CREATE TABLE IF NOT EXISTS tw_favor (
Note_ID VARCHAR(139),
Avatar VARCHAR(20),
- Date TIMESTAMP,
+ Date DATETIME,
Favor BOOLEAN,
PRIMARY KEY (Avatar, Note_ID),
FOREIGN KEY (Avatar) REFERENCES tn_avatar(Avatar_ID) ON UPDATE CASCADE ON DELETE CASCADE
@@ -297,13 +296,14 @@
if (favor != null) {
it.prepareStatement(
"""
- REPLACE INTO tw_favor(Note_ID, Avatar, Favor)
- VALUES(?, ?, ?)
+ REPLACE INTO tw_favor
+ VALUES(?, ?, ?, ?)
""".trimIndent()
).use { dbStatement ->
dbStatement.setString(1, noteID)
dbStatement.setString(2, avatarID)
- dbStatement.setBoolean(3, favor)
+ dbStatement.setTimestamp(3, Timestamp(System.currentTimeMillis()))
+ dbStatement.setBoolean(4, favor)
dbStatement.execute()
}
} else {
@@ -382,57 +382,67 @@
}
}
- fun getWipeNote(noteID: String): CompletableFuture {
- return logValueFuture {
- pool.connection.use {
- it.prepareStatement(
- """
- SELECT COUNT(Note_ID) AS Count
- FROM tw_note
- WHERE Note_ID LIKE ?
- """.trimIndent()
- ).use { dbStatement ->
- dbStatement.setString(1, "$noteID:%")
- dbStatement.executeQuery().use { rows ->
- if (rows.next()) {
- rows.getInt("Count")
- } else {
- 0
- }
- }
- }
- }
- }
- }
-
- fun wipeNote(noteID: String): CompletableFuture {
+ fun wipeNote(noteID: String, logger: Logger): CompletableFuture {
return logFuture {
pool.connection.use {
it.prepareStatement(
"""
DELETE
- FROM tw_comment
- WHERE Note_ID LIKE ?
+ FROM tw_note
+ WHERE Note_ID = ?
""".trimIndent()
).use { dbStatement ->
- dbStatement.setString(1, "$noteID:%")
- val wipedCount = dbStatement.executeUpdate()
- FileUtils.deleteDirectory(TwilightComponent.COMMENT_ENTRY_PATH.resolve(noteID).toFile())
- logInfo("Wiped $wipedCount Comments")
+ dbStatement.setString(1, noteID)
+ logger.logInfo("Wiped ${dbStatement.executeUpdate()} Notes")
}
- }
- pool.connection.use {
it.prepareStatement(
"""
- DELETE
+ SELECT Note_ID
FROM tw_note
WHERE Note_ID LIKE ?
""".trimIndent()
).use { dbStatement ->
- dbStatement.setString(1, "$noteID:%")
- val wipedCount = dbStatement.executeUpdate()
- FileUtils.deleteQuietly(TwilightComponent.NOTE_ENTRY_PATH.resolve(noteID).toFile())
- logInfo("Wiped $wipedCount Notes")
+ val noteID512 = Utility.getNoteID512(noteID)
+ dbStatement.setString(1, "$noteID512:%")
+ dbStatement.executeQuery().use { rows ->
+ if (!rows.next() && Files.deleteIfExists(TwilightComponent.NOTE_ENTRY_PATH.resolve(noteID512))) {
+ logger.logInfo("Wiped Note File")
+ } else {
+ logger.logInfo("Wiped 0 Note Files")
+ }
+ }
+ }
+ it.prepareStatement(
+ """
+ DELETE
+ FROM tw_comment
+ WHERE Note_ID = ?
+ """.trimIndent()
+ ).use { dbStatement ->
+ dbStatement.setString(1, noteID)
+ logger.logInfo("Wiped ${dbStatement.executeUpdate()} Comments")
+ }
+ it.prepareStatement(
+ """
+ SELECT Comment_ID
+ FROM tw_comment
+ WHERE Note_ID = ?
+ """.trimIndent()
+ ).use { dbStatement ->
+ dbStatement.setString(1, noteID)
+ dbStatement.executeQuery().use { rows ->
+ var wipedCount = 0
+ while (rows.next()) {
+ if (Files.deleteIfExists(
+ TwilightComponent.COMMENT_ENTRY_PATH.resolve(Utility.getNoteID512(noteID))
+ .resolve("${rows.getString("Comment_ID")}.xz")
+ )
+ ) {
+ ++wipedCount
+ }
+ }
+ logger.logInfo("Wiped $wipedCount Comment Files")
+ }
}
}
}
@@ -454,128 +464,87 @@
pool.connection.use {
it.prepareStatement(
"""
- SELECT tw_note.Note_ID, Artist, Title
+ SELECT tw_note.Note_ID
FROM tw_note LEFT OUTER JOIN tw_comment
ON tw_note.Note_ID = tw_comment.Note_ID
WHERE tw_comment.Note_ID IS NULL
""".trimIndent()
).use { dbStatement ->
dbStatement.executeQuery().use { rows ->
- val noteIDs = mutableSetOf()
+ val data = mutableSetOf()
while (rows.next()) {
val noteID = rows.getString("Note_ID")
if (!LevelSystem.levelNoteIDs.contains(noteID)) {
- noteIDs.add(noteID)
+ data.add(noteID)
}
}
- noteIDs
+ data
}
}
}
}
}
- fun wipeNotes(noteIDs: Collection): CompletableFuture {
+ fun pmsNote(noteID: String, logger: Logger): CompletableFuture {
return logFuture {
- logInfo(
- "Wiped ${
- noteIDs.count { noteID ->
- pool.connection.use {
- it.prepareStatement(
- """
- DELETE
- FROM tw_note
- WHERE Note_ID = ?
- """.trimIndent()
- ).use { dbStatement ->
- dbStatement.setString(1, noteID)
- dbStatement.execute()
- true
- }
- }
+ pool.connection.use {
+ it.autoCommit = false
+ val pmsNoteID = "${Utility.getNoteID512(noteID)}:1"
+ it.prepareStatement(
+ """
+ UPDATE tw_note
+ SET Note_ID = ?, Input_Mode = 12
+ WHERE Note_ID = ?
+ """.trimIndent()
+ ).use { dbStatement ->
+ dbStatement.setString(1, pmsNoteID)
+ dbStatement.setString(2, noteID)
+ if (dbStatement.executeUpdate() > 0) {
+ logger.logInfo("PMSed Note File")
}
- } Notes"
- )
- logInfo(
- "Wiped ${
- noteIDs.count {
- try {
- Files.delete(TwilightComponent.NOTE_ENTRY_PATH.resolve(it.substring(0, it.indexOf(':'))))
- true
- } catch (e: IOException) {
- logFault(e)
- false
- }
- }
- } Note Files")
+ }
+ 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()} Comment Files")
+ }
+ it.commit()
+ }
}
}
- fun getWipeComment(avatarID: String): CompletableFuture {
+ fun getPMSNotes(): CompletableFuture> {
return logValueFuture {
pool.connection.use {
it.prepareStatement(
"""
- SELECT COUNT(Comment_ID) AS Count
- FROM tw_comment
- WHERE Avatar = ?
+ SELECT Note_ID, Title
+ FROM tw_note
+ WHERE Input_Mode = 12
""".trimIndent()
).use { dbStatement ->
- dbStatement.setString(1, avatarID)
dbStatement.executeQuery().use { rows ->
- if (rows.next()) {
- rows.getInt("Count")
- } else {
- 0
- }
- }
- }
- }
- }
- }
-
- fun wipeComment(avatarID: String): CompletableFuture {
- return logFuture {
- pool.connection.use {
- it.prepareStatement(
- """
- SELECT Note_ID, Comment_ID
- FROM tw_comment
- WHERE Avatar = ?
- """.trimIndent()
- ).use { dbStatement ->
- dbStatement.setString(1, avatarID)
- dbStatement.executeQuery().use { rows ->
- var wipedCount = 0
+ val data = mutableSetOf()
while (rows.next()) {
- try {
- var noteID = rows.getString("Note_ID")
- noteID = noteID.substring(0, noteID.indexOf(':'))
- Files.delete(
- TwilightComponent.COMMENT_ENTRY_PATH.resolve(noteID)
- .resolve("${rows.getString("Comment_ID")}.xz")
+ val title = rows.getString("Title")
+ if (title.contains("9B", true) || title.contains("9K", true) || title.contains(
+ "PMS",
+ true
)
- ++wipedCount
- } catch (e: IOException) {
- logFault(e)
+ ) {
+ data.add(rows.getString("Note_ID"))
}
}
- logInfo("Wiped $wipedCount Comment Files")
+ data
}
}
}
- pool.connection.use {
- it.prepareStatement(
- """
- DELETE
- FROM tw_comment
- WHERE Avatar LIKE ?
- """.trimIndent()
- ).use { dbStatement ->
- dbStatement.setString(1, avatarID)
- logInfo("Wiped ${dbStatement.executeUpdate()} Comments")
- }
- }
}
}
@@ -612,21 +581,16 @@
}
}
- fun wipeComments(commentFilePaths: Collection): CompletableFuture {
- return logFuture {
- logInfo(
- "Wiped ${
- commentFilePaths.count {
- try {
- Files.delete(it)
- true
- } catch (e: IOException) {
- logFault(e)
- false
- }
- }
- } Comment Files"
- )
+ fun wipeComments(commentFilePaths: Collection): CompletableFuture {
+ return logValueFuture {
+ commentFilePaths.count {
+ try {
+ Files.deleteIfExists(it)
+ } catch (e: IOException) {
+ logFault(e)
+ false
+ }
+ }
}
}
@@ -664,21 +628,16 @@
}
}
- fun wipeBundles(bundleFilePaths: Collection) {
- logValueFuture {
- logInfo(
- "Wiped ${
- bundleFilePaths.count {
- try {
- Files.delete(it)
- true
- } catch (e: IOException) {
- logFault(e)
- false
- }
- }
- } Bundle Files"
- )
+ fun wipeBundles(bundleFilePaths: Collection): CompletableFuture {
+ return logValueFuture {
+ bundleFilePaths.count {
+ try {
+ Files.deleteIfExists(it)
+ } catch (e: IOException) {
+ logFault(e)
+ false
+ }
+ }
}
}
@@ -903,13 +862,34 @@
}
}
+ fun getNotes(): CompletableFuture> {
+ return logValueFuture {
+ pool.connection.use {
+ it.prepareStatement(
+ """
+ SELECT Note_ID
+ FROM tw_note
+ """.trimIndent()
+ ).use { dbStatement ->
+ dbStatement.executeQuery().use { rows ->
+ val data = mutableListOf()
+ while (rows.next()) {
+ data.add(rows.getString("Note_ID"))
+ }
+ data
+ }
+ }
+ }
+ }
+ }
+
fun setBundle(qwilightSetBundle: JSON.QwilightSetBundle, avatarID: String) {
logValueFuture {
pool.connection.use {
it.prepareStatement(
"""
UPDATE tw_bundle
- SET Competence = ?, Date = Date
+ SET Competence = ?
WHERE Name = ? AND Avatar = ?
""".trimIndent()
).use { dbStatement ->
@@ -1000,7 +980,7 @@
WHERE Avatar_ID = ?
""".trimIndent()
).use { dbStatement ->
- dbStatement.setTimestamp(1, Timestamp.from(Instant.now()))
+ dbStatement.setTimestamp(1, Timestamp(System.currentTimeMillis()))
dbStatement.setString(2, avatarID)
dbStatement.execute()
}
@@ -1152,12 +1132,13 @@
pool.connection.use {
it.prepareStatement(
"""
- REPLACE INTO tw_level(Avatar, Level_ID)
- VALUES (?, ?)
+ REPLACE INTO tw_level
+ VALUES (?, ?, ?)
""".trimIndent()
).use { dbStatement ->
dbStatement.setString(1, avatarID)
dbStatement.setString(2, levelID)
+ dbStatement.setTimestamp(3, Timestamp(System.currentTimeMillis()))
dbStatement.execute()
}
}
@@ -1290,21 +1271,22 @@
pool.connection.use {
it.prepareStatement(
"""
- INSERT INTO tw_bundle(Avatar, Name, Length, Competence, Variety, Etc)
- VALUES (?, ?, ?, ?, ?, ?)
+ INSERT INTO tw_bundle
+ VALUES (?, ?, ?, ?, ?, ?, ?)
""".trimIndent()
).use { dbStatement ->
dbStatement.setString(1, avatarID)
- dbStatement.setString(2, bundleName)
- dbStatement.setLong(3, bundleLength)
+ dbStatement.setTimestamp(2, Timestamp(System.currentTimeMillis()))
+ dbStatement.setString(3, bundleName)
+ dbStatement.setLong(4, bundleLength)
dbStatement.setInt(
- 4,
+ 5,
if (bundleVariety == BundleVariety.QWILIGHT) QwilightAvatar.BUNDLE_VOID else getDefaultBundleCompetence(
avatarID
)
)
- dbStatement.setInt(5, bundleVariety.value)
- dbStatement.setString(6, etc)
+ dbStatement.setInt(6, bundleVariety.value)
+ dbStatement.setString(7, etc)
dbStatement.execute()
}
}
@@ -1667,7 +1649,7 @@
it.prepareStatement(
"""
UPDATE tw_comment
- SET Date = Date, Is_Max = false
+ SET Is_Max = false
WHERE Note_ID = ? AND Avatar = ?
""".trimIndent()
).use { dbStatement ->
@@ -1678,33 +1660,34 @@
}
it.prepareStatement(
"""
- INSERT INTO tw_comment(Note_ID, Avatar, Multiplier, Auto_Mode, Note_Salt_Mode, Audio_Multiplier, Faint_Note_Mode, Judgment_Mode, Hit_Points_Mode, Note_Mobility_Mode, Long_Note_Mode, Input_Favor_Mode, Note_Modify_Mode, Lowest_Judgment_Condition_Mode, Stand, Band, Is_P, Point, Salt, Comment_ID, Is_Max, Is_Paused, Input_Flags)
- VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT INTO tw_comment
+ VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""".trimIndent()
).use { dbStatement ->
- dbStatement.setString(1, noteID)
- dbStatement.setString(2, avatarID)
- dbStatement.setDouble(3, multiplier)
- dbStatement.setInt(4, autoMode)
- dbStatement.setInt(5, noteSaltMode)
- dbStatement.setDouble(6, audioMultiplier)
- dbStatement.setInt(7, faintNoteMode)
- dbStatement.setInt(8, judgmentMode)
- dbStatement.setInt(9, hitPointsMode)
- dbStatement.setInt(10, noteMobilityMode)
- dbStatement.setInt(11, longNoteMode)
- dbStatement.setInt(12, inputFavorMode)
- dbStatement.setInt(13, noteModifyMode)
- dbStatement.setInt(14, lowestJudgmentConditionMode)
- dbStatement.setInt(15, stand)
- dbStatement.setInt(16, band)
- dbStatement.setBoolean(17, isP)
- dbStatement.setDouble(18, point)
- dbStatement.setInt(19, salt)
- dbStatement.setString(20, commentID)
- dbStatement.setBoolean(21, isNewStand)
- dbStatement.setBoolean(22, isPaused)
- dbStatement.setInt(23, inputFlags)
+ 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, commentID)
+ dbStatement.setBoolean(22, isNewStand)
+ dbStatement.setBoolean(23, isPaused)
+ dbStatement.setInt(24, inputFlags)
dbStatement.execute()
}
it.commit()
@@ -2398,7 +2381,7 @@
ORDER BY COUNT DESC
LIMIT 10
""".trimIndent()
- ).use {dbStatement ->
+ ).use { dbStatement ->
dbStatement.setString(1, avatarID)
dbStatement.setInt(2, inputMode.value)
dbStatement.executeQuery().use {
@@ -3444,76 +3427,4 @@
}
}
}
-
- fun setCommentMax(avatarID: String): CompletableFuture {
- return logFuture {
- val noteIDs = mutableListOf()
- pool.connection.use {
- it.prepareStatement(
- """
- SELECT DISTINCT Note_ID
- FROM tw_comment
- WHERE Avatar = ?
- """.trimIndent()
- ).use { dbStatement ->
- dbStatement.setString(1, avatarID)
- dbStatement.executeQuery().use { rows ->
- while (rows.next()) {
- noteIDs.add(rows.getString("Note_ID"))
- }
- }
- }
- }
- noteIDs.forEach { noteID ->
- pool.connection.use { it ->
- it.autoCommit = false
- var stand = 0
- var date: Timestamp? = null
- it.prepareStatement(
- """
- SELECT Stand, Date
- FROM tw_comment
- WHERE Note_ID = ? AND Date = (
- SELECT MAX(Date)
- FROM tw_comment AS tw_comment_2
- WHERE Note_ID = ? AND Avatar = ? AND Stand = (
- SELECT MAX(Stand)
- FROM tw_comment AS tw_comment_3
- WHERE Note_ID = ? AND Avatar = ?
- )
- ) AND Avatar = ?
- """.trimIndent()
- ).use { dbStatement ->
- dbStatement.setString(1, noteID)
- dbStatement.setString(2, noteID)
- dbStatement.setString(3, avatarID)
- dbStatement.setString(4, noteID)
- dbStatement.setString(5, avatarID)
- dbStatement.setString(6, avatarID)
- dbStatement.executeQuery().use {
- if (it.next()) {
- stand = it.getInt("Stand")
- date = it.getTimestamp("Date")
- }
- }
- }
- it.prepareStatement(
- """
- UPDATE tw_comment
- SET Date = Date, Is_Max = (Stand = ? AND Date = ?)
- WHERE Note_ID = ? AND Avatar = ?
- """.trimIndent()
- ).use { dbStatement ->
- dbStatement.setInt(1, stand)
- dbStatement.setTimestamp(2, date)
- dbStatement.setString(3, noteID)
- dbStatement.setString(4, avatarID)
- dbStatement.execute()
- }
- it.commit()
- }
- }
- logInfo("Learned")
- }
- }
}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/system/IO.kt b/src/main/kotlin/net/taehui/twilight/system/IO.kt
index bf030c9..eab3655 100644
--- a/src/main/kotlin/net/taehui/twilight/system/IO.kt
+++ b/src/main/kotlin/net/taehui/twilight/system/IO.kt
@@ -3,11 +3,10 @@
import net.taehui.twilight.BaseCompiler
import net.taehui.twilight.Logger
import net.taehui.twilight.TwilightComponent
-import org.apache.commons.codec.binary.Hex
+import net.taehui.twilight.Utility
import org.jline.reader.UserInterruptException
import java.nio.file.Files
import java.nio.file.Path
-import java.security.MessageDigest
import java.time.LocalDateTime
import java.util.concurrent.CompletableFuture
import java.util.concurrent.atomic.AtomicInteger
@@ -15,12 +14,10 @@
object IO : Logger {
- private val futureNoteLearnerStatus = AtomicInteger()
- private var futureNoteLearner: CompletableFuture? = null
- private var futureCommentLearner: CompletableFuture? = null
- private var futureWipeNote = ""
+ private val futureLearnNotesStatus = AtomicInteger()
+ private var futureLearnNotes: CompletableFuture? = null
private var futureWipeNotes: Collection? = null
- private var futureWipeComment = ""
+ private var futurePMSNotes: Collection? = null
private var futureWipeComments: Collection? = null
private var futureWipeBundles: Collection? = null
@@ -32,36 +29,33 @@
val line = r.readLine("> ")
if (line.isNotEmpty()) {
val w = r.parsedLine.words()
- if (futureWipeNote.isNotEmpty()) {
- if ("y".equals(w[0], ignoreCase = true)) {
- DB.wipeNote(futureWipeNote)
- } else {
- logInfo("Cancelled")
- }
- futureWipeNote = ""
- continue
- }
if (futureWipeNotes != null) {
- if ("y".equals(w[0], ignoreCase = true)) {
- DB.wipeNotes(futureWipeNotes!!)
+ if ("y".equals(w[0], true)) {
+ futureWipeNotes?.forEach {
+ DB.wipeNote(it, this)
+ }
} else {
logInfo("Cancelled")
}
futureWipeNotes = null
continue
}
- if (futureWipeComment.isNotEmpty()) {
- if ("y".equals(w[0], ignoreCase = true)) {
- DB.wipeComment(futureWipeComment)
+ if (futurePMSNotes != null) {
+ if ("y".equals(w[0], true)) {
+ futurePMSNotes?.forEach {
+ DB.pmsNote(it, this)
+ }
} else {
logInfo("Cancelled")
}
- futureWipeComment = ""
+ futurePMSNotes = null
continue
}
if (futureWipeComments != null) {
- if ("y".equals(w[0], ignoreCase = true)) {
- DB.wipeComments(futureWipeComments!!)
+ if ("y".equals(w[0], true)) {
+ DB.wipeComments(futureWipeComments!!).thenAccept {
+ logInfo("Wiped $it Comment Files")
+ }
} else {
logInfo("Cancelled")
}
@@ -69,8 +63,10 @@
continue
}
if (futureWipeBundles != null) {
- if ("y".equals(w[0], ignoreCase = true)) {
- DB.wipeBundles(futureWipeBundles!!)
+ if ("y".equals(w[0], true)) {
+ DB.wipeBundles(futureWipeBundles!!).thenAccept {
+ logInfo("Wiped $it Bundle Files")
+ }
} else {
logInfo("Cancelled")
}
@@ -83,8 +79,7 @@
"alarm" -> {
if (w.size > 2) {
SiteHandler.setSiteNotify(
- SiteHandler.getSiteID(w[1]),
- w[2]
+ SiteHandler.getSiteID(w[1]), w[2]
)
} else if (w.size > 1) {
AvatarHandler.justNotify(w[1])
@@ -142,7 +137,7 @@
}
}
}
- logInfo("avatar [view] view Avatars")
+ logInfo("avatar [view] View Avatars")
logInfo("avatar [quit] Quit Avatar")
logInfo("avatar [ban] Ban Avatar IP")
logInfo("avatar [allow] Allow Avatar IP")
@@ -150,16 +145,20 @@
"awilight" -> {
if (w.size > 2) {
- if ("set" == w[1]) {
- val awilightCount = w[2].toInt()
- Configure.awilightCount =
- 0.coerceAtLeast(Configure.awilightCount + awilightCount)
- AwilightHandler.setAwilightCount(
- awilightCount
- )
- continue
- } else {
- logInfo("awilight set ")
+ when (w[1]) {
+ "set" -> {
+ if (w.size > 3) {
+ val awilightCount = w[2].toInt()
+ Configure.awilightCount =
+ 0.coerceAtLeast(Configure.awilightCount + awilightCount)
+ AwilightHandler.setAwilightCount(
+ awilightCount
+ )
+ } else {
+ logInfo("awilight set ")
+ }
+ continue
+ }
}
}
logInfo("awilight [set] Set Awilight")
@@ -167,59 +166,36 @@
"bundle" -> {
if (w.size > 1) {
- if ("wipe" == w[1]) {
- DB.getWipeBundles().thenAccept {
- if (it.isNotEmpty()) {
- futureWipeBundles = it
+ when (w[1]) {
+ "wipe" -> {
+ DB.getWipeBundles().thenAccept {
+ if (it.isNotEmpty()) {
+ futureWipeBundles = it
+ }
+ logInfo("${it.size} Bundle Files")
}
- logInfo("${it.size} Bundle Files")
+ continue
}
- continue
}
}
- logInfo("bundle [wipe] Wipe Bundle Files")
+ logInfo("bundle [wipe] Clean Bundle Files")
}
"comment" -> {
if (w.size > 1) {
when (w[1]) {
"wipe" -> {
- if (w.size > 2) {
- DB.getWipeComment(w[2]).thenAccept {
- if (it > 0) {
- futureWipeComment = w[2]
- }
- logInfo("$it Comment Files")
+ DB.getWipeComments().thenAccept {
+ if (it.isNotEmpty()) {
+ futureWipeComments = it
}
- } else {
- DB.getWipeComments().thenAccept {
- if (it.isNotEmpty()) {
- futureWipeComments = it
- }
- logInfo("${it.size} Comment Files")
- }
- }
- continue
- }
-
- "learn" -> {
- if (w.size > 2) {
- if (futureCommentLearner?.isDone != false) {
- futureCommentLearner = DB.setCommentMax(w[2])
- } else {
- logInfo(
- "Learning Comments"
- )
- }
- } else {
- logInfo("comment learn ")
+ logInfo("${it.size} Comment Files")
}
continue
}
}
}
- logInfo("comment [wipe] Wipe Comment Files")
- logInfo("comment [learn] Learn Comments")
+ logInfo("comment [wipe] Clean Comment Files")
}
"note" -> {
@@ -227,59 +203,54 @@
when (w[1]) {
"learn" -> {
fun learnNoteFile(noteFilePath: Path): Boolean {
- try {
- val noteData = Files.readAllBytes(noteFilePath)
- val hashComputer512 = MessageDigest.getInstance("SHA-512")
- hashComputer512.update(noteData)
- val hashComputer128 = MessageDigest.getInstance("MD5")
- hashComputer128.update(noteData)
- val hashComputer256 = MessageDigest.getInstance("SHA-256")
- hashComputer256.update(noteData)
- val noteID512 = Hex.encodeHexString(hashComputer512.digest())
- val noteID128 = Hex.encodeHexString(hashComputer128.digest())
- val noteID256 = Hex.encodeHexString(hashComputer256.digest())
- val targetComputing = BaseCompiler.handleCompile(noteData)
- DB.setNote(
- "$noteID512:0",
- noteID128,
- noteID256,
- targetComputing
- )
- return true
+ return try {
+ val noteFileData = Files.readAllBytes(noteFilePath)
+ BaseCompiler.handleCompile(noteFileData, -1).forEach {
+ DB.setNote(
+ it.noteID,
+ Utility.getID128(noteFileData),
+ Utility.getID256(noteFileData),
+ it
+ )
+ }
+ true
} catch (e: Throwable) {
logFault(e)
- return false
+ false
}
}
if (w.size > 2) {
- learnNoteFile(Path.of(w[2]))
+ if (learnNoteFile(Path.of(w[2]))) {
+ logInfo("Learned Note File")
+ NoteFilesSystem.loadNoteFiles()
+ }
} else {
- if (futureNoteLearner?.isDone != false) {
- futureNoteLearner = logFuture {
+ if (futureLearnNotes?.isDone != false) {
+ futureLearnNotes = logFuture {
DB.wipeNotes()
try {
Files.newDirectoryStream(
TwilightComponent.NOTE_ENTRY_PATH
- )
- .use {
- StreamSupport.stream(it.spliterator(), true)
- .forEach { noteFilePath ->
- if (learnNoteFile(noteFilePath)) {
- futureNoteLearnerStatus.incrementAndGet()
- }
+ ).use {
+ StreamSupport.stream(it.spliterator(), true)
+ .forEach { noteFilePath ->
+ if (learnNoteFile(noteFilePath)) {
+ futureLearnNotesStatus.incrementAndGet()
}
- }
+ }
+ }
} finally {
logInfo(
- "Learned ${futureNoteLearnerStatus.get()} Note Files"
+ "Learned ${futureLearnNotesStatus.get()} Note Files"
)
- futureNoteLearnerStatus.set(0)
+ futureLearnNotesStatus.set(0)
+ NoteFilesSystem.loadNoteFiles()
}
}
} else {
logInfo(
- "Learning ${futureNoteLearnerStatus.get()} Note Files"
+ "Learning ${futureLearnNotesStatus.get()} Note Files"
)
}
}
@@ -288,7 +259,7 @@
"ban" -> {
if (w.size > 3) {
- BannedNote.putBannedIP(w[2], w[3])
+ BannedNoteFile.putBannedNoteFile(w[2], w[3])
} else {
logInfo("note ban ")
}
@@ -297,7 +268,7 @@
"allow" -> {
if (w.size > 2) {
- BannedNote.wipeBannedNote(w[2])
+ BannedNoteFile.wipeBannedNoteFile(w[2])
} else {
logInfo("note allow ")
}
@@ -306,12 +277,7 @@
"wipe" -> {
if (w.size > 2) {
- DB.getWipeNote(w[2]).thenAccept {
- if (it > 0) {
- futureWipeNote = w[2]
- }
- logInfo("$it Notes")
- }
+ DB.wipeNote(w[2], this)
} else {
DB.getWipeNotes().thenAccept {
if (it.isNotEmpty()) {
@@ -322,12 +288,27 @@
}
continue
}
+
+ "pms" -> {
+ if (w.size > 2) {
+ DB.pmsNote(w[2], this)
+ } else {
+ DB.getPMSNotes().thenAccept {
+ if (it.isNotEmpty()) {
+ futurePMSNotes = it
+ }
+ logInfo("${it.size} Notes")
+ }
+ }
+ continue
+ }
}
}
logInfo("note [learn] Learn Notes")
logInfo("note [ban] Ban Note")
logInfo("note [allow] Allow Note")
- logInfo("note [wipe] Wipe Note File")
+ logInfo("note [wipe] Clean or Wipe Note File")
+ logInfo("note [pms] PMS Note File")
}
"pause" -> {
@@ -352,9 +333,27 @@
}
continue
}
+
+ "view" -> {
+ logInfo(PlatformSystem.platformStatus)
+ continue
+ }
+
+ "dispose" -> {
+ PlatformSystem.dispose()
+ continue
+ }
+
+ "handle" -> {
+ PlatformSystem.handleSystem()
+ continue
+ }
}
}
- logInfo("platform [avatar] ")
+ logInfo("platform [avatar] Handle Avatars")
+ logInfo("platform [view] View Platform")
+ logInfo("platform [dispose] Close Platform")
+ logInfo("platform [handle] Handle Platform")
}
"ram" -> {
@@ -402,12 +401,36 @@
}
}
}
- logInfo("site [view] view Sites")
+ logInfo("site [view] View Sites")
logInfo("site [put] Put Site")
logInfo("site [wipe] Wipe Site")
logInfo("site [silent] Silent Site")
}
+ "tv" -> {
+ if (w.size > 1) {
+ when (w[1]) {
+ "view" -> {
+ logInfo(TVSystem.tvStatus)
+ continue
+ }
+
+ "dispose" -> {
+ TVSystem.dispose()
+ continue
+ }
+
+ "handle" -> {
+ TVSystem.handleSystem()
+ continue
+ }
+ }
+ }
+ logInfo("tv [view] View TV")
+ logInfo("tv [dispose] Close TV")
+ logInfo("tv [handle] Handle TV")
+ }
+
else -> {
logInfo("[alarm] Send Notify")
logInfo("[avatar] Handle Avatars")
@@ -418,6 +441,7 @@
logInfo("[pause] Pause Twilight")
logInfo("[platform] Handle Platform")
logInfo("[site] Handle Sites")
+ logInfo("[tv] Handle TV")
logInfo("[stop] Stop Twilight")
}
}
diff --git a/src/main/kotlin/net/taehui/twilight/system/NoteFilesSystem.kt b/src/main/kotlin/net/taehui/twilight/system/NoteFilesSystem.kt
index 99a0986..6fc1f1a 100644
--- a/src/main/kotlin/net/taehui/twilight/system/NoteFilesSystem.kt
+++ b/src/main/kotlin/net/taehui/twilight/system/NoteFilesSystem.kt
@@ -4,29 +4,27 @@
import net.taehui.twilight.TwilightComponent
import net.taehui.twilight.Utility
import java.io.IOException
-import java.nio.file.Files
import java.nio.file.Path
import java.util.concurrent.ConcurrentHashMap
object NoteFilesSystem : Logger {
- private val noteFiles = ConcurrentHashMap()
+ private var noteFiles = ConcurrentHashMap()
fun loadNoteFiles() {
- try {
- noteFiles.clear()
- Files.list(TwilightComponent.NOTE_ENTRY_PATH).use { noteFilePaths ->
- noteFilePaths.forEach { noteFilePath ->
- noteFiles["${noteFilePath.fileName}:0"] = noteFilePath
- }
+ DB.getNotes().thenAccept { notes ->
+ try {
+ noteFiles = ConcurrentHashMap(notes.associateWith {
+ TwilightComponent.NOTE_ENTRY_PATH.resolve(Utility.getNoteID512(it))
+ })
+ logInfo("Loaded Note Files")
+ } catch (e: IOException) {
+ logFault(e)
}
- logInfo("Loaded Note Files")
- } catch (e: IOException) {
- logFault(e)
}
}
val noteFile: Map.Entry?
- get() = Utility.getSaltedItem(ArrayList?>(noteFiles.entries), null)
+ get() = noteFiles.entries.randomOrNull()
fun getNoteFile(noteID: String): Path? {
return noteFiles[noteID]
diff --git a/src/main/kotlin/net/taehui/twilight/system/PlatformSystem.kt b/src/main/kotlin/net/taehui/twilight/system/PlatformSystem.kt
index c56f390..82148f0 100644
--- a/src/main/kotlin/net/taehui/twilight/system/PlatformSystem.kt
+++ b/src/main/kotlin/net/taehui/twilight/system/PlatformSystem.kt
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.databind.ObjectMapper
import net.dv8tion.jda.api.JDA
+import net.dv8tion.jda.api.JDA.Status
import net.dv8tion.jda.api.JDABuilder
import net.dv8tion.jda.api.entities.Guild
import net.dv8tion.jda.api.entities.Member
@@ -126,6 +127,9 @@
}
}
+ val platformStatus: String
+ get() = (platform?.status ?: Status.SHUTDOWN).toString()
+
fun dispose() {
platform?.shutdown()
}
diff --git a/src/main/kotlin/net/taehui/twilight/system/QwilightNamesSystem.kt b/src/main/kotlin/net/taehui/twilight/system/QwilightNamesSystem.kt
index f232e40..2997f4d 100644
--- a/src/main/kotlin/net/taehui/twilight/system/QwilightNamesSystem.kt
+++ b/src/main/kotlin/net/taehui/twilight/system/QwilightNamesSystem.kt
@@ -2,30 +2,25 @@
import net.taehui.twilight.Logger
import net.taehui.twilight.Utility
+import java.util.LinkedList
+import java.util.concurrent.ConcurrentLinkedQueue
object QwilightNamesSystem : Logger {
- private val qwilightNameCountMap = mutableMapOf()
- private val qwilightNames = mutableListOf()
+ private val qwilightNames = LinkedList()
fun loadQwilightNames() {
qwilightNames.addAll(DB.getQwilightNames())
- qwilightNames.forEach { qwilightNameCountMap[it] = 0 }
logInfo("Loaded Qwilight Names")
}
val qwilightName: String
get() {
- synchronized(qwilightNameCountMap) {
- val minValue = qwilightNameCountMap.values.minOrNull() ?: 0
- val qwilightName = Utility.getSaltedItem(
- qwilightNameCountMap.entries
- .filter { it.value == minValue }
- .map { it.key }, ""
- )
+ return synchronized(qwilightNames) {
+ val qwilightName = qwilightNames.poll() ?: ""
if (qwilightName.isNotEmpty()) {
- qwilightNameCountMap[qwilightName] = (qwilightNameCountMap[qwilightName] ?: 0) + 1
+ qwilightNames.offer(qwilightName)
}
- return qwilightName
+ qwilightName
}
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/system/SiteHandler.kt b/src/main/kotlin/net/taehui/twilight/system/SiteHandler.kt
index 197727d..38bd34f 100644
--- a/src/main/kotlin/net/taehui/twilight/system/SiteHandler.kt
+++ b/src/main/kotlin/net/taehui/twilight/system/SiteHandler.kt
@@ -191,9 +191,9 @@
)
}
- fun setNoteFileContents(avatar: Avatar, siteID: UUID, noteFileContents: JSON.QwilightSetNoteFile) {
+ fun setNoteFileContents(avatar: Avatar, siteID: UUID, noteFileData: JSON.QwilightSetNoteFile) {
sites[siteID]?.setNoteFileContents(
- avatar, noteFileContents
+ avatar, noteFileData
)
}
@@ -258,7 +258,7 @@
site.setModeComponent(qwilightNewSite.data!!)
site.setNoteFileContents(JSON.QwilightSetNoteFile().apply {
noteID = qwilightNewSite.noteID
- noteIDs = qwilightNewSite.noteIDs!!
+ noteIDs = qwilightNewSite.noteIDs
title = qwilightNewSite.title
artist = qwilightNewSite.artist
genre = qwilightNewSite.genre
diff --git a/src/main/kotlin/net/taehui/twilight/system/TVSystem.kt b/src/main/kotlin/net/taehui/twilight/system/TVSystem.kt
index 74d8a2d..e89f2a4 100644
--- a/src/main/kotlin/net/taehui/twilight/system/TVSystem.kt
+++ b/src/main/kotlin/net/taehui/twilight/system/TVSystem.kt
@@ -11,6 +11,7 @@
import java.time.Duration
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
+import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
object TVSystem : Logger {
@@ -33,51 +34,54 @@
isDaemon = true
}
}
- private var targetSystem: WebDriver? = null
+ private var future: ScheduledFuture<*>? = null
+ private var tv: WebDriver? = null
fun handleSystem() {
if (Configure.mode.tv) {
try {
- targetSystem = EdgeDriver(EdgeOptions().apply {
+ tv = EdgeDriver(EdgeOptions().apply {
addArguments("--headless", "--no-sandbox")
})
-
val pendingElements = mutableMapOf()
var lastElements = emptySet()
- ses.scheduleWithFixedDelay({
- targetSystem?.get("https://www.twitch.tv/directory/game/Qwilight")
- val dataTest = By.cssSelector("[data-test-selector=TitleAndChannel]")
- val elements = try {
- WebDriverWait(
- targetSystem,
- Duration.ofSeconds(1)
- ).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(dataTest))
- targetSystem?.findElements(dataTest) ?: throw TimeoutException()
- } catch (e: TimeoutException) {
- emptyList()
- }.map {
- TVItem(
- it.getAttribute("href"),
- it.findElement(By.tagName("h3")).text,
- it.findElement(By.tagName("p")).text
- )
- }.toSet()
- elements.subtract(lastElements).filter {
- pendingElements.remove(it) == null
- }.forEach {
- SiteHandler.putSiteYell(it)
- }
- lastElements.subtract(elements).forEach {
- pendingElements[it] = 0
- }
- pendingElements.toMap().forEach {
- if (it.value < 5) {
- pendingElements[it.key] = it.value + 1
- } else {
- pendingElements.remove(it.key)
+
+ future = ses.scheduleWithFixedDelay({
+ tv?.let { it ->
+ it.get("https://www.twitch.tv/directory/game/Qwilight")
+ val dataTest = By.cssSelector("[data-test-selector=TitleAndChannel]")
+ val elements = try {
+ WebDriverWait(
+ it,
+ Duration.ofSeconds(1)
+ ).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(dataTest))
+ it.findElements(dataTest) ?: throw TimeoutException()
+ } catch (e: TimeoutException) {
+ emptyList()
+ }.map { element ->
+ TVItem(
+ element.getAttribute("href"),
+ element.findElement(By.tagName("h3")).text,
+ element.findElement(By.tagName("p")).text
+ )
+ }.toSet()
+ elements.subtract(lastElements).filter {
+ pendingElements.remove(it) == null
+ }.forEach {
+ SiteHandler.putSiteYell(it)
}
+ lastElements.subtract(elements).forEach {
+ pendingElements[it] = 0
+ }
+ pendingElements.toMap().forEach {
+ if (it.value < 5) {
+ pendingElements[it.key] = it.value + 1
+ } else {
+ pendingElements.remove(it.key)
+ }
+ }
+ lastElements = elements
}
- lastElements = elements
}, 0L, 1L, TimeUnit.MINUTES)
} catch (e: Throwable) {
logFault(e)
@@ -85,9 +89,11 @@
}
}
+ val tvStatus: String
+ get() = "{Title: ${tv?.title}, Page: ${tv?.pageSource}, URL: ${tv?.currentUrl}, Handles: [${tv?.windowHandles?.joinToString()}]}"
+
fun dispose() {
ses.shutdown()
- ses.awaitTermination(1, TimeUnit.SECONDS)
- targetSystem?.quit()
+ tv?.quit()
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/system/WitSystem.kt b/src/main/kotlin/net/taehui/twilight/system/WitSystem.kt
index 3479a7b..59d4663 100644
--- a/src/main/kotlin/net/taehui/twilight/system/WitSystem.kt
+++ b/src/main/kotlin/net/taehui/twilight/system/WitSystem.kt
@@ -15,7 +15,6 @@
fun dispose() {
ses.shutdown()
- ses.awaitTermination(1, TimeUnit.SECONDS)
}
fun handleLoop(src: Any, date: LocalDateTime, loopCount: Int, toHandle: (LocalDateTime) -> Unit) {
diff --git a/src/main/kotlin/net/taehui/twilight/taehui/TaehuiAvatar.kt b/src/main/kotlin/net/taehui/twilight/taehui/TaehuiAvatar.kt
index a3ecfb1..b94ba02 100644
--- a/src/main/kotlin/net/taehui/twilight/taehui/TaehuiAvatar.kt
+++ b/src/main/kotlin/net/taehui/twilight/taehui/TaehuiAvatar.kt
@@ -97,7 +97,7 @@
override fun logFault(e: Throwable) {
if (Utility.isValidFault(e)) {
- LoggerFactory.getLogger(javaClass).error("[{}] {}", avatarIP, Utility.getFault(e))
+ LoggerFactory.getLogger(javaClass).error("[{}] {}", avatarIP, Utility.getFaultText(e))
}
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/net/taehui/twilight/www/WwwAvatar.kt b/src/main/kotlin/net/taehui/twilight/www/WwwAvatar.kt
index 562255d..89335b4 100644
--- a/src/main/kotlin/net/taehui/twilight/www/WwwAvatar.kt
+++ b/src/main/kotlin/net/taehui/twilight/www/WwwAvatar.kt
@@ -10,7 +10,6 @@
import io.netty.util.CharsetUtil
import net.taehui.twilight.*
import net.taehui.twilight.system.*
-import org.apache.commons.codec.binary.Hex
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream
import org.apache.commons.io.IOUtils
import org.apache.hc.client5.http.classic.methods.HttpGet
@@ -20,7 +19,6 @@
import java.net.URLDecoder
import java.nio.charset.StandardCharsets
import java.nio.file.Files
-import java.security.MessageDigest
import java.util.concurrent.CompletableFuture
import kotlin.io.path.inputStream
@@ -146,7 +144,7 @@
"/qwilight/www/comment" -> {
val noteID = params.getOrDefault("noteID", "")
- if (BannedNote.isBanned(noteID)) {
+ if (BannedNoteFile.isBanned(noteID)) {
send(ctx, object {
val favor = null
val totalFavor = 0
@@ -165,10 +163,7 @@
} else {
XZCompressorInputStream(
TwilightComponent.COMMENT_ENTRY_PATH.resolve(
- noteID.substring(
- 0,
- noteID.indexOf(':')
- )
+ Utility.getNoteID512(noteID)
).resolve("$commentID.xz")
.inputStream()
).use {
@@ -187,49 +182,89 @@
}
}
- "/qwilight/www/avatar/favorites/5K" -> DB.getAvatarFavorites(Component.InputMode.INPUT_MODE_5_1, avatarID).thenAccept {
- send(ctx, it)
- }
- "/qwilight/www/avatar/favorites/7K" -> DB.getAvatarFavorites(Component.InputMode.INPUT_MODE_7_1, avatarID).thenAccept {
- send(ctx, it)
- }
- "/qwilight/www/avatar/favorites/9K" -> DB.getAvatarFavorites(Component.InputMode.INPUT_MODE_9, avatarID).thenAccept {
- send(ctx, it)
- }
- "/qwilight/www/avatar/favorites/10K" -> DB.getAvatarFavorites(Component.InputMode.INPUT_MODE_10_2, avatarID).thenAccept {
- send(ctx, it)
- }
- "/qwilight/www/avatar/favorites/14K" -> DB.getAvatarFavorites(Component.InputMode.INPUT_MODE_14_2, avatarID).thenAccept {
- send(ctx, it)
- }
- "/qwilight/www/avatar/favorites/24K" -> DB.getAvatarFavorites(Component.InputMode.INPUT_MODE_24_2, avatarID).thenAccept {
- send(ctx, it)
- }
- "/qwilight/www/avatar/favorites/48K" -> DB.getAvatarFavorites(Component.InputMode.INPUT_MODE_48_4, avatarID).thenAccept {
+ "/qwilight/www/avatar/favorites/5K" -> DB.getAvatarFavorites(
+ Component.InputMode.INPUT_MODE_5_1,
+ avatarID
+ ).thenAccept {
send(ctx, it)
}
- "/qwilight/www/avatar/lasts/5K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_5_1, avatarID).thenAccept {
+ "/qwilight/www/avatar/favorites/7K" -> DB.getAvatarFavorites(
+ Component.InputMode.INPUT_MODE_7_1,
+ avatarID
+ ).thenAccept {
send(ctx, it)
}
- "/qwilight/www/avatar/lasts/7K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_7_1, avatarID).thenAccept {
+
+ "/qwilight/www/avatar/favorites/9K" -> DB.getAvatarFavorites(
+ Component.InputMode.INPUT_MODE_9,
+ avatarID
+ ).thenAccept {
send(ctx, it)
}
- "/qwilight/www/avatar/lasts/9K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_9, avatarID).thenAccept {
+
+ "/qwilight/www/avatar/favorites/10K" -> DB.getAvatarFavorites(
+ Component.InputMode.INPUT_MODE_10_2,
+ avatarID
+ ).thenAccept {
send(ctx, it)
}
- "/qwilight/www/avatar/lasts/10K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_10_2, avatarID).thenAccept {
+
+ "/qwilight/www/avatar/favorites/14K" -> DB.getAvatarFavorites(
+ Component.InputMode.INPUT_MODE_14_2,
+ avatarID
+ ).thenAccept {
send(ctx, it)
}
- "/qwilight/www/avatar/lasts/14K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_14_2, avatarID).thenAccept {
+
+ "/qwilight/www/avatar/favorites/24K" -> DB.getAvatarFavorites(
+ Component.InputMode.INPUT_MODE_24_2,
+ avatarID
+ ).thenAccept {
send(ctx, it)
}
- "/qwilight/www/avatar/lasts/24K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_24_2, avatarID).thenAccept {
+
+ "/qwilight/www/avatar/favorites/48K" -> DB.getAvatarFavorites(
+ Component.InputMode.INPUT_MODE_48_4,
+ avatarID
+ ).thenAccept {
send(ctx, it)
}
- "/qwilight/www/avatar/lasts/48K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_48_4, avatarID).thenAccept {
- send(ctx, it)
- }
+
+ "/qwilight/www/avatar/lasts/5K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_5_1, avatarID)
+ .thenAccept {
+ send(ctx, it)
+ }
+
+ "/qwilight/www/avatar/lasts/7K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_7_1, avatarID)
+ .thenAccept {
+ send(ctx, it)
+ }
+
+ "/qwilight/www/avatar/lasts/9K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_9, avatarID)
+ .thenAccept {
+ send(ctx, it)
+ }
+
+ "/qwilight/www/avatar/lasts/10K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_10_2, avatarID)
+ .thenAccept {
+ send(ctx, it)
+ }
+
+ "/qwilight/www/avatar/lasts/14K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_14_2, avatarID)
+ .thenAccept {
+ send(ctx, it)
+ }
+
+ "/qwilight/www/avatar/lasts/24K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_24_2, avatarID)
+ .thenAccept {
+ send(ctx, it)
+ }
+
+ "/qwilight/www/avatar/lasts/48K" -> DB.getAvatarLasts(Component.InputMode.INPUT_MODE_48_4, avatarID)
+ .thenAccept {
+ send(ctx, it)
+ }
"/qwilight/www/avatar/wwwLevels" -> DB.getAvatarWwwLevels(avatarID).thenAccept {
send(ctx, it)
@@ -508,24 +543,21 @@
}
"/qwilight/www/note" -> {
- val noteFileContents = ByteBufUtil.getBytes(msg.content())
- val hashComputer512 = MessageDigest.getInstance("SHA-512")
- hashComputer512.update(noteFileContents)
- val hashComputer128 = MessageDigest.getInstance("MD5")
- hashComputer128.update(noteFileContents)
- val hashComputer256 = MessageDigest.getInstance("SHA-256")
- hashComputer256.update(noteFileContents)
- val noteID512 = Hex.encodeHexString(hashComputer512.digest())
- val noteID128 = Hex.encodeHexString(hashComputer128.digest())
- val noteID256 = Hex.encodeHexString(hashComputer256.digest())
- val targetComputing = BaseCompiler.handleCompile(noteFileContents)
- if (targetComputing.isBanned || BannedNote.isBanned(noteID512)) {
+ val noteFileData = ByteBufUtil.getBytes(msg.content())
+ val targetComputing = BaseCompiler.handleCompile(noteFileData, 0).single()
+ if (targetComputing.isBanned || BannedNoteFile.isBanned(targetComputing.noteID)) {
send403(ctx)
} else {
logFuture {
- Files.write(TwilightComponent.NOTE_ENTRY_PATH.resolve(noteID512), noteFileContents)
+ Files.write(
+ TwilightComponent.NOTE_ENTRY_PATH.resolve(Utility.getID512(noteFileData)),
+ noteFileData
+ )
DB.setNote(
- "$noteID512:0", noteID128, noteID256, targetComputing
+ targetComputing.noteID,
+ Utility.getID128(noteFileData),
+ Utility.getID256(noteFileData),
+ targetComputing
)
send204(ctx)
}
@@ -562,7 +594,7 @@
override fun logFault(e: Throwable) {
if (Utility.isValidFault(e)) {
- LoggerFactory.getLogger(javaClass).error("[{}] {}", avatarIP, Utility.getFault(e))
+ LoggerFactory.getLogger(javaClass).error("[{}] {}", avatarIP, Utility.getFaultText(e))
}
}
}
\ No newline at end of file