mirror of
https://github.com/GayPizzaSpecifications/foundation.git
synced 2025-08-02 13:10:55 +00:00
DevUpdate Server for Test Server Updates
This commit is contained in:
parent
795e99ad4f
commit
139ce551dc
@ -1,6 +1,7 @@
|
||||
package cloud.kubelet.foundation.core
|
||||
|
||||
import cloud.kubelet.foundation.core.command.*
|
||||
import cloud.kubelet.foundation.core.devupdate.DevUpdateServer
|
||||
import cloud.kubelet.foundation.core.persist.PersistentStore
|
||||
import cloud.kubelet.foundation.core.persist.setAllProperties
|
||||
import io.papermc.paper.event.player.AsyncChatEvent
|
||||
@ -19,6 +20,8 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
class FoundationCorePlugin : JavaPlugin(), Listener {
|
||||
internal val persistentStores = ConcurrentHashMap<String, PersistentStore>()
|
||||
private lateinit var _pluginDataPath: Path
|
||||
private lateinit var chatLogStore: PersistentStore
|
||||
private lateinit var devUpdateServer: DevUpdateServer
|
||||
|
||||
var pluginDataPath: Path
|
||||
/**
|
||||
@ -40,8 +43,6 @@ class FoundationCorePlugin : JavaPlugin(), Listener {
|
||||
*/
|
||||
fun getPersistentStore(name: String) = persistentStores.getOrPut(name) { PersistentStore(this, name) }
|
||||
|
||||
private lateinit var chatLogStore: PersistentStore
|
||||
|
||||
override fun onEnable() {
|
||||
pluginDataPath = dataFolder.toPath()
|
||||
val backupPath = pluginDataPath.resolve(BACKUPS_DIRECTORY)
|
||||
@ -67,11 +68,14 @@ class FoundationCorePlugin : JavaPlugin(), Listener {
|
||||
log.info("Features:")
|
||||
Util.printFeatureStatus(log, "Backup", BACKUP_ENABLED)
|
||||
chatLogStore = getPersistentStore("chat-logs")
|
||||
devUpdateServer = DevUpdateServer(this)
|
||||
devUpdateServer.enable()
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
persistentStores.values.forEach { store -> store.close() }
|
||||
persistentStores.clear()
|
||||
devUpdateServer.disable()
|
||||
}
|
||||
|
||||
private fun registerCommandExecutor(name: String, executor: CommandExecutor) {
|
||||
|
@ -0,0 +1,10 @@
|
||||
package cloud.kubelet.foundation.core.devupdate
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
class DevUpdateConfig(
|
||||
val port: Int = 8484,
|
||||
val token: String,
|
||||
val ipAllowList: List<String> = listOf("*")
|
||||
)
|
@ -0,0 +1,89 @@
|
||||
package cloud.kubelet.foundation.core.devupdate
|
||||
|
||||
import cloud.kubelet.foundation.core.FoundationCorePlugin
|
||||
import cloud.kubelet.foundation.core.Util
|
||||
import com.charleskorn.kaml.Yaml
|
||||
import com.sun.net.httpserver.HttpExchange
|
||||
import com.sun.net.httpserver.HttpServer
|
||||
import java.net.InetSocketAddress
|
||||
import kotlin.io.path.inputStream
|
||||
|
||||
class DevUpdateServer(val plugin: FoundationCorePlugin) {
|
||||
private lateinit var config: DevUpdateConfig
|
||||
private var server: HttpServer? = null
|
||||
|
||||
fun enable() {
|
||||
val configPath = Util.copyDefaultConfig<FoundationCorePlugin>(
|
||||
plugin.slF4JLogger,
|
||||
plugin.pluginDataPath,
|
||||
"devupdate.yaml"
|
||||
)
|
||||
|
||||
config = Yaml.default.decodeFromStream(DevUpdateConfig.serializer(), configPath.inputStream())
|
||||
start()
|
||||
}
|
||||
|
||||
private fun start() {
|
||||
if (config.token.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (config.token.length < 8) {
|
||||
plugin.slF4JLogger.warn("DevUpdate Token was too short (must be 8 or more characters)")
|
||||
return
|
||||
}
|
||||
|
||||
val server = HttpServer.create()
|
||||
server.createContext("/").setHandler { exchange ->
|
||||
val ip = exchange.remoteAddress.address.hostAddress
|
||||
if (!config.ipAllowList.contains("*") && !config.ipAllowList.contains(ip)) {
|
||||
plugin.slF4JLogger.warn("DevUpdate Server received request from IP $ip which is not allowed.")
|
||||
exchange.close()
|
||||
return@setHandler
|
||||
}
|
||||
|
||||
plugin.slF4JLogger.info("DevUpdate Server Request $ip ${exchange.requestMethod} ${exchange.requestURI.path}")
|
||||
if (exchange.requestMethod != "POST") {
|
||||
exchange.respond(405, "Method not allowed.")
|
||||
return@setHandler
|
||||
}
|
||||
|
||||
if (exchange.requestURI.path != "/webhook/update") {
|
||||
exchange.respond(404, "Not Found.")
|
||||
return@setHandler
|
||||
}
|
||||
|
||||
if (exchange.requestURI.query != config.token) {
|
||||
exchange.respond(401, "Unauthorized.")
|
||||
return@setHandler
|
||||
}
|
||||
|
||||
exchange.respond(200, "Success.")
|
||||
plugin.server.scheduler.runTask(plugin) { ->
|
||||
plugin.slF4JLogger.info("DevUpdate Server Restart")
|
||||
try {
|
||||
plugin.server.dispatchCommand(plugin.server.consoleSender, "fupdate")
|
||||
plugin.server.dispatchCommand(plugin.server.consoleSender, "stop")
|
||||
} catch (e: Exception) {
|
||||
plugin.slF4JLogger.error("DevUpdate Server failed to update server.", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
server.bind(InetSocketAddress("0.0.0.0", config.port), 0)
|
||||
server.start()
|
||||
this.server = server
|
||||
plugin.slF4JLogger.info("DevUpdate Server listening on port ${config.port}")
|
||||
}
|
||||
|
||||
fun disable() {
|
||||
server?.stop(0)
|
||||
}
|
||||
|
||||
private fun HttpExchange.respond(code: Int, content: String) {
|
||||
val encoded = content.encodeToByteArray()
|
||||
sendResponseHeaders(code, encoded.size.toLong())
|
||||
responseBody.write(encoded)
|
||||
responseBody.close()
|
||||
close()
|
||||
}
|
||||
}
|
12
foundation-core/src/main/resources/devupdate.yaml
Normal file
12
foundation-core/src/main/resources/devupdate.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
# Server port to listen on.
|
||||
port: 8484
|
||||
|
||||
# An authentication token. Should be random and 8 or more characters.
|
||||
# If empty, the DevUpdate server is not enabled.
|
||||
token: ""
|
||||
|
||||
# IP address allow list.
|
||||
# If * is specified, all addresses are allowed.
|
||||
# Specify IP addresses as a string that should be allowed to update the server.
|
||||
ipAllowList:
|
||||
- "*"
|
Loading…
Reference in New Issue
Block a user