package net.taehui.twilight.system import com.google.protobuf.UnsafeByteOperations import io.netty.bootstrap.Bootstrap import io.netty.channel.ChannelHandlerContext import io.netty.channel.ChannelInitializer import io.netty.channel.EventLoopGroup import io.netty.channel.epoll.EpollSocketChannel import io.netty.channel.socket.SocketChannel import io.netty.channel.socket.nio.NioSocketChannel import io.netty.handler.codec.protobuf.ProtobufDecoder import io.netty.handler.codec.protobuf.ProtobufEncoder import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender import io.netty.handler.ssl.SslContextBuilder import io.netty.handler.ssl.util.InsecureTrustManagerFactory import net.taehui.twilight.HCDataHandler import net.taehui.twilight.Logger import net.taehui.twilight.awilight.AwilightAvatar import org.apache.commons.lang3.SystemUtils import org.apache.hc.client5.http.classic.methods.HttpGet import org.apache.hc.client5.http.impl.classic.HttpClients import java.io.IOException import java.time.LocalDateTime import java.util.concurrent.ConcurrentHashMap object AwilightHandler : Logger { private val avatars = ConcurrentHashMap<ChannelHandlerContext, AwilightAvatar>() lateinit var eventLoopGroup: EventLoopGroup fun putAvatar(handler: ChannelHandlerContext, avatar: AwilightAvatar) { avatars[handler] = avatar logValueFuture { if (avatar.isBeginner) { try { HttpClients.createDefault().use { UnsafeByteOperations.unsafeWrap( it.execute( HttpGet("https://picsum.photos/200"), HCDataHandler() ) ) } } catch (e: IOException) { logFault(e) null } } else { null } }.thenAccept { val text = object { val qwilightName = avatar.qwilightName val hash = Configure.hash.random() val date = "" val language = "ko-KR" } if (it != null) { avatar.send(EventOuterClass.Event.EventID.ESTABLISH, text, it) } else { avatar.send(EventOuterClass.Event.EventID.ESTABLISH, text) } } } fun loadAwilight() { avatars.values.forEach { it.loadAwilight() } logInfo("Loaded Awilight") } fun quitAvatar(handler: ChannelHandlerContext) { avatars.remove(handler) } fun dispose() { avatars.keys.forEach{ it.close() } } fun setAwilightCount(awilightCount: Int) { WitSystem.wipeWit(this) if (awilightCount > 0) { WitSystem.handleLoop( this, LocalDateTime.now(), awilightCount ) { Bootstrap().group(eventLoopGroup) .channel(if (SystemUtils.IS_OS_LINUX) EpollSocketChannel::class.java else NioSocketChannel::class.java) .handler(object : ChannelInitializer<SocketChannel>() { public override fun initChannel(ch: SocketChannel) { ch.pipeline() .addLast( SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE) .build() .newHandler(ch.alloc(), "taehui.ddns.net", 6101) ) .addLast(ProtobufVarint32FrameDecoder()) .addLast(ProtobufDecoder(EventOuterClass.Event.getDefaultInstance())) .addLast(ProtobufVarint32LengthFieldPrepender()) .addLast(ProtobufEncoder()) .addLast(AwilightAvatar()) } }).connect("localhost", 6101) } } else { avatars.keys.stream().limit(-awilightCount.toLong()) .forEach { it.close() } } } }