70 lines
1.6 KiB
Kotlin
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()
|
|
}
|
|
}
|