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.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, 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() } } } }