Newer
Older
Twilight / src / main / kotlin / net / taehui / twilight / trust / TrustAvatar.kt
@taehui taehui on 16 Aug 5 KB v1.0-SNAPSHOT
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<FullHttpRequest>(), 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))
        }
    }
}