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

import io.netty.channel.nio.NioEventLoopGroup
import net.taehui.twilight.qwilight.QwilightBoot
import net.taehui.twilight.site.SiteBoot
import net.taehui.twilight.system.*
import net.taehui.twilight.trust.TrustBoot
import net.taehui.twilight.www.WwwBoot
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)
        }

        NioEventLoopGroup().use { eventLoopGroup ->
            Configure.loadConfigure()
            DB.loadDB()

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

            AbilityClassSystem.loadAbilityClass()
            AbilitySystem.load(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()

            AutoLoadingSystem.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, sslContext).use {
                    SiteBoot(eventLoopGroup).use {
                        WwwBoot(eventLoopGroup).use {
                            TrustBoot(eventLoopGroup).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()
            }
        }
    }
}