Newer
Older
Twilight / src / main / kotlin / net / taehui / twilight / Twilight.kt
@Taehui Taehui on 18 Jul 4 KB v1.0-SNAPSHOT
package net.taehui.twilight

import io.netty.channel.epoll.EpollEventLoopGroup
import io.netty.channel.epoll.EpollServerSocketChannel
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.www.WwwBoot
import org.apache.commons.lang3.SystemUtils
import org.fusesource.jansi.AnsiConsole
import java.io.IOException
import java.net.BindException
import java.net.InetSocketAddress
import java.nio.channels.DatagramChannel
import java.nio.file.Files
import java.nio.file.Paths
import java.security.KeyStore
import javax.net.ssl.KeyManagerFactory
import javax.net.ssl.SSLContext
import kotlin.io.path.absolute
import kotlin.system.exitProcess

object Twilight {
    @JvmStatic
    fun main(args: Array<String>) {
        AnsiConsole.systemInstall()

        try {
            val datagramChannel = DatagramChannel.open()
            datagramChannel?.bind(InetSocketAddress("localhost", 6101))
        } catch (e: BindException) {
            System.err.println("Twilight is already running")
            exitProcess(1)
        }

        try {
            Files.createDirectories(TwilightComponent.NOTE_ENTRY_PATH)
            Files.createDirectories(TwilightComponent.COMMENT_ENTRY_PATH)
            Files.createDirectories(TwilightComponent.BUNDLE_ENTRY_PATH)
            Files.createDirectories(TwilightComponent.DEFAULT_NOTE_ENTRY)
            Files.createDirectories(TwilightComponent.DEFAULT_UI_ENTRY)
            Files.createDirectories(TwilightComponent.TITLE_ENTRY_PATH)
            Files.createDirectories(TwilightComponent.LEVEL_ENTRY_PATH)
            Files.createDirectories(TwilightComponent.VOTE_ENTRY_PATH)
            Files.createDirectories(TwilightComponent.ABILITY_ENTRY_PATH)
            Files.createDirectories(TwilightComponent.EDGE_ENTRY_PATH)
        } catch (e: IOException) {
            System.err.println("Cannot run Twilight from ${Paths.get(".").absolute()}")
            exitProcess(1)
        }

        (if (SystemUtils.IS_OS_LINUX) EpollEventLoopGroup() else NioEventLoopGroup()).use { eventLoopGroup ->
            val eventChannel: Class<out ServerSocketChannel> =
                if (SystemUtils.IS_OS_LINUX) EpollServerSocketChannel::class.java else NioServerSocketChannel::class.java

            Configure.loadConfigure()
            DB.loadDB()

            AvatarIPSystem.loadAvatarIP()
            BannedNoteSystem.loadBannedNote()
            BannedIPSystem.loadBannedIP()
            PlatformIDSystem.loadPlatformID()
            TVSystem.loadAllowedTV()

            AbilityClassSystem.loadAbilityClass()
            AbilitySystem.loadAbility(false)
            EdgeSystem.loadEdge()
            LevelSystem.loadLevel()
            TitleSystem.loadTitle()
            VoteSystem.loadVote()

            NoteFilesSystem.loadNoteFiles()
            QwilightNamesSystem.loadQwilightNames()

            AwilightHandler.eventLoopGroup = eventLoopGroup
            AwilightHandler.setAwilightCount(Configure.awilightCount)
            PlatformSystem.handleSystem()
            TVSystem.handleSystem()
            WitSystem.handleSystem()

            AutoSystem.handleSystem()
            try {

                val sslContext = Files.newInputStream(Paths.get("Twilight.jks")).use {
                    val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
                    keyStore.load(it, Configure.javaCipherStore.pw0)
                    val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
                    keyManagerFactory.init(keyStore, Configure.javaCipherStore.pw1)
                    val sslContext = SSLContext.getInstance("TLS")
                    sslContext.init(keyManagerFactory.keyManagers, null, null)
                    sslContext
                }

                QwilightBoot(eventLoopGroup, eventChannel, sslContext).use {
                    SiteBoot(eventLoopGroup, eventChannel).use {
                        WwwBoot(eventLoopGroup, eventChannel).use {
                            TaehuiBoot(eventLoopGroup, eventChannel).use {
                                AvatarHandler.sendClose(IO.handleSystem())
                            }
                        }
                    }
                }
            } finally {
                TVSystem.dispose()
                PlatformSystem.dispose()
                AwilightHandler.dispose()
                AvatarHandler.dispose()

                TVSystem.saveAllowedTV()
                PlatformIDSystem.savePlatformID()
                BannedIPSystem.saveBannedIP()
                BannedNoteSystem.saveBannedNote()
                AvatarIPSystem.saveAvatarIP()

                Configure.saveConfigure()
            }
        }
    }
}