diff --git a/src/main/kotlin/net/taehui/twilight/Site.kt b/src/main/kotlin/net/taehui/twilight/Site.kt index a4661a9..6cc77f1 100644 --- a/src/main/kotlin/net/taehui/twilight/Site.kt +++ b/src/main/kotlin/net/taehui/twilight/Site.kt @@ -1002,7 +1002,7 @@ fun putSiteYell(avatar: Member, event: MessageReceivedEvent) { val avatarID = "$${avatar.id}" - PlatformSystem.putDrawing(avatarID, avatar.effectiveAvatarUrl).thenAccept { + PlatformSystem.putDrawing(avatarID, avatar.effectiveAvatarUrl).thenRun { if (event.message.contentDisplay.isNotEmpty()) { val target = getTarget(avatarID) val siteYell = synchronized(siteYells) { @@ -1072,7 +1072,7 @@ } fun doModifySiteYell(avatar: Member, event: MessageUpdateEvent) { - PlatformSystem.putDrawing("$${avatar.id}", avatar.effectiveAvatarUrl).thenAccept { + PlatformSystem.putDrawing("$${avatar.id}", avatar.effectiveAvatarUrl).thenRun { synchronized(siteYells) { platformSiteYells.computeIfPresent(event.messageIdLong) { _, platformSiteYell -> platformSiteYell.forEach { diff --git a/src/main/kotlin/net/taehui/twilight/Twilight.kt b/src/main/kotlin/net/taehui/twilight/Twilight.kt index db0278b..567bb3c 100644 --- a/src/main/kotlin/net/taehui/twilight/Twilight.kt +++ b/src/main/kotlin/net/taehui/twilight/Twilight.kt @@ -1,14 +1,11 @@ package net.taehui.twilight import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.ServerSocketChannel -import io.netty.channel.socket.nio.NioServerSocketChannel import net.taehui.twilight.qwilight.QwilightBoot import net.taehui.twilight.site.SiteBoot import net.taehui.twilight.system.* -import net.taehui.twilight.taehui.TaehuiBoot +import net.taehui.twilight.trust.TrustBoot import net.taehui.twilight.www.WwwBoot -import org.apache.commons.lang3.SystemUtils import org.fusesource.jansi.AnsiConsole import java.io.IOException import java.net.BindException @@ -92,7 +89,7 @@ QwilightBoot(eventLoopGroup, sslContext).use { SiteBoot(eventLoopGroup).use { WwwBoot(eventLoopGroup).use { - TaehuiBoot(eventLoopGroup).use { + TrustBoot(eventLoopGroup).use { AvatarHandler.sendClose(IO.handleSystem()) } } diff --git a/src/main/kotlin/net/taehui/twilight/system/Configure.kt b/src/main/kotlin/net/taehui/twilight/system/Configure.kt index e52f33f..546be5a 100644 --- a/src/main/kotlin/net/taehui/twilight/system/Configure.kt +++ b/src/main/kotlin/net/taehui/twilight/system/Configure.kt @@ -87,6 +87,7 @@ class Mode { var platform = false var tv = false + @JsonIgnore var pause = false } @@ -111,8 +112,10 @@ lateinit var www: Www lateinit var nhn: NHN var awilightCount = 0 + @JsonIgnore var defaultNoteDate = 0L + @JsonIgnore var defaultUIDate = 0L @@ -131,8 +134,12 @@ } fun loadDefaultDate() { - defaultNoteDate = Files.getLastModifiedTime(TwilightComponent.DEFAULT_NOTE_ENTRY).to(TimeUnit.MILLISECONDS) - defaultUIDate = Files.getLastModifiedTime(TwilightComponent.DEFAULT_UI_ENTRY).to(TimeUnit.MILLISECONDS) + defaultNoteDate = Files.list(TwilightComponent.DEFAULT_NOTE_ENTRY).map { + Files.getLastModifiedTime(it).to(TimeUnit.MILLISECONDS) + }.max(Comparator.naturalOrder()).orElse(0L) + defaultUIDate = Files.list(TwilightComponent.DEFAULT_UI_ENTRY).map { + Files.getLastModifiedTime(it).to(TimeUnit.MILLISECONDS) + }.max(Comparator.naturalOrder()).orElse(0L) logInfo("Loaded Default Date") } diff --git a/src/main/kotlin/net/taehui/twilight/system/DB.kt b/src/main/kotlin/net/taehui/twilight/system/DB.kt index ddd3268..7b9b2e6 100644 --- a/src/main/kotlin/net/taehui/twilight/system/DB.kt +++ b/src/main/kotlin/net/taehui/twilight/system/DB.kt @@ -1148,7 +1148,7 @@ val commentsMe = mutableListOf() comments.forEach { comment -> val isMe = comment.avatarID == avatarID - if (viewUnit == -1 || commentsMe.size < viewUnit || isMe) { + if (commentsMe.size < viewUnit || isMe) { commentsMe.add(comment) } } diff --git a/src/main/kotlin/net/taehui/twilight/system/IO.kt b/src/main/kotlin/net/taehui/twilight/system/IO.kt index 3345760..e2d97cf 100644 --- a/src/main/kotlin/net/taehui/twilight/system/IO.kt +++ b/src/main/kotlin/net/taehui/twilight/system/IO.kt @@ -89,7 +89,7 @@ if (futureLearnAvatars?.isDone != false) { futureLearnAvatarsStatus.set(0) futureLearnAvatars = - DB.learnAvatars(futureLearnAvatarsStatus).thenAccept { + DB.learnAvatars(futureLearnAvatarsStatus).thenRun { logInfo( "Learned ${futureLearnAvatarsStatus.get()} Avatars" ) @@ -197,7 +197,7 @@ if (futureLearnComments?.isDone != false) { futureLearnCommentsStatus.set(0) futureLearnComments = - DB.learnComments(futureLearnCommentsStatus).thenAccept { + DB.learnComments(futureLearnCommentsStatus).thenRun { logInfo( "Learned ${futureLearnCommentsStatus.get()} Comments" ) @@ -271,7 +271,7 @@ "learn" -> { if (futureLearnHandled?.isDone != false) { futureLearnHandledStatus.set(0) - futureLearnHandled = DB.learnHandled(futureLearnHandledStatus).thenAccept { + futureLearnHandled = DB.learnHandled(futureLearnHandledStatus).thenRun { logInfo( "Learned ${futureLearnHandledStatus.get()} Handled" ) @@ -295,7 +295,7 @@ "learn" -> { if (futureLearnNotes?.isDone != false) { futureLearnNotesStatus.set(0) - futureLearnNotes = DB.learnNotes(futureLearnNotesStatus).thenAccept { + futureLearnNotes = DB.learnNotes(futureLearnNotesStatus).thenRun { logInfo( "Learned ${futureLearnNotesStatus.get()} Notes" ) diff --git a/src/main/kotlin/net/taehui/twilight/system/SiteHandler.kt b/src/main/kotlin/net/taehui/twilight/system/SiteHandler.kt index dc5bfcd..61baac3 100644 --- a/src/main/kotlin/net/taehui/twilight/system/SiteHandler.kt +++ b/src/main/kotlin/net/taehui/twilight/system/SiteHandler.kt @@ -66,7 +66,7 @@ } fun silentSite(siteID: UUID) { - DB.silentSite(siteID.toString()).thenAccept { + DB.silentSite(siteID.toString()).thenRun { sites[siteID]?.silentSite() } } diff --git a/src/main/kotlin/net/taehui/twilight/taehui/TaehuiAvatar.kt b/src/main/kotlin/net/taehui/twilight/taehui/TaehuiAvatar.kt deleted file mode 100644 index f6c53fd..0000000 --- a/src/main/kotlin/net/taehui/twilight/taehui/TaehuiAvatar.kt +++ /dev/null @@ -1,161 +0,0 @@ -package net.taehui.twilight.taehui - -import com.fasterxml.jackson.databind.ObjectMapper -import io.netty.buffer.ByteBufUtil -import io.netty.channel.ChannelFutureListener -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler -import io.netty.handler.codec.http.* -import net.taehui.twilight.Logger -import net.taehui.twilight.Utility -import net.taehui.twilight.system.AvatarHandler -import net.taehui.twilight.system.Configure -import org.slf4j.LoggerFactory -import java.net.InetSocketAddress -import java.net.URLDecoder -import java.nio.charset.StandardCharsets -import java.nio.file.Files - -class TaehuiAvatar : SimpleChannelInboundHandler(), Logger { - class QwilightDate { - var date = "" - var hashAMD64 = "" - var hashARM64 = "" - var titleAMD64 = "" - var titleARM64 = "" - - @Deprecated("hashAMD64") - var hash = "" - - @Deprecated("hashAMD64") - var hashX64 = "" - - @Deprecated("titleAMD64") - var title = "" - - @Deprecated("titleAMD64") - var titleX64 = "" - } - - private var avatarIP = "" - - private fun send204(handler: ChannelHandlerContext) { - handler.writeAndFlush(DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NO_CONTENT)) - .addListener(ChannelFutureListener.CLOSE) - } - - override fun channelActive(ctx: ChannelHandlerContext) { - avatarIP = (ctx.channel().remoteAddress() as InetSocketAddress).address.hostAddress - } - - public override fun channelRead0(ctx: ChannelHandlerContext, msg: FullHttpRequest) { - fun getQwilightDate(): QwilightDate { - val jm = ObjectMapper() - val qwilightDateFilePath = Configure.path.wwwPath.resolve(Configure.path.datePath) - return jm.readValue(Files.readString(qwilightDateFilePath), QwilightDate::class.java) - } - - val path = URLDecoder.decode(msg.uri(), StandardCharsets.UTF_8) - val mode = msg.method() - logInfo("$mode $path") - when (mode) { - HttpMethod.GET -> when (path) { - "/health" -> { - send204(ctx) - } - } - - HttpMethod.PATCH -> when (path) { - "/date/AMD64" -> { - val data = ByteBufUtil.getBytes(msg.content()) - logFuture { - Files.write( - Configure.path.wwwPath.resolve(getQwilightDate().titleAMD64), - data - ) - send204(ctx) - } - } - - "/date/ARM64" -> { - val data = ByteBufUtil.getBytes(msg.content()) - logFuture { - Files.write( - Configure.path.wwwPath.resolve(getQwilightDate().titleARM64), - data - ) - send204(ctx) - } - } - - "/date" -> { - val data = msg.content().toString(StandardCharsets.UTF_8).split(" ".toRegex()) - var date = data[0] - val hashAMD64 = data[1] - val hashARM64 = data[2] - if (date.contains("!")) { - Configure.hash.clear() - date = date.replace("!", "") - } - Configure.hash.add(hashAMD64) - Configure.hash.add(hashARM64) - val jm = ObjectMapper() - val qwilightDateFilePath = Configure.path.wwwPath.resolve(Configure.path.datePath) - val qwilightDate = - jm.readValue(Files.readString(qwilightDateFilePath), QwilightDate::class.java) - qwilightDate.date = date - qwilightDate.hashAMD64 = hashAMD64 - qwilightDate.hashARM64 = hashARM64 - qwilightDate.hash = hashAMD64 - qwilightDate.hashX64 = hashAMD64 - Files.newBufferedWriter(qwilightDateFilePath).use { - jm.writerWithDefaultPrettyPrinter().writeValue(it, qwilightDate) - } - send204(ctx) - } - - "/drawing" -> { - AvatarHandler.sendInvalidateAvatarDrawing(msg.content().toString(StandardCharsets.UTF_8)) - send204(ctx) - } - - "/totem" -> { - AvatarHandler.handleNotLogIn(msg.content().toString(StandardCharsets.UTF_8)) - send204(ctx) - } - - else -> ctx.writeAndFlush( - DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, - HttpResponseStatus.NOT_FOUND - ) - ).addListener( - ChannelFutureListener.CLOSE - ) - } - - else -> ctx.writeAndFlush( - DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, - HttpResponseStatus.METHOD_NOT_ALLOWED - ) - ).addListener( - ChannelFutureListener.CLOSE - ) - } - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - logFault(cause) - } - - override fun logInfo(toNotify: String) { - LoggerFactory.getLogger(javaClass).info("[{}] {}", avatarIP, toNotify) - } - - override fun logFault(e: Throwable) { - if (Utility.isValidFault(e)) { - LoggerFactory.getLogger(javaClass).error("[{}] {}", avatarIP, Utility.getFaultText(e)) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/net/taehui/twilight/taehui/TaehuiBoot.kt b/src/main/kotlin/net/taehui/twilight/taehui/TaehuiBoot.kt deleted file mode 100644 index 81ced6d..0000000 --- a/src/main/kotlin/net/taehui/twilight/taehui/TaehuiBoot.kt +++ /dev/null @@ -1,39 +0,0 @@ -package net.taehui.twilight.taehui - -import io.netty.bootstrap.ServerBootstrap -import io.netty.channel.Channel -import io.netty.channel.ChannelInitializer -import io.netty.channel.EventLoopGroup -import io.netty.channel.socket.ServerSocketChannel -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioServerSocketChannel -import io.netty.handler.codec.http.HttpClientCodec -import io.netty.handler.codec.http.HttpObjectAggregator -import io.netty.handler.codec.http.HttpServerCodec -import net.taehui.twilight.Logger - -class TaehuiBoot(eventLoopGroup: EventLoopGroup) : Logger, AutoCloseable { - private val mainBootstrap: ServerBootstrap = ServerBootstrap().group(eventLoopGroup).channel(NioServerSocketChannel::class.java) - .childHandler(object : ChannelInitializer() { - public override fun initChannel(ch: SocketChannel) { - ch.pipeline() - .addLast(HttpServerCodec()) - .addLast(HttpObjectAggregator(Int.MAX_VALUE)) - .addLast(HttpClientCodec()) - .addLast(TaehuiAvatar()) - } - }) - private val mainChannel: Channel - - init { - logInfo("Loading Taehui") - mainChannel = mainBootstrap.bind(8300).channel().closeFuture() - .addListener { - logInfo("Closed Taehui") - }.channel() - } - - override fun close() { - mainChannel.close() - } -} \ No newline at end of file diff --git a/src/main/kotlin/net/taehui/twilight/trust/TrustAvatar.kt b/src/main/kotlin/net/taehui/twilight/trust/TrustAvatar.kt new file mode 100644 index 0000000..f8442ae --- /dev/null +++ b/src/main/kotlin/net/taehui/twilight/trust/TrustAvatar.kt @@ -0,0 +1,153 @@ +package net.taehui.twilight.trust + +import com.fasterxml.jackson.databind.ObjectMapper +import io.netty.buffer.ByteBufUtil +import io.netty.channel.ChannelFutureListener +import io.netty.channel.ChannelHandlerContext +import io.netty.channel.SimpleChannelInboundHandler +import io.netty.handler.codec.http.* +import net.taehui.twilight.Logger +import net.taehui.twilight.Utility +import net.taehui.twilight.system.AvatarHandler +import net.taehui.twilight.system.Configure +import org.slf4j.LoggerFactory +import java.net.InetSocketAddress +import java.net.URLDecoder +import java.nio.charset.StandardCharsets +import java.nio.file.Files +import java.util.concurrent.CompletableFuture + +class TrustAvatar : SimpleChannelInboundHandler(), Logger { + class QwilightDate { + var date = "" + var hashAMD64 = "" + var hashARM64 = "" + var titleAMD64 = "" + var titleARM64 = "" + } + + private var avatarIP = "" + + private fun send204(handler: ChannelHandlerContext) { + handler.writeAndFlush(DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NO_CONTENT)) + .addListener(ChannelFutureListener.CLOSE) + } + + override fun channelActive(ctx: ChannelHandlerContext) { + avatarIP = (ctx.channel().remoteAddress() as InetSocketAddress).address.hostAddress + } + + public override fun channelRead0(ctx: ChannelHandlerContext, msg: FullHttpRequest) { + fun getQwilightDate(): QwilightDate { + val jm = ObjectMapper() + val qwilightDateFilePath = Configure.path.wwwPath.resolve(Configure.path.datePath) + return jm.readValue(Files.readString(qwilightDateFilePath), QwilightDate::class.java) + } + + val path = URLDecoder.decode(msg.uri(), StandardCharsets.UTF_8) + val mode = msg.method() + logInfo("$mode $path") + when (mode) { + HttpMethod.GET -> when (path) { + "/health" -> { + send204(ctx) + } + } + + HttpMethod.PATCH -> when (path) { + "/date/AMD64" -> { + val data = ByteBufUtil.getBytes(msg.content()) + logFuture { + Files.write( + Configure.path.wwwPath.resolve(getQwilightDate().titleAMD64), + data + ) + send204(ctx) + } + } + + "/date/ARM64" -> { + val data = ByteBufUtil.getBytes(msg.content()) + logFuture { + Files.write( + Configure.path.wwwPath.resolve(getQwilightDate().titleARM64), + data + ) + send204(ctx) + } + } + + "/date" -> { + val data = msg.content().toString(StandardCharsets.UTF_8).split(" ".toRegex()) + var date = data[0] + val hashAMD64 = data[1] + val hashARM64 = data[2] + CompletableFuture.allOf(logFuture { + if (date.contains("!")) { + Configure.hash.clear() + date = date.replace("!", "") + } + Configure.hash.add(hashAMD64) + Configure.hash.add(hashARM64) + Configure.saveConfigure() + }, logFuture { + val jm = ObjectMapper() + val qwilightDateFilePath = Configure.path.wwwPath.resolve(Configure.path.datePath) + val qwilightDate = + jm.readValue(Files.readString(qwilightDateFilePath), QwilightDate::class.java) + qwilightDate.date = date + qwilightDate.hashAMD64 = hashAMD64 + qwilightDate.hashARM64 = hashARM64 + Files.newBufferedWriter(qwilightDateFilePath).use { + jm.writerWithDefaultPrettyPrinter().writeValue(it, qwilightDate) + } + }).thenRun { + send204(ctx) + } + } + + "/drawing" -> { + AvatarHandler.sendInvalidateAvatarDrawing(msg.content().toString(StandardCharsets.UTF_8)) + send204(ctx) + } + + "/totem" -> { + AvatarHandler.handleNotLogIn(msg.content().toString(StandardCharsets.UTF_8)) + send204(ctx) + } + + else -> ctx.writeAndFlush( + DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, + HttpResponseStatus.NOT_FOUND + ) + ).addListener( + ChannelFutureListener.CLOSE + ) + } + + else -> ctx.writeAndFlush( + DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, + HttpResponseStatus.METHOD_NOT_ALLOWED + ) + ).addListener( + ChannelFutureListener.CLOSE + ) + } + } + + override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { + logFault(cause) + } + + override fun logInfo(toNotify: String) { + LoggerFactory.getLogger(javaClass).info("[{}] {}", avatarIP, toNotify) + } + + override fun logFault(e: Throwable) { + if (Utility.isValidFault(e)) { + LoggerFactory.getLogger(javaClass).error("[{}] {}", avatarIP, Utility.getFaultText(e)) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/net/taehui/twilight/trust/TrustBoot.kt b/src/main/kotlin/net/taehui/twilight/trust/TrustBoot.kt new file mode 100644 index 0000000..b6a608b --- /dev/null +++ b/src/main/kotlin/net/taehui/twilight/trust/TrustBoot.kt @@ -0,0 +1,38 @@ +package net.taehui.twilight.trust + +import io.netty.bootstrap.ServerBootstrap +import io.netty.channel.Channel +import io.netty.channel.ChannelInitializer +import io.netty.channel.EventLoopGroup +import io.netty.channel.socket.SocketChannel +import io.netty.channel.socket.nio.NioServerSocketChannel +import io.netty.handler.codec.http.HttpClientCodec +import io.netty.handler.codec.http.HttpObjectAggregator +import io.netty.handler.codec.http.HttpServerCodec +import net.taehui.twilight.Logger + +class TrustBoot(eventLoopGroup: EventLoopGroup) : Logger, AutoCloseable { + private val mainBootstrap: ServerBootstrap = ServerBootstrap().group(eventLoopGroup).channel(NioServerSocketChannel::class.java) + .childHandler(object : ChannelInitializer() { + public override fun initChannel(ch: SocketChannel) { + ch.pipeline() + .addLast(HttpServerCodec()) + .addLast(HttpObjectAggregator(Int.MAX_VALUE)) + .addLast(HttpClientCodec()) + .addLast(TrustAvatar()) + } + }) + private val mainChannel: Channel + + init { + logInfo("Loading Trust") + mainChannel = mainBootstrap.bind(8300).channel().closeFuture() + .addListener { + logInfo("Closed Trust") + }.channel() + } + + override fun close() { + mainChannel.close() + } +} \ 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 4190b6a..c5f4657 100644 --- a/src/main/kotlin/net/taehui/twilight/www/WwwAvatar.kt +++ b/src/main/kotlin/net/taehui/twilight/www/WwwAvatar.kt @@ -125,18 +125,13 @@ val avatarID = params.getOrDefault("avatarID", "") when (data.path()) { "/qwilight/www/note" -> { - val viewUnit = params.getOrDefault("viewUnit", "20").toInt() - if (viewUnit > 20) { - send400(ctx) - } else { - DB.getNote( - params.getOrDefault("want", ""), - params.getOrDefault("src", "0").toInt(), - params.getOrDefault("fit", "0").toInt(), - params.getOrDefault("page", "1").toInt(), - viewUnit - ).thenAccept { send(ctx, it) } - } + DB.getNote( + params.getOrDefault("want", ""), + params.getOrDefault("src", "0").toInt(), + params.getOrDefault("fit", "0").toInt(), + params.getOrDefault("page", "1").toInt(), + 20 + ).thenAccept { send(ctx, it) } } "/qwilight/www/comment" -> { @@ -154,14 +149,13 @@ } else { val commentID = params.getOrDefault("commentID", "") if (commentID.isEmpty()) { - val viewUnit = params.getOrDefault("viewUnit", "-1").toInt() val isUbuntu = params.getOrDefault("isUbuntu", "false").toBoolean() val ubuntuID = params.getOrDefault("ubuntuID", "") DB.getComment( noteID, Utility.getDefaultAvatarID(avatarID), language, - viewUnit, + 50, isUbuntu, ubuntuID, this diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index c4e9f79..e479aff 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -46,7 +46,7 @@ - +