All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.robocode.tankroyale.gui.server.ServerProcess.kt Maven / Gradle / Ivy

package dev.robocode.tankroyale.gui.server

import dev.robocode.tankroyale.gui.settings.ConfigSettings
import dev.robocode.tankroyale.gui.settings.ServerSettings
import dev.robocode.tankroyale.gui.ui.server.ServerActions
import dev.robocode.tankroyale.gui.ui.server.ServerEvents
import dev.robocode.tankroyale.gui.ui.server.ServerLogFrame
import dev.robocode.tankroyale.gui.util.EDT
import dev.robocode.tankroyale.gui.util.ResourceUtil
import java.io.BufferedReader
import java.io.FileNotFoundException
import java.io.InputStreamReader
import java.io.PrintStream
import java.nio.file.Files
import java.nio.file.Paths
import java.util.concurrent.atomic.AtomicBoolean

object ServerProcess {

    private const val JAR_FILE_NAME = "robocode-tankroyale-server"

    private val isRunning = AtomicBoolean(false)
    private var process: Process? = null
    private var logThread: Thread? = null
    private val logThreadRunning = AtomicBoolean(false)

    init {
        ServerActions
    }

    fun isRunning(): Boolean = isRunning.get()

    fun start() {
        if (isRunning.get()) return

        var command: MutableList
        ServerSettings.apply {
            command = mutableListOf(
                "java",
                "-Dpicocli.ansi=true", // to show server logo in ANSI colors
                "-jar",
                getServerJar(),
                "--port=${serverPort}",
                "--games=classic,melee,1v1",
                "--tps=${ConfigSettings.tps}",
                "--controller-secrets=${controllerSecrets.joinToString(",")}",
                "--bot-secrets=${botSecrets.joinToString(",")}"
            )
            if (initialPositionsEnabled) {
                command += "--enable-initial-position"
            }
        }
        ProcessBuilder(command).apply {
            redirectErrorStream(true)
            process = start()
        }
        isRunning.set(true)

        startLogThread()

        ServerEvents.onStarted.fire(Unit)
    }

    fun stop() {
        if (!isRunning.get()) return

        stopLogThread()

        process?.apply {
            if (isAlive) {
                PrintStream(outputStream).apply {
                    println("q")
                    flush()
                }
            }
            waitFor()
            isRunning.set(false)
        }
        process = null
        logThread = null

        ServerEvents.onStopped.fire(Unit)
    }

    private fun getServerJar(): String {
        System.getProperty("serverJar")?.let {
            Paths.get(it).apply {
                if (Files.exists(this)) {
                    throw FileNotFoundException(toString())
                }
                return toString()
            }
        }
        Paths.get("").apply {
            Files.list(this).filter { it.startsWith(JAR_FILE_NAME) && it.endsWith(".jar") }.findFirst().apply {
                if (isPresent) {
                    return get().toString()
                }
            }
        }
        return try {
            ResourceUtil.getResourceFile("${JAR_FILE_NAME}.jar")?.absolutePath ?: ""
        } catch (ex: Exception) {
            System.err.println(ex.message)
            ""
        }
    }

    private fun startLogThread() {
        logThread = Thread {
            logThreadRunning.set(true)

            BufferedReader(InputStreamReader(process?.inputStream!!)).use {
                while (logThreadRunning.get()) {
                    try {
                        it.lines().forEach { line ->
                            EDT.enqueue {
                                ServerLogFrame.append(line + "\n")
                            }
                        }
                    } catch (_: InterruptedException) {
                        logThreadRunning.set(false)
                    }
                }
            }
        }.apply { start() }
    }

    private fun stopLogThread() {
        logThreadRunning.set(false)
        logThread?.interrupt()
    }
}

fun main() {
    ServerProcess.start()
    println("Server started")
    System.`in`.read()
    ServerProcess.stop()
    println("Server stopped ")
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy