commit 20/08/2025
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import audio.AudioPlayer
|
||||
import content.ContentCache
|
||||
import org.tinylog.Logger
|
||||
|
||||
import web.WebApp
|
||||
|
||||
|
||||
fun main() {
|
||||
@@ -9,5 +9,12 @@ fun main() {
|
||||
val audioPlayer = AudioPlayer(44100) // 44100 Hz sampling rate
|
||||
audioPlayer.InitAudio(1)
|
||||
val content = ContentCache()
|
||||
val web = WebApp(3030,
|
||||
listOf(
|
||||
Pair("admin", "password"),
|
||||
Pair("user", "password")
|
||||
)
|
||||
)
|
||||
web.Start()
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package codes
|
||||
|
||||
import oshi.SystemInfo
|
||||
import oshi.hardware.CentralProcessor
|
||||
import oshi.hardware.GlobalMemory
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
@@ -7,6 +10,45 @@ import java.nio.file.Path
|
||||
@Suppress("unused")
|
||||
class Somecodes {
|
||||
companion object {
|
||||
|
||||
val si = SystemInfo()
|
||||
val processor: CentralProcessor = si.hardware.processor
|
||||
val memory : GlobalMemory = si.hardware.memory
|
||||
|
||||
|
||||
const val KB_threshold = 1024.0
|
||||
const val MB_threshold = KB_threshold * 1024.0
|
||||
const val GB_threshold = MB_threshold * 1024.0
|
||||
const val TB_threshold = GB_threshold * 1024.0
|
||||
|
||||
/**
|
||||
* Converts a size in bytes to a human-readable format.
|
||||
* @param size Size in bytes.
|
||||
* @return A string representing the size in a human-readable format.
|
||||
*/
|
||||
fun SizetoHuman(size: Long): String {
|
||||
return when {
|
||||
size < KB_threshold -> "${size}B"
|
||||
size < MB_threshold -> String.format("%.2f KB", size / KB_threshold)
|
||||
size < GB_threshold -> String.format("%.2f MB", size / MB_threshold)
|
||||
size < TB_threshold -> String.format("%.2f GB", size / GB_threshold)
|
||||
else -> String.format("%.2f TB", size / TB_threshold)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun getMemoryUsage() : String{
|
||||
val totalMemory = memory.total
|
||||
val availableMemory = memory.available
|
||||
val usedMemory = totalMemory - availableMemory
|
||||
return String.format("Total: %s, Used: %s, Available: %s, Usage: %.2f%%",
|
||||
SizetoHuman(totalMemory),
|
||||
SizetoHuman(usedMemory),
|
||||
SizetoHuman(availableMemory)
|
||||
, (usedMemory.toDouble() / totalMemory * 100))
|
||||
}
|
||||
|
||||
fun ValidString(value: Any) : Boolean {
|
||||
return value is String && value.isNotBlank()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package database
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.mariadb.jdbc.Connection
|
||||
import org.tinylog.Logger
|
||||
import java.sql.DriverManager
|
||||
@@ -46,19 +49,17 @@ class MariaDB (
|
||||
Logger.info("Connected to MariaDB" as Any)
|
||||
connected = true
|
||||
|
||||
val loadthread = Thread {
|
||||
// Load soundbank and messagebank lists
|
||||
Reload_Messagebank()
|
||||
Logger.info { "Messagebank loaded" }
|
||||
Reload_Soundbank()
|
||||
Logger.info { "Soundbank loaded" }
|
||||
|
||||
runBlocking {
|
||||
withContext(Dispatchers.IO){
|
||||
Reload_Messagebank()
|
||||
Logger.info { "Messagebank loaded" }
|
||||
Reload_Soundbank()
|
||||
Logger.info { "Soundbank loaded" }
|
||||
}
|
||||
}
|
||||
loadthread.name = "LoadMariaDBThread"
|
||||
loadthread.isDaemon = true
|
||||
loadthread.start()
|
||||
|
||||
loadthread.join()
|
||||
|
||||
|
||||
Logger.info { "Loading MariaDB completed" }
|
||||
Logger.info { "Soundbank count: ${SoundbankList.size}" }
|
||||
Logger.info { "Messagebank count: ${MessagebankList.size}" }
|
||||
|
||||
145
src/web/WebApp.kt
Normal file
145
src/web/WebApp.kt
Normal file
@@ -0,0 +1,145 @@
|
||||
package web
|
||||
|
||||
import codes.Somecodes
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import io.javalin.Javalin
|
||||
import io.javalin.apibuilder.ApiBuilder.before
|
||||
import io.javalin.apibuilder.ApiBuilder.get
|
||||
import io.javalin.apibuilder.ApiBuilder.path
|
||||
import io.javalin.apibuilder.ApiBuilder.post
|
||||
import io.javalin.apibuilder.ApiBuilder.ws
|
||||
import io.javalin.http.Context
|
||||
|
||||
@Suppress("unused")
|
||||
class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
|
||||
var app : Javalin? = null
|
||||
private val objectmapper = jacksonObjectMapper()
|
||||
|
||||
fun Start() {
|
||||
app = Javalin.create {
|
||||
config ->
|
||||
config.useVirtualThreads = true
|
||||
config.staticFiles.add("/webpage")
|
||||
config.router.apiBuilder {
|
||||
path("/"){
|
||||
get { ctx ->
|
||||
// Serve the main page
|
||||
ctx.sessionAttribute("user", null) // Clear user session
|
||||
ctx.redirect("login.html")
|
||||
}
|
||||
|
||||
}
|
||||
path("login.html"){
|
||||
post{ it ->
|
||||
// get username and password from form
|
||||
val username = it.formParam("username")
|
||||
val password = it.formParam("password")
|
||||
if (username == null || password == null) {
|
||||
it.status(400).result("Username and password are required")
|
||||
return@post
|
||||
}
|
||||
// Check if user exists in userlist
|
||||
val user = userlist.find { it.first == username && it.second == password }
|
||||
if (user == null) {
|
||||
it.status(401).result("Invalid username or password")
|
||||
return@post
|
||||
}
|
||||
// Set user session
|
||||
it.sessionAttribute("user", user.first)
|
||||
println("User ${user.first} logged in")
|
||||
// Redirect to home page
|
||||
it.redirect("home.html")
|
||||
}
|
||||
}
|
||||
|
||||
path("home.html") {
|
||||
before { CheckUsers(it) }
|
||||
ws("/ws") { it ->
|
||||
// WebSocket endpoint for home
|
||||
it.onClose {
|
||||
// TODO Handle WebSocket close event
|
||||
println("WebSocket closed: ${it.session.remoteAddress}")
|
||||
}
|
||||
it.onMessage {
|
||||
try{
|
||||
val cmd = objectmapper.readValue(it.message(), WebsocketCommand::class.java)
|
||||
when (cmd.command) {
|
||||
"getCPUStatus" ->{
|
||||
//TODO Get CPU status
|
||||
|
||||
it.send(objectmapper.writeValueAsString(WebsocketReply(cmd.command,"OK")))
|
||||
}
|
||||
"getMemoryStatus" ->{
|
||||
// TODO Get Memory status
|
||||
it.send(objectmapper.writeValueAsString(WebsocketReply(cmd.command, Somecodes.getMemoryUsage())))
|
||||
}
|
||||
"getDiskStatus" ->{
|
||||
// TODO Get Disk status
|
||||
it.send(objectmapper.writeValueAsString(WebsocketReply(cmd.command,"OK")))
|
||||
}
|
||||
"getNetworkStatus" ->{
|
||||
// TODO Get Network status
|
||||
it.send(objectmapper.writeValueAsString(WebsocketReply(cmd.command,"OK")))
|
||||
}
|
||||
else -> {
|
||||
it.send(objectmapper.writeValueAsString(WebsocketReply("error", "Unknown command: ${cmd.command}")))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception){
|
||||
println("Error processing WebSocket message: ${e.message}")
|
||||
}
|
||||
|
||||
}
|
||||
it.onConnect {
|
||||
// TODO Handle WebSocket connect event
|
||||
println("WebSocket connected: ${it.session.remoteAddress}")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
path("soundbank.html") {
|
||||
before {CheckUsers(it)}
|
||||
}
|
||||
path("messagebank.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("language.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("log.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("setting.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
path("timer.html") {
|
||||
before { CheckUsers(it) }
|
||||
}
|
||||
}
|
||||
}.start(listenPort)
|
||||
|
||||
}
|
||||
|
||||
fun CheckUsers(ctx: Context){
|
||||
println("Checking user session at ${ctx.req().requestURI}")
|
||||
val user = ctx.sessionAttribute<String?>("user")
|
||||
if (user == null) {
|
||||
println("User not logged in, redirecting to login page")
|
||||
ctx.redirect("login.html")
|
||||
}
|
||||
println("User is logged in: $user")
|
||||
val foundUser = userlist.find { it.first == user }
|
||||
if (foundUser==null) {
|
||||
println("User not found in user list, redirecting to login page")
|
||||
ctx.redirect("login.html")
|
||||
} else {
|
||||
println("User found: $user")
|
||||
}
|
||||
}
|
||||
|
||||
fun Stop(){
|
||||
app?.stop()
|
||||
|
||||
}
|
||||
}
|
||||
4
src/web/WebsocketCommand.kt
Normal file
4
src/web/WebsocketCommand.kt
Normal file
@@ -0,0 +1,4 @@
|
||||
package web
|
||||
|
||||
@Suppress("unused")
|
||||
data class WebsocketCommand (val command: String, val data: String)
|
||||
4
src/web/WebsocketReply.kt
Normal file
4
src/web/WebsocketReply.kt
Normal file
@@ -0,0 +1,4 @@
|
||||
package web
|
||||
|
||||
@Suppress("unused")
|
||||
data class WebsocketReply (val reply: String, val data: String)
|
||||
Reference in New Issue
Block a user