KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/server/StarboundServer.kt
2024-02-10 16:49:58 +07:00

70 lines
1.6 KiB
Kotlin

package ru.dbotthepony.kstarbound.server
import ru.dbotthepony.kommons.util.MailboxExecutorService
import ru.dbotthepony.kstarbound.server.world.ServerWorld
import java.io.Closeable
import java.io.File
import java.util.Collections
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.locks.LockSupport
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
sealed class StarboundServer(val root: File) : Closeable {
init {
if (!root.exists()) {
check(root.mkdirs()) { "Unable to create ${root.absolutePath}" }
} else if (!root.isDirectory) {
throw IllegalArgumentException("${root.absolutePath} is not a directory")
}
}
val worlds: MutableList<ServerWorld> = Collections.synchronizedList(ArrayList<ServerWorld>())
val serverID = threadCounter.getAndIncrement()
val thread = Thread(::runThread, "Starbound Server $serverID")
val mailbox = MailboxExecutorService(thread)
val settings = ServerSettings()
val channels = ServerChannels(this)
val lock = ReentrantLock()
@Volatile
var isClosed = false
private set
init {
thread.isDaemon = this is IntegratedStarboundServer
thread.start()
}
fun playerInGame(player: ServerConnection) {
val world = worlds.first()
world.acceptPlayer(player)
}
protected abstract fun close0()
private fun runThread() {
while (!isClosed) {
mailbox.executeQueuedTasks()
LockSupport.park()
}
}
final override fun close() {
lock.withLock {
if (isClosed) return
channels.close()
worlds.forEach { it.close() }
close0()
LockSupport.unpark(thread)
}
}
companion object {
private val threadCounter = AtomicInteger()
}
}