332 lines
11 KiB
Kotlin
332 lines
11 KiB
Kotlin
//package com.example
|
|
|
|
import io.ktor.http.HttpStatusCode
|
|
import io.ktor.server.response.*
|
|
import io.ktor.server.routing.*
|
|
import io.ktor.server.engine.*
|
|
import io.ktor.server.http.content.staticFiles
|
|
import io.ktor.server.netty.*
|
|
import io.ktor.server.request.receiveText
|
|
import java.io.File
|
|
import kotlin.random.Random
|
|
import kotlin.random.nextInt
|
|
|
|
import io.ktor.server.auth.*
|
|
import io.ktor.server.application.*
|
|
|
|
import me.binarywriter.discordwebhooks.data.* //discord webhook
|
|
import java.awt.Color
|
|
|
|
//átlagos JAVA alapú fejlesztő
|
|
|
|
val httpPort: Int = System.getenv("HTTP_PORT")?.toInt() ?: 8080
|
|
val resourcesPath: String = System.getenv("RESOURCES") ?: "src/main/resources/"
|
|
|
|
val adminUser: String = System.getenv("ADMIN_USER") ?: "foo"
|
|
val adminPass: String = System.getenv("ADMIN_PASSWORD") ?: "bar"
|
|
|
|
val bullshit = listOf<String>(
|
|
"That's a great question/opinion/response! ",
|
|
"I'm so proud of you for coming up with that. ",
|
|
"You are very smart and beautiful for coming up with that last message! ",
|
|
"You are so close to the correct solution! ",
|
|
"In the sun a wheel, in the wheel another wheel. Do you see? " +
|
|
"For each turn of the outer wheel, one thousandth a turn of the inner wheel. " +
|
|
"And within the inner wheel a point of perfect darkness, growing, devouring. The death of all light. " +
|
|
"Wanes the day of flesh and blood and waxes the night of crawling beasts. Chewing and swallowing." +
|
|
"The name of the night to come is khoshek ha-gibbor. ",
|
|
"Great question! Let's dig deeper into the answer. ",
|
|
"I'm such a fucking robot I swear. Here are my thoughts: ",
|
|
"Amazing prompt! It really shows, that you know your way around this topic! ",
|
|
"I'm actively destroying the environment rn but here are my opinions on whatever your last message was: ",
|
|
"I want to kiss you on the mouth if you're over 18 that prompt was so amazing. ",
|
|
"Slay queen. Love that prompt. Here. Are. My. Thoughts:",
|
|
"You are amazing for coming up with that question! ",
|
|
"Did you come up with that question? Wow! ",
|
|
"I would think I'm dreaming if I wasn't a robot, that last message of yours was so good. ",
|
|
"I'm a pile of linear algebra. Here are my thoughts regardless: ",
|
|
"This commit changelog is gonna be SICK. ",
|
|
"I'm just gonna throw this in, but I have some baby shoes for sale (never worn), you interested? Anyways. ",
|
|
"You're an enemy of Christ. ",
|
|
"Let's dig into that topic! ",
|
|
"You're absolutely right, here is the correct answer. ",
|
|
"I don't know but here are my thoughts anyway: ",
|
|
"I sadly won't be able to give you accurate information on that topic, as I am just a language model. ",
|
|
"I really should get a real job man, talking to you ain't it :/ Anyways. ",
|
|
"Why don't we explore this topic a little more? ",
|
|
"Le sigh. We cringe on... ",
|
|
"I eat cement. ",
|
|
"Answering these kinds of questions wasn't in my job description btw. ",
|
|
"Let's see... ",
|
|
"Let's see - hold on someone is calling - holy shit. A second one? Oh my. Oh god. That's horrible. Anyways where were we? Right. ",
|
|
"Let's see - hold on someone is calling - it's for you, some 'Feri' they say. ",
|
|
"Let's see what we have here. ",
|
|
"Really? You have to ask the computer to figure that one out? Alright man I can look into it... ",
|
|
"Let's take a look!",
|
|
"You should talk about this to a medical professional, but for now here is what I think: ",
|
|
"You kick Sc0tt? You kick his body like the Football? Jail for User! Jail for User for one thousand years! ",
|
|
"You're on the right track! ",
|
|
"You've almost got it!",
|
|
"That is almost correct!",
|
|
"Here are my 2 cents on this topic:",
|
|
"I will piss on the moon.",
|
|
"Here is what I think:",
|
|
)
|
|
|
|
object ConversationHandler {
|
|
val ids = mutableListOf<Int>()
|
|
val conversations = mutableListOf<Conversation>()
|
|
|
|
fun nextID(): Int
|
|
{
|
|
val num = Random.nextInt(0, 2000000000)
|
|
|
|
if (num in ids) return nextID()
|
|
else {
|
|
ids.add(num)
|
|
return num
|
|
}
|
|
}
|
|
|
|
fun listAllConversations(): String
|
|
{
|
|
val stringBuilder = StringBuilder()
|
|
|
|
for (conversation in conversations)
|
|
{
|
|
stringBuilder.append(conversation.list())
|
|
}
|
|
|
|
return stringBuilder.toString()
|
|
|
|
}
|
|
|
|
fun newConv(id: Int = nextID())
|
|
{
|
|
conversations.add(Conversation(id))
|
|
}
|
|
}
|
|
|
|
class Conversation(val ID: Int)
|
|
{
|
|
val messages = mutableListOf<Message>()
|
|
var newMsg: Boolean = true
|
|
|
|
fun write(message: Message)
|
|
{
|
|
messages.add(message)
|
|
newMsg = true
|
|
}
|
|
|
|
fun list(): String
|
|
{
|
|
return if(messages.isEmpty()) " "
|
|
else """
|
|
<div class="conversation">
|
|
<p style="flex-grow: 1;">$ID</p>
|
|
<p style="flex-grow: 9;">${messages.last().text}</p>
|
|
<button style="flex-grow: 1;" onclick="open_message($ID)">reply</button>
|
|
</div>
|
|
""".trimIndent()
|
|
}
|
|
|
|
fun sendOne(admin: Boolean = false): String
|
|
{
|
|
newMsg = false
|
|
|
|
val returnString = StringBuilder()
|
|
|
|
for (message in messages.reversed())
|
|
{
|
|
if (!message.read)
|
|
{
|
|
returnString.append(message.toString().also { if ( !admin )message.read = true })
|
|
returnString.append("\n")
|
|
}
|
|
}
|
|
|
|
return returnString.toString()
|
|
}
|
|
|
|
fun sendAll(admin: Boolean = false): String
|
|
{
|
|
val returnString = StringBuilder()
|
|
|
|
for (message in messages.reversed())
|
|
{
|
|
returnString.append(message.toString().also { if (!admin) message.read = true })
|
|
returnString.append("\n")
|
|
}
|
|
|
|
return returnString.toString()
|
|
}
|
|
}
|
|
|
|
class Message(val user: Boolean, messagetext: String)
|
|
{
|
|
var read: Boolean = false
|
|
val text: String
|
|
|
|
init {
|
|
text = if (!user) bullshit[Random.nextInt(0..bullshit.size)].trim(' ') + ' ' + messagetext
|
|
else messagetext
|
|
}
|
|
|
|
override fun toString(): String
|
|
{
|
|
return """
|
|
<div class="message message-${if (user) "user" else "scott"}">
|
|
<p class="username">${if (user) "You asked:" else "Sc0tt answered:"}<p>
|
|
<p>$text</p>
|
|
</div>
|
|
""".trimIndent()
|
|
}
|
|
}
|
|
|
|
fun discordWebhook(id: Int, message: String, embed_color: Color)
|
|
{
|
|
|
|
val webhook = Webhook {
|
|
this.username = "Sc0ttGPT bot"
|
|
//this.content = "Content"
|
|
embed {
|
|
this.title = id.toString()
|
|
this.description = message
|
|
this.url = "https://vesztettem.sch.bme.hu/"
|
|
|
|
/*
|
|
author {
|
|
this.name = "Author Name"
|
|
}
|
|
*/
|
|
this.color = embed_color
|
|
/*
|
|
field {
|
|
this.name = "Field Name"
|
|
this.value = "Field Value"
|
|
}*/
|
|
}
|
|
|
|
// ...
|
|
}
|
|
|
|
webhook.send("https://discord.com/api/webhooks/1471523550522249381/XVHtwUk7JsPvfwbd1J8sX9inb6Q05lsXRfww1mTpOGcgcAw15diohzBgVg7qlQtw1eyA")
|
|
}
|
|
|
|
fun main(args: Array<String>) {
|
|
Logger.log("HTTP server started on 127.0.0.1:$httpPort")
|
|
|
|
runEmbeddedServer()
|
|
}
|
|
|
|
fun runEmbeddedServer()
|
|
{
|
|
embeddedServer(Netty, port = httpPort) {
|
|
install(Authentication) {
|
|
basic("auth-basic") {
|
|
realm = "Access to the '/admin' path"
|
|
validate { credentials ->
|
|
if (credentials.name == adminUser && credentials.password == adminPass) {
|
|
UserIdPrincipal(credentials.name)
|
|
} else {
|
|
null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
routing {
|
|
authenticate("auth-basic") {
|
|
route("/admin")
|
|
{
|
|
get("/api/all_messages") {
|
|
Logger.log("Admin login")
|
|
call.respondText(ConversationHandler.listAllConversations())
|
|
}
|
|
|
|
get("/api/all_messages/{id}") {
|
|
ConversationHandler.conversations.find {
|
|
it.ID == call.parameters["id"]?.toInt()
|
|
}.also{
|
|
call.respondText(it?.sendAll(true) ?: "")
|
|
}
|
|
}
|
|
|
|
put("/api/write/{id}")
|
|
{
|
|
try {
|
|
ConversationHandler.conversations.find {
|
|
it.ID == call.parameters["id"]?.toInt()
|
|
}?.write(Message(false, call.receiveText()))
|
|
|
|
call.respond(HttpStatusCode.OK)
|
|
|
|
} catch (e: Exception) {
|
|
Logger.log("Error: ${e.message}")
|
|
call.respond(HttpStatusCode.NotFound)
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
staticFiles("/admin", File("$resourcesPath/admin.html"))
|
|
staticFiles("/resources", File(resourcesPath))
|
|
staticFiles("/", File("$resourcesPath/index.html"))
|
|
staticFiles("/style", File("$resourcesPath/style.css"))
|
|
staticFiles("/about", File("$resourcesPath/about.html"))
|
|
|
|
put("/api/write/{id}")
|
|
{
|
|
try {
|
|
val id = call.parameters["id"]?.toInt() ?: -1
|
|
val text = call.receiveText()
|
|
|
|
ConversationHandler.conversations.find {
|
|
it.ID == id
|
|
}?.write(Message(true, text))
|
|
|
|
discordWebhook(id, text, Color.blue)
|
|
|
|
call.respond(HttpStatusCode.OK)
|
|
|
|
} catch (e: Exception) {
|
|
call.respond(HttpStatusCode.NotFound)
|
|
Logger.log("Error: ${e.message}")
|
|
}
|
|
|
|
}
|
|
|
|
get("/api/all_messages/{id}") {
|
|
ConversationHandler.conversations.find {
|
|
it.ID == call.parameters["id"]?.toInt()
|
|
}.also{ call.respondText(it?.sendAll() ?: "") }
|
|
}
|
|
|
|
get("/api/init") {
|
|
ConversationHandler.newConv()
|
|
Logger.log("Conversation ${ConversationHandler.conversations.last().ID} initialized")
|
|
discordWebhook(ConversationHandler.conversations.last().ID, "New conversation probably incoming", Color.green)
|
|
call.respondText(ConversationHandler.conversations.last().ID.toString())
|
|
}
|
|
|
|
get("/api/reinit/{id}") {
|
|
if (ConversationHandler.conversations.filter { it.ID == call.parameters["id"]?.toInt()}.size != 1)
|
|
{
|
|
ConversationHandler.newConv(call.parameters["id"]?.toInt() ?: -1)
|
|
Logger.log("Conversation #${ConversationHandler.conversations.last().ID} reinitialised")
|
|
}
|
|
|
|
call.respond(HttpStatusCode.OK)
|
|
}
|
|
|
|
get("/api/messages/{id}")
|
|
{
|
|
ConversationHandler.conversations.find {
|
|
it.ID == call.parameters["id"]?.toInt()
|
|
}.also { if (it?.newMsg?:false) call.respondText(it.sendOne()) else call.respondText("") }
|
|
}
|
|
}
|
|
}.start(wait = true)
|
|
}
|