Skip to content

Commit fb32dff

Browse files
committed
feat: finish backend
1 parent 0bac3e0 commit fb32dff

File tree

6 files changed

+68
-8
lines changed

6 files changed

+68
-8
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/run/
66
/*.iml
77
/kotlin-js-store/
8+
/.kotlin/

docker-compose.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ services:
1313
- "traefik.http.routers.adventure-webui.tls.certresolver=httpOnly"
1414
- "traefik.http.routers.adventure-webui.tls.domains[0].main=webui.adventure.kyori.net"
1515
- "traefik.http.routers.adventure-webui.tls.domains[1].main=webui.advntr.dev"
16+
- "traefik.tcp.services.adventure-webui-mc.loadbalancer.server.port=25565"
17+
- "traefik.tcp.routers.adventure-webui-mc.rule=HostSNI(`*`)"
18+
- "traefik.tcp.routers.adventure-webui-mc.entrypoints=minecraft"
19+
- "traefik.tcp.routers.adventure-webui-mc.tls.passthrough=true"
1620
networks:
1721
- web
1822

src/commonMain/kotlin/net/kyori/adventure/webui/Constants.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,10 @@ public const val PARAM_EDITOR_TOKEN: String = "token"
4242
/** Path for getting a short link for a MiniMessage input. */
4343
public const val URL_MINI_SHORTEN: String = "/mini-shorten"
4444

45+
/** Path for getting a hostname for an in-game MiniMessage motd preview. */
46+
public const val URL_SETUP_MOTD_PREVIEW: String = "/setup-motd-preview"
47+
/** Path for getting a hostname for an in-game MiniMessage kick preview. */
48+
public const val URL_SETUP_KICK_PREVIEW: String = "/setup-kick-preview"
49+
4550
/** Path for getting the configuration of this WebUI instance */
4651
public const val URL_BUILD_INFO: String = "/build"

src/jvmMain/kotlin/net/kyori/adventure/webui/jvm/Application.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import io.ktor.server.websocket.WebSockets
1515
import io.ktor.server.websocket.pingPeriod
1616
import io.ktor.server.websocket.timeout
1717
import io.ktor.websocket.WebSocketDeflateExtension
18-
import net.kyori.adventure.webui.jvm.minimessage.preview.ServerStatusPreviewManager
1918
import java.time.Duration
2019

2120
public fun Application.main() {
@@ -49,9 +48,6 @@ public fun Application.main() {
4948
trace { route -> this@main.log.debug(route.buildText()) }
5049
}
5150
}
52-
53-
// Initialise the server status preview manager.
54-
ServerStatusPreviewManager(this)
5551
}
5652

5753

src/jvmMain/kotlin/net/kyori/adventure/webui/jvm/minimessage/MiniMessage.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import net.kyori.adventure.webui.URL_MINI_SHORTEN
3030
import net.kyori.adventure.webui.URL_MINI_TO_HTML
3131
import net.kyori.adventure.webui.URL_MINI_TO_JSON
3232
import net.kyori.adventure.webui.URL_MINI_TO_TREE
33+
import net.kyori.adventure.webui.URL_SETUP_KICK_PREVIEW
34+
import net.kyori.adventure.webui.URL_SETUP_MOTD_PREVIEW
3335
import net.kyori.adventure.webui.jvm.appendComponent
3436
import net.kyori.adventure.webui.jvm.getConfigString
3537
import net.kyori.adventure.webui.jvm.minimessage.editor.installEditor
@@ -42,6 +44,7 @@ import net.kyori.adventure.webui.jvm.minimessage.hook.INSERTION_RENDER_HOOK
4244
import net.kyori.adventure.webui.jvm.minimessage.hook.TEXT_COLOR_RENDER_HOOK
4345
import net.kyori.adventure.webui.jvm.minimessage.hook.TEXT_DECORATION_RENDER_HOOK
4446
import net.kyori.adventure.webui.jvm.minimessage.hook.TEXT_RENDER_HOOK
47+
import net.kyori.adventure.webui.jvm.minimessage.preview.ServerStatusPreviewManager
4548
import net.kyori.adventure.webui.jvm.minimessage.storage.BytebinStorage
4649
import net.kyori.adventure.webui.tryDecodeFromString
4750
import net.kyori.adventure.webui.websocket.Call
@@ -92,6 +95,9 @@ public fun Application.miniMessage() {
9295

9396
BytebinStorage.BYTEBIN_INSTANCE = this.getConfigString("bytebinInstance")
9497

98+
// Initialise the server status preview manager.
99+
val previewManager = ServerStatusPreviewManager(this)
100+
95101
routing {
96102
// define static path to resources
97103
static("") {
@@ -199,6 +205,18 @@ public fun Application.miniMessage() {
199205
}
200206
}
201207

208+
post(URL_SETUP_MOTD_PREVIEW) {
209+
val input = call.receiveText()
210+
val hostname = previewManager.initializeMotdPreview(input)
211+
call.respondText(hostname)
212+
}
213+
214+
post(URL_SETUP_KICK_PREVIEW) {
215+
val input = call.receiveText()
216+
val hostname = previewManager.initializeKickPreview(input)
217+
call.respondText(hostname)
218+
}
219+
202220
get(URL_BUILD_INFO) {
203221
val info = BuildInfo(
204222
startedAt = startedAt.toString(),

src/jvmMain/kotlin/net/kyori/adventure/webui/jvm/minimessage/preview/ServerStatusPreviewManager.kt

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.kyori.adventure.webui.jvm.minimessage.preview
22

3+
import io.github.reactivecircus.cache4k.Cache
34
import io.ktor.network.selector.SelectorManager
45
import io.ktor.network.sockets.aSocket
56
import io.ktor.network.sockets.openReadChannel
@@ -24,6 +25,7 @@ import org.slf4j.LoggerFactory
2425
import java.io.ByteArrayOutputStream
2526
import java.io.DataOutputStream
2627
import kotlin.coroutines.CoroutineContext
28+
import kotlin.time.Duration.Companion.hours
2729

2830
/** Manager class for previewing server status. */
2931
public class ServerStatusPreviewManager(
@@ -34,10 +36,13 @@ public class ServerStatusPreviewManager(
3436
private val managerJob = SupervisorJob(application.coroutineContext.job)
3537
override val coroutineContext: CoroutineContext = application.coroutineContext + managerJob
3638

39+
private val motdPreviews = Cache.Builder<String, String>().expireAfterAccess(1.hours).build()
40+
private val kickPreviews = Cache.Builder<String, String>().expireAfterAccess(1.hours).build()
41+
3742
init {
3843
launch {
3944
// Initialise the socket.
40-
val serverSocket = aSocket(SelectorManager(Dispatchers.IO)).tcp().bind("127.0.0.1", 9002)
45+
val serverSocket = aSocket(SelectorManager(Dispatchers.IO)).tcp().bind("0.0.0.0", 25565)
4146
logger.info("Listening for pings at ${serverSocket.localAddress}")
4247

4348
while (true) {
@@ -64,7 +69,7 @@ public class ServerStatusPreviewManager(
6469
sendChannel.writeMcPacket(0) {
6570
it.writeString(
6671
GsonComponentSerializer.gson()
67-
.serialize(MiniMessage.miniMessage().deserialize("<red>You cant join here!"))
72+
.serialize(MiniMessage.miniMessage().deserialize(lookupKickMessage(serverAddress)))
6873
)
6974
}
7075
} else {
@@ -77,11 +82,15 @@ public class ServerStatusPreviewManager(
7782
LegacyComponentSerializer.legacySection()
7883
.serialize(MiniMessage.miniMessage().deserialize("<rainbow>MiniMessage"))
7984
}",
80-
"protocol": $protocolVersion
85+
"protocol": 1
86+
},
87+
"players": {
88+
"max": 0,
89+
"online": 0
8190
},
8291
"description": ${
8392
GsonComponentSerializer.gson().serialize(
84-
MiniMessage.miniMessage().deserialize("<rainbow>MiniMessage is cool!")
93+
MiniMessage.miniMessage().deserialize(lookupMotd(serverAddress))
8594
)
8695
}
8796
}""".trimIndent()
@@ -100,6 +109,33 @@ public class ServerStatusPreviewManager(
100109
}
101110
}
102111

112+
private fun lookupKickMessage(serverAddress: String): String {
113+
return kickPreviews.get(serverAddress.split("\\.")[0]) ?: "<red>You cant join here!"
114+
}
115+
116+
private fun lookupMotd(serverAddress: String): String {
117+
return motdPreviews.get(serverAddress.split("\\.")[0]) ?: "<rainbow>MiniMessage is cool!"
118+
}
119+
120+
public fun initializeKickPreview(input: String): String {
121+
val key = generateRandomString()
122+
kickPreviews.put(key, input)
123+
return "$key.webui.advntr.dev"
124+
}
125+
126+
public fun initializeMotdPreview(input: String): String {
127+
val key = generateRandomString()
128+
motdPreviews.put(key, input)
129+
return "$key.webui.advntr.dev"
130+
}
131+
132+
private fun generateRandomString(length: Int = 8): String {
133+
val allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
134+
return (1..length)
135+
.map { allowedChars.random() }
136+
.joinToString("")
137+
}
138+
103139
private suspend fun ByteWriteChannel.writeMcPacket(packetId: Int, consumer: (packet: DataOutputStream) -> Unit) {
104140
val stream = ByteArrayOutputStream()
105141
val packet = DataOutputStream(stream)

0 commit comments

Comments
 (0)