package net.taehui.twilight.system import net.taehui.twilight.BaseCompiler import net.taehui.twilight.Logger import net.taehui.twilight.TwilightComponent import org.apache.commons.codec.binary.Hex 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 import java.util.stream.StreamSupport object IO : Logger { private val futureNoteLearnerStatus = AtomicInteger() private var futureNoteLearner: CompletableFuture<Void>? = null private var futureCommentLearner: CompletableFuture<Void>? = null private var futureWipeNote = "" private var futureWipeNotes: Collection<String>? = null private var futureWipeComment = "" private var futureWipeComments: Collection<Path>? = null private var futureWipeBundles: Collection<Path>? = null fun handleSystem(): String { var stopText: String? = null val r = Window.window.r while (stopText == null) { try { 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!!) } else { logInfo("Cancelled") } futureWipeNotes = null continue } if (futureWipeComment.isNotEmpty()) { if ("y".equals(w[0], ignoreCase = true)) { DB.wipeComment(futureWipeComment) } else { logInfo("Cancelled") } futureWipeComment = "" continue } if (futureWipeComments != null) { if ("y".equals(w[0], ignoreCase = true)) { DB.wipeComments(futureWipeComments!!) } else { logInfo("Cancelled") } futureWipeComments = null continue } if (futureWipeBundles != null) { if ("y".equals(w[0], ignoreCase = true)) { DB.wipeBundles(futureWipeBundles!!) } else { logInfo("Cancelled") } futureWipeBundles = null continue } when (w[0]) { "stop" -> stopText = if (w.size > 1) w[1] else "" "alarm" -> { if (w.size > 2) { SiteHandler.setSiteNotify( SiteHandler.getSiteID(w[1]), w[2] ) } else if (w.size > 1) { AvatarHandler.justNotify(w[1]) } else { logInfo("alarm <Site ID> <Text>") } } "avatar" -> { if (w.size > 1) { when (w[1]) { "view" -> { AvatarHandler.doInfo(this) continue } "quit" -> { if (w.size > 2) { AvatarHandler.handleNotSignIn(w[2]) } else { logInfo("avatar quit <Avatar ID>") } continue } "ban" -> { if (w.size > 3) { AvatarHandler.getAvatar( w[2] ).let { if (it != null) { BannedIP.putBannedIP( it.remote, LocalDateTime.parse( w[3] ) ) it.close() } else { logInfo("Failed to Find ID") } } } else { logInfo("avatar ban <Avatar ID> <Date>") } continue } "allow" -> { if (w.size > 2) { BannedIP.wipeBannedIP(w[2]) } else { logInfo("avatar allow <Avatar IP>") } continue } } } logInfo("avatar [view] view Avatars") logInfo("avatar [quit] Quit Avatar") logInfo("avatar [ban] Ban Avatar IP") logInfo("avatar [allow] Allow Avatar IP") } "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 <Count>") } } logInfo("awilight [set] Set Awilight") } "bundle" -> { if (w.size > 1) { if ("wipe" == w[1]) { DB.getWipeBundles().thenAccept { if (it.isNotEmpty()) { futureWipeBundles = it } logInfo("${it.size} Bundle Files") } continue } } logInfo("bundle [wipe] Wipe 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") } } 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 <Avatar ID>") } continue } } } logInfo("comment [wipe] <Avatar ID> Wipe Comment Files") logInfo("comment [learn] <Avatar ID> Learn Comments") } "note" -> { if (w.size > 1) { 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 } catch (e: Throwable) { logFault(e) return false } } if (w.size > 2) { learnNoteFile(Path.of(w[2])) } else { if (futureNoteLearner?.isDone != false) { futureNoteLearner = logFuture { DB.wipeNotes() try { Files.newDirectoryStream( TwilightComponent.NOTE_ENTRY_PATH ) .use { StreamSupport.stream(it.spliterator(), true) .forEach { noteFilePath -> if (learnNoteFile(noteFilePath)) { futureNoteLearnerStatus.incrementAndGet() } } } } finally { logInfo( "Learned ${futureNoteLearnerStatus.get()} Note Files" ) futureNoteLearnerStatus.set(0) } } } else { logInfo( "Learning ${futureNoteLearnerStatus.get()} Note Files" ) } } continue } "ban" -> { if (w.size > 3) { BannedNote.putBannedIP(w[2], w[3]) } else { logInfo("note ban <Note ID> <Comment>") } continue } "allow" -> { if (w.size > 2) { BannedNote.wipeBannedNote(w[2]) } else { logInfo("note allow <Note ID>") } continue } "wipe" -> { if (w.size > 2) { DB.getWipeNote(w[2]).thenAccept { if (it > 0) { futureWipeNote = w[2] } logInfo("$it Notes") } } else { DB.getWipeNotes().thenAccept { if (it.isNotEmpty()) { futureWipeNotes = it } logInfo("${it.size} Notes") } } continue } } } logInfo("note [learn] <Path> Learn Notes") logInfo("note [ban] <Note ID> Ban Note") logInfo("note [allow] <Note ID> Allow Note") logInfo("note [wipe] <Note ID> Wipe Note File") } "pause" -> { Configure.mode.pause = !Configure.mode.pause Configure.saveConfigure() if (w.size > 1) { AvatarHandler.pause(w[1]) } else { AvatarHandler.pause("") } } "platform" -> { if (w.size > 1) { when (w[1]) { "avatar" -> { if (w.size > 3) { PlatformIDSystem.putPlatformID(w[2], w[3]) } else if (w.size > 2) { PlatformIDSystem.wipePlatformID(w[2]) } else { logInfo("platform avatar <Platform ID> <Qwilight ID>") } continue } } } logInfo("platform [avatar] <Platform ID> <Qwilight ID>") } "ram" -> { Runtime.getRuntime().gc() logInfo( "Heap: ${ Runtime.getRuntime().totalMemory() / 1000 / 1000 } MB / ${Runtime.getRuntime().maxMemory() / 1000 / 1000} MB" ) } "site" -> { if (w.size > 1) { when (w[1]) { "view" -> { SiteHandler.doInfo(this) continue } "put" -> { if (w.size > 2) { SiteHandler.putSite(w[2]) } else { logInfo("site put <Name>") } continue } "wipe" -> { if (w.size > 2) { SiteHandler.wipeSite(SiteHandler.getSiteID(w[2])) } else { logInfo("site wipe <Site ID>") } continue } "silent" -> { if (w.size > 2) { SiteHandler.silentSite(SiteHandler.getSiteID(w[2])) } else { logInfo("site silent <Site ID>") } continue } } } logInfo("site [view] view Sites") logInfo("site [put] Put Site") logInfo("site [wipe] Wipe Site") logInfo("site [silent] Silent Site") } else -> { logInfo("[alarm] Send Notify") logInfo("[avatar] Handle Avatars") logInfo("[awilight] Handle Awilight") logInfo("[bundle] Handle Bundles") logInfo("[comment] Handle Comments") logInfo("[note] Handle Notes") logInfo("[pause] Pause Twilight") logInfo("[platform] Handle Platform") logInfo("[site] Handle Sites") logInfo("[stop] Stop Twilight") } } } } catch (_: UserInterruptException) { } catch (e: Throwable) { logFault(e) } } return stopText } }