More shit.

This commit is contained in:
yenon 2023-11-10 16:57:36 +01:00
parent 428226dcd4
commit 6915315192
3 changed files with 117 additions and 11 deletions

View File

@ -6,9 +6,19 @@ import io.ktor.server.cio.*
import io.ktor.server.engine.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import java.nio.file.Files
import kotlin.io.path.Path
suspend fun main() {
val path = Path("data.json")
if (Files.isRegularFile(path)) {
RaceHolder.load(path)
}
Runtime.getRuntime().addShutdownHook(Thread {
RaceHolder.save(path)
})
val kord = Kord("MTE3MTIwODc1MDE5MTg5MDQ4Mw.GOUedL.i3zD6IG5B6fFRvaSOotWwJ5KBRK2whC9xr0vL8")
kord.on<MessageCreateEvent> {

View File

@ -1,9 +1,15 @@
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
@Serializable
data class RaceData(var name: String, var description: String) {
val trackList = arrayListOf<Long>()
val leaderboardMap = hashMapOf<Long, Velocidrone.Leaderboard>()
private val trackList = arrayListOf<Long>()
private val leaderboardMap = hashMapOf<Long, Velocidrone.Leaderboard>()
private var totalScores = arrayListOf<Pair<String, Long>>()
fun addTrack(trackId: Long) {
trackList.add(trackId)
@ -14,7 +20,7 @@ data class RaceData(var name: String, var description: String) {
leaderboardMap.remove(trackId)
}
suspend fun rescanLeaderboard(trackId: Long, newLeaderboardCallback: (Velocidrone.Leaderboard) -> Unit) {
private suspend fun rescanLeaderboard(trackId: Long, newLeaderboardCallback: (Velocidrone.Leaderboard) -> Unit) {
if (trackList.contains(trackId)) {
Velocidrone.getLeaderboardForId(trackId).getOrNull()?.let { newLeaderboard ->
if (leaderboardMap[trackId]?.equals(newLeaderboard) == false) {
@ -25,17 +31,56 @@ data class RaceData(var name: String, var description: String) {
}
}
fun getTotalScores(): List<Pair<String, Long>> {
suspend fun rescanAll() {
var changes = false
trackList.forEach {
rescanLeaderboard(it) {
changes = true
}
}
if (changes) {
calculateTotalScores()
}
}
fun calculateTotalScores() {
val scoreMap = hashMapOf<String, Long>()
leaderboardMap.forEach { leaderboardEntry ->
val sortedTimes = leaderboardEntry.value.tracktimes.sortedBy { it.lap_time }.forEach {
leaderboardEntry.value.tracktimes.sortedBy { it.lap_time }.forEach {
scoreMap[it.playername] = scoreMap.getOrDefault(it.playername, 0L) + 1
}
}
return scoreMap.toList().sortedByDescending { it.second }
synchronized(totalScores) {
totalScores.clear()
scoreMap.asIterable().sortedByDescending { it.value }.map { it.toPair() }.toCollection(totalScores)
}
}
}
object RaceHolder {
val races = arrayListOf<RaceData>()
var races = arrayListOf<RaceData>()
fun save(path: Path) {
val tempSavePath = path.resolveSibling("save.json.tmp")
val stream = Files.newBufferedWriter(
tempSavePath,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE,
StandardOpenOption.CREATE
).buffered()
stream.write(Json.encodeToString(races))
stream.flush()
stream.close()
if (Files.isRegularFile(path)) {
Files.delete(path)
}
Files.move(tempSavePath, path)
}
fun load(path: Path) {
val stream = Files.newBufferedReader(path)
races = Json.decodeFromString(stream.readText())
stream.close()
}
}

View File

@ -1,14 +1,32 @@
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.util.pipeline.*
import kotlinx.html.div
import kotlinx.html.h1
import kotlinx.html.p
import kotlinx.html.*
fun Routing.racePage() {
get("/races") {
get("/race/list") {
raceOverviewPage(RaceHolder.races)
}
get("/race/new") {
newRacePage()
}
post("/race/new") {
val parameters = call.receiveParameters()
val name = parameters["name"]
val description = parameters["description"]
if (name == null || description == null) {
newRacePage("Not all parameters given.", name ?: "", description ?: "")
return@post
}
if (RaceHolder.races.any { it.name == name }) {
newRacePage("Race with the same name already exists.", name, description)
return@post
}
RaceHolder.races.add(RaceData(name, description))
call.respondRedirect("/race/list")
}
}
private suspend fun PipelineContext<Unit, ApplicationCall>.raceOverviewPage(races: ArrayList<RaceData>) {
@ -22,4 +40,37 @@ private suspend fun PipelineContext<Unit, ApplicationCall>.raceOverviewPage(race
}
}
}
}
private suspend fun PipelineContext<Unit, ApplicationCall>.newRacePage(
error: String? = null,
name: String = "",
description: String = ""
) {
respondThemedHtml("Race Overview") {
form("/race/new", encType = FormEncType.applicationXWwwFormUrlEncoded, method = FormMethod.post) {
error?.let {
p(classes = "error") {
+it
}
}
p {
+"Name:"
textInput(name = "name") {
value = name
}
}
p {
+"Description:"
}
p {
TEXTAREA(mapOf("name" to "description", "rows" to "4", "cols" to "40"), consumer).visit {
+description
}
}
p {
submitInput()
}
}
}
}