package net.taehui.twilight.system import com.fasterxml.jackson.annotation.JsonGetter import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonSetter import com.fasterxml.jackson.databind.ObjectMapper import net.taehui.EventClass import net.taehui.twilight.Avatar import net.taehui.twilight.JSON import net.taehui.twilight.Logger import net.taehui.twilight.TwilightComponent import org.apache.hc.client5.http.HttpResponseException import org.apache.hc.client5.http.classic.methods.HttpPatch import org.apache.hc.client5.http.classic.methods.HttpPost import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler import org.apache.hc.client5.http.impl.classic.HttpClients import org.apache.hc.core5.http.ContentType import org.apache.hc.core5.http.io.entity.StringEntity import java.io.IOException import java.lang.reflect.Modifier import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit object Configure : Logger { class PathItem { @JvmField var www = "" @JvmField var tmp = "" @JvmField var date = "" @JsonIgnore lateinit var wwwPath: Path @JsonIgnore lateinit var tmpPath: Path @JsonIgnore lateinit var datePath: Path @JsonSetter fun setWww(www: String) { this.www = www wwwPath = Paths.get(www) } @JsonSetter fun setTmp(tmp: String) { this.tmp = tmp tmpPath = Paths.get(tmp) } @JsonSetter fun setDate(date: String) { this.date = date datePath = Paths.get(date) } } class DBItem { var auth = "" var db = "" var remote = "" var avatar = "" var format = "" } class FaxItem { var auth = "" var remote = "" var avatar = "" } class JavaCipherStore { @get:JsonGetter lateinit var pw0: CharArray @get:JsonGetter lateinit var pw1: CharArray @JsonSetter fun setPw0(pw0: String) { this.pw0 = pw0.toCharArray() } @JsonSetter fun setPw1(pw1: String) { this.pw1 = pw1.toCharArray() } } class Mode { @JsonIgnore lateinit var funcEstablish: (Avatar, Array<Any>, (isPause: Boolean) -> Unit) -> Unit @JsonIgnore lateinit var funcSignIn: (Array<Any>) -> CompletableFuture<Array<Any>?> @JvmField var allowEstablish = false @JvmField var allowSignIn = false var pause = false var getAbility = false var platform = false var tv = false @JsonSetter fun setAllowEstablish(allowEstablish: Boolean) { this.allowEstablish = allowEstablish funcEstablish = { avatar, data, onHandled -> avatar.qwilightHash = data[0] as String avatar.qwilightDate = data[1] as String if (pause) { avatar.send(EventClass.Event.EventID.WARNING, avatar.translateLanguage("pause")) onHandled(true) } else if (BannedIP.isBanned(avatar.remote)) { avatar.send(EventClass.Event.EventID.WARNING, avatar.translateLanguage("bannedIP")) } else if (allowEstablish || avatar.avatarIP.isLoopbackAddress || avatar.avatarIP.isSiteLocalAddress || hash.contains( avatar.qwilightHash ) ) { onHandled(false) } else { if (data[2] as Boolean) { avatar.send(EventClass.Event.EventID.WARNING, avatar.translateLanguage("unavailableValveDate")) } else { avatar.send( EventClass.Event.EventID.UNAVAILABLE_DATE, avatar.translateLanguage("unavailableDate") ) } } } } @JsonSetter fun setAllowSignIn(allowSignIn: Boolean) { this.allowSignIn = allowSignIn funcSignIn = if (allowSignIn) { { data -> logValueFuture { val pendingAvatarID = data[1] as String arrayOf("", pendingAvatarID, pendingAvatarID, 1) } } } else { { data -> logValueFuture { val avatar = data[0] as Avatar val jm = ObjectMapper() HttpClients.createDefault().use { val dataPost = HttpPost(www.taehui + "/avatar/getTotem") dataPost.setHeader("millis", System.currentTimeMillis()) dataPost.setHeader("X-Real-IP", avatar.remote) dataPost.entity = StringEntity( jm.writeValueAsString( object { val avatarID = (data[1] as String) val avatarCipher = (data[2] as String) }), ContentType.APPLICATION_JSON ) try { val taehuiGetTotem = jm.readValue( it.execute(dataPost, BasicHttpClientResponseHandler()), JSON.TaehuiGetTotem::class.java ) arrayOf( taehuiGetTotem.totem, taehuiGetTotem.avatarID, taehuiGetTotem.avatarName, taehuiGetTotem.level ) } catch (e: HttpResponseException) { avatar.send(EventClass.Event.EventID.WARNING, avatar.translateLanguage("wrongAvatar")) null } } } } } } } class Www { var qwilight = "" var taehui = "" var remote = "" } class NHN { var nhnID = "" var nhnPw = "" } lateinit var path: PathItem lateinit var db: DBItem lateinit var fax: FaxItem lateinit var javaCipherStore: JavaCipherStore var hash = mutableSetOf<String>() lateinit var mode: Mode lateinit var www: Www lateinit var nhn: NHN var awilightCount = 0 var defaultNoteDate = 0L var defaultUIDate = 0L fun loadConfigure() { try { val text = ObjectMapper().readValue(Paths.get("Configure.json").toFile(), Configure::class.java) Configure::class.java.fields.forEach { if (it.getAnnotation(JsonIgnore::class.java)?.value != true && it.modifiers and Modifier.FINAL != Modifier.FINAL) { it[this] = it[text] ?: throw RuntimeException(it.name) } } defaultNoteDate = Files.getLastModifiedTime(TwilightComponent.DEFAULT_NOTE_ENTRY).to(TimeUnit.MILLISECONDS) defaultUIDate = Files.getLastModifiedTime(TwilightComponent.DEFAULT_UI_ENTRY).to(TimeUnit.MILLISECONDS) logInfo("Loaded Configure") } catch (e: IOException) { logFault(e) } } fun saveConfigure() { Files.newOutputStream(Paths.get("Configure.json")).use { ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(it, this) logInfo("Saved Configure") } } fun signIn(avatar: Avatar, pendingAvatarID: String, pw: String): CompletableFuture<Array<Any>?> { return mode.funcSignIn(arrayOf(avatar, pendingAvatarID, pw)) } fun signIn(avatar: Avatar, totem: String): CompletableFuture<Array<Any>?> { return logValueFuture { HttpClients.createDefault().use { val data = HttpPatch(www.taehui + "/avatar/totem") data.setHeader("X-Real-IP", avatar.remote) data.setHeader("millis", System.currentTimeMillis()) data.setHeader("totem", totem) try { val taehuiTotem = ObjectMapper().readValue( it.execute(data, BasicHttpClientResponseHandler()), JSON.TaehuiTotem::class.java ) arrayOf(taehuiTotem.avatarID, taehuiTotem.avatarName, taehuiTotem.level) } catch (e: HttpResponseException) { avatar.send(EventClass.Event.EventID.FAILED_VALIDATE_TOTEM, null) null } } } } fun establish(avatar: Avatar, hash: String, date: String, isValve: Boolean, onHandled: (isPause: Boolean) -> Unit) { mode.funcEstablish(avatar, arrayOf(hash, date, isValve), onHandled) } }