mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-26 15:49:14 +07:00
Server Cleanup (#13598)
* update server dependencies and do necessary cleanup for chat support later * resolve versions issue
This commit is contained in:

committed by
GitHub

parent
cbf5f551f2
commit
3616a39caa
3
.gitignore
vendored
3
.gitignore
vendored
@ -170,3 +170,6 @@ detekt/reports.html
|
||||
|
||||
# When you test the wiki by running mkdocs locally:
|
||||
/site/
|
||||
|
||||
# When running the desktop app locally using "gradlew desktop:run"
|
||||
GameSettings.json
|
||||
|
@ -1,9 +1,10 @@
|
||||
|
||||
import com.unciv.build.BuildConfig.appVersion
|
||||
import com.unciv.build.BuildConfig.coroutinesVersion
|
||||
import com.unciv.build.BuildConfig.gdxVersion
|
||||
import com.unciv.build.BuildConfig.jnaVersion
|
||||
import com.unciv.build.BuildConfig.kotlinVersion
|
||||
import com.unciv.build.BuildConfig.ktorVersion
|
||||
import com.unciv.build.BuildConfig.appVersion
|
||||
|
||||
|
||||
buildscript {
|
||||
@ -89,21 +90,28 @@ project(":desktop") {
|
||||
"implementation"("com.github.MinnDevelopment:java-discord-rpc:v2.0.1")
|
||||
|
||||
// Needed for Windows turn notifiers
|
||||
"implementation"("net.java.dev.jna:jna:5.11.0")
|
||||
"implementation"("net.java.dev.jna:jna-platform:5.11.0")
|
||||
"implementation"("net.java.dev.jna:jna:$jnaVersion")
|
||||
"implementation"("net.java.dev.jna:jna-platform:$jnaVersion")
|
||||
}
|
||||
}
|
||||
|
||||
// For server-side
|
||||
project(":server") {
|
||||
apply(plugin = "kotlin")
|
||||
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
|
||||
|
||||
dependencies {
|
||||
// For server-side
|
||||
"implementation"("io.ktor:ktor-server-core:1.6.8")
|
||||
"implementation"("io.ktor:ktor-server-netty:1.6.8")
|
||||
"implementation"("ch.qos.logback:logback-classic:1.2.5")
|
||||
"implementation"("com.github.ajalt.clikt:clikt:3.4.0")
|
||||
"implementation"("io.ktor:ktor-server-core:$ktorVersion")
|
||||
"implementation"("io.ktor:ktor-server-netty:$ktorVersion")
|
||||
"implementation"("io.ktor:ktor-server-content-negotiation:$ktorVersion")
|
||||
"implementation"("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
|
||||
"implementation"("ch.qos.logback:logback-classic:1.5.18")
|
||||
"implementation"("com.github.ajalt.clikt:clikt:4.4.0")
|
||||
|
||||
// clikt somehow needs this
|
||||
"implementation"("net.java.dev.jna:jna:$jnaVersion")
|
||||
"implementation"("net.java.dev.jna:jna-platform:$jnaVersion")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,8 +8,9 @@ object BuildConfig {
|
||||
const val appVersion = "4.17.4"
|
||||
|
||||
const val gdxVersion = "1.13.1"
|
||||
const val ktorVersion = "2.3.12"
|
||||
const val ktorVersion = "2.3.13"
|
||||
const val coroutinesVersion = "1.8.1"
|
||||
const val jnaVersion = "5.17.0"
|
||||
|
||||
const val identifier = "com.unciv.app"
|
||||
}
|
||||
|
@ -6,31 +6,38 @@ import com.github.ajalt.clikt.parameters.options.flag
|
||||
import com.github.ajalt.clikt.parameters.options.option
|
||||
import com.github.ajalt.clikt.parameters.types.int
|
||||
import com.github.ajalt.clikt.parameters.types.restrictTo
|
||||
import io.ktor.application.call
|
||||
import io.ktor.application.log
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.request.receiveText
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.response.respondText
|
||||
import io.ktor.routing.get
|
||||
import io.ktor.routing.put
|
||||
import io.ktor.routing.routing
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import io.ktor.server.application.call
|
||||
import io.ktor.server.application.install
|
||||
import io.ktor.server.application.log
|
||||
import io.ktor.server.engine.embeddedServer
|
||||
import io.ktor.server.engine.stop
|
||||
import io.ktor.server.netty.Netty
|
||||
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.server.request.receiveText
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.response.respondText
|
||||
import io.ktor.server.routing.get
|
||||
import io.ktor.server.routing.put
|
||||
import io.ktor.server.routing.routing
|
||||
import io.ktor.utils.io.jvm.javaio.toInputStream
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.io.File
|
||||
import java.util.Base64
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
|
||||
internal object UncivServer {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) = UncivServerRunner().main(args)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class IsAliveInfo(val authVersion: Int)
|
||||
|
||||
private class UncivServerRunner : CliktCommand() {
|
||||
private val port by option(
|
||||
"-p", "-port",
|
||||
@ -102,6 +109,7 @@ private class UncivServerRunner : CliktCommand() {
|
||||
return authMap[userId] == null || authMap[userId] == password
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
private fun extractAuth(authHeader: String?): Pair<String, String>? {
|
||||
if (!authV1Enabled)
|
||||
return null
|
||||
@ -110,8 +118,8 @@ private class UncivServerRunner : CliktCommand() {
|
||||
if (authHeader == null || !authHeader.startsWith("Basic "))
|
||||
return null
|
||||
|
||||
val decodedString = String(Base64.getDecoder().decode(authHeader.drop(6)))
|
||||
val splitAuthString = decodedString.split(":", limit=2)
|
||||
val decodedString = Base64.Default.decode(authHeader.drop(6)).decodeToString()
|
||||
val splitAuthString = decodedString.split(":", limit = 2)
|
||||
if (splitAuthString.size != 2)
|
||||
return null
|
||||
|
||||
@ -121,24 +129,27 @@ private class UncivServerRunner : CliktCommand() {
|
||||
|
||||
private fun serverRun(serverPort: Int, fileFolderName: String) {
|
||||
val portStr: String = if (serverPort == 80) "" else ":$serverPort"
|
||||
|
||||
val isAliveInfo = IsAliveInfo(authVersion = if (authV1Enabled) 1 else 0)
|
||||
|
||||
val file = File(fileFolderName)
|
||||
echo("Starting UncivServer for ${file.absolutePath} on http://localhost$portStr")
|
||||
if (!file.exists()) file.mkdirs()
|
||||
val server = embeddedServer(Netty, port = serverPort) {
|
||||
install(ContentNegotiation) { json() }
|
||||
|
||||
routing {
|
||||
get("/isalive") {
|
||||
log.info("Received isalive request from ${call.request.local.remoteHost}")
|
||||
call.respondText("{authVersion: ${if (authV1Enabled) "1" else "0"}}")
|
||||
call.application.log.info("Received isalive request from ${call.request.local.remoteHost}")
|
||||
call.respond(isAliveInfo)
|
||||
}
|
||||
put("/files/{fileName}") {
|
||||
val fileName = call.parameters["fileName"] ?: throw Exception("No fileName!")
|
||||
|
||||
// If IdentifyOperators is enabled an Operator IP is displayed
|
||||
if (identifyOperators) {
|
||||
log.info("Receiving file: $fileName --Operation sourced from ${call.request.local.remoteHost}")
|
||||
}else{
|
||||
log.info("Receiving file: $fileName")
|
||||
call.application.log.info("Receiving file: $fileName --Operation sourced from ${call.request.local.remoteHost}")
|
||||
} else {
|
||||
call.application.log.info("Receiving file: $fileName")
|
||||
}
|
||||
|
||||
val file = File(fileFolderName, fileName)
|
||||
@ -160,9 +171,9 @@ private class UncivServerRunner : CliktCommand() {
|
||||
|
||||
// If IdentifyOperators is enabled an Operator IP is displayed
|
||||
if (identifyOperators) {
|
||||
log.info("File requested: $fileName --Operation sourced from ${call.request.local.remoteHost}")
|
||||
}else{
|
||||
log.info("File requested: $fileName")
|
||||
call.application.log.info("File requested: $fileName --Operation sourced from ${call.request.local.remoteHost}")
|
||||
} else {
|
||||
call.application.log.info("File requested: $fileName")
|
||||
}
|
||||
|
||||
val file = File(fileFolderName, fileName)
|
||||
@ -170,9 +181,9 @@ private class UncivServerRunner : CliktCommand() {
|
||||
|
||||
// If IdentifyOperators is enabled an Operator IP is displayed
|
||||
if (identifyOperators) {
|
||||
log.info("File $fileName not found --Operation sourced from ${call.request.local.remoteHost}")
|
||||
call.application.log.info("File $fileName not found --Operation sourced from ${call.request.local.remoteHost}")
|
||||
} else {
|
||||
log.info("File $fileName not found")
|
||||
call.application.log.info("File $fileName not found")
|
||||
}
|
||||
call.respond(HttpStatusCode.NotFound, "File does not exist")
|
||||
return@get
|
||||
@ -183,7 +194,7 @@ private class UncivServerRunner : CliktCommand() {
|
||||
}
|
||||
if (authV1Enabled) {
|
||||
get("/auth") {
|
||||
log.info("Received auth request from ${call.request.local.remoteHost}")
|
||||
call.application.log.info("Received auth request from ${call.request.local.remoteHost}")
|
||||
|
||||
val authHeader = call.request.headers["Authorization"] ?: run {
|
||||
call.respond(HttpStatusCode.BadRequest, "Missing authorization header!")
|
||||
@ -202,7 +213,7 @@ private class UncivServerRunner : CliktCommand() {
|
||||
}
|
||||
}
|
||||
put("/auth") {
|
||||
log.info("Received auth password set from ${call.request.local.remoteHost}")
|
||||
call.application.log.info("Received auth password set from ${call.request.local.remoteHost}")
|
||||
val authHeader = call.request.headers["Authorization"]
|
||||
if (validateAuth(authHeader)) {
|
||||
val (userId, _) = extractAuth(authHeader) ?: Pair(null, null)
|
||||
|
Reference in New Issue
Block a user