Fix some bloppers
This commit is contained in:
parent
602c21edfc
commit
6df7710dc2
@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m
|
|||||||
|
|
||||||
kotlinVersion=1.9.10
|
kotlinVersion=1.9.10
|
||||||
kotlinCoroutinesVersion=1.8.0
|
kotlinCoroutinesVersion=1.8.0
|
||||||
kommonsVersion=2.10.2
|
kommonsVersion=2.11.0
|
||||||
|
|
||||||
ffiVersion=2.2.13
|
ffiVersion=2.2.13
|
||||||
lwjglVersion=3.3.0
|
lwjglVersion=3.3.0
|
||||||
|
@ -104,7 +104,7 @@ fun main() {
|
|||||||
|
|
||||||
Starbound.mailboxInitialized.submit {
|
Starbound.mailboxInitialized.submit {
|
||||||
val server = IntegratedStarboundServer(File("./"))
|
val server = IntegratedStarboundServer(File("./"))
|
||||||
//val world = ServerWorld.create(server, WorldGeometry(Vector2i(3000, 2000), true, false), LegacyWorldStorage.file(db))
|
val world = ServerWorld.load(server, LegacyWorldStorage.file(db)).get()
|
||||||
//world.thread.start()
|
//world.thread.start()
|
||||||
|
|
||||||
//ply = PlayerEntity(client.world!!)
|
//ply = PlayerEntity(client.world!!)
|
||||||
|
@ -244,7 +244,7 @@ object Registries {
|
|||||||
try {
|
try {
|
||||||
val json = Starbound.gson.getAdapter(JsonObject::class.java).read(JsonReader(listedFile.reader()).also { it.isLenient = true })
|
val json = Starbound.gson.getAdapter(JsonObject::class.java).read(JsonReader(listedFile.reader()).also { it.isLenient = true })
|
||||||
val name = json["name"]?.asString ?: throw JsonSyntaxException("Missing 'name' field")
|
val name = json["name"]?.asString ?: throw JsonSyntaxException("Missing 'name' field")
|
||||||
val factory = TerrainSelectorType.factory(json)
|
val factory = TerrainSelectorType.factory(json, false)
|
||||||
|
|
||||||
terrainSelectors.add {
|
terrainSelectors.add {
|
||||||
terrainSelectors.add(name, factory)
|
terrainSelectors.add(name, factory)
|
||||||
|
@ -58,6 +58,8 @@ import ru.dbotthepony.kstarbound.json.factory.SingletonTypeAdapterFactory
|
|||||||
import ru.dbotthepony.kstarbound.math.*
|
import ru.dbotthepony.kstarbound.math.*
|
||||||
import ru.dbotthepony.kstarbound.server.world.UniverseChunk
|
import ru.dbotthepony.kstarbound.server.world.UniverseChunk
|
||||||
import ru.dbotthepony.kstarbound.item.ItemStack
|
import ru.dbotthepony.kstarbound.item.ItemStack
|
||||||
|
import ru.dbotthepony.kstarbound.util.Directives
|
||||||
|
import ru.dbotthepony.kstarbound.util.ExceptionLogger
|
||||||
import ru.dbotthepony.kstarbound.util.SBPattern
|
import ru.dbotthepony.kstarbound.util.SBPattern
|
||||||
import ru.dbotthepony.kstarbound.util.HashTableInterner
|
import ru.dbotthepony.kstarbound.util.HashTableInterner
|
||||||
import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise
|
import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise
|
||||||
@ -104,10 +106,12 @@ object Starbound : ISBFileLocator {
|
|||||||
return if (USE_CAFFEINE_INTERNER) Interner.newWeakInterner() else HashTableInterner(bits)
|
return if (USE_CAFFEINE_INTERNER) Interner.newWeakInterner() else HashTableInterner(bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
|
||||||
val thread = Thread(::universeThread, "Starbound Universe")
|
val thread = Thread(::universeThread, "Starbound Universe")
|
||||||
val mailbox = MailboxExecutorService(thread)
|
val mailbox = MailboxExecutorService(thread).also { it.exceptionHandler = ExceptionLogger(LOGGER) }
|
||||||
val mailboxBootstrapped = MailboxExecutorService(thread)
|
val mailboxBootstrapped = MailboxExecutorService(thread).also { it.exceptionHandler = ExceptionLogger(LOGGER) }
|
||||||
val mailboxInitialized = MailboxExecutorService(thread)
|
val mailboxInitialized = MailboxExecutorService(thread).also { it.exceptionHandler = ExceptionLogger(LOGGER) }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
thread.isDaemon = true
|
thread.isDaemon = true
|
||||||
@ -121,6 +125,11 @@ object Starbound : ISBFileLocator {
|
|||||||
val thread = Thread(it, "Starbound Storage IO ${ioPoolCounter.getAndIncrement()}")
|
val thread = Thread(it, "Starbound Storage IO ${ioPoolCounter.getAndIncrement()}")
|
||||||
thread.isDaemon = true
|
thread.isDaemon = true
|
||||||
thread.priority = Thread.MIN_PRIORITY
|
thread.priority = Thread.MIN_PRIORITY
|
||||||
|
|
||||||
|
thread.uncaughtExceptionHandler = Thread.UncaughtExceptionHandler { t, e ->
|
||||||
|
LOGGER.error("I/O thread died due to uncaught exception", e)
|
||||||
|
}
|
||||||
|
|
||||||
return@ThreadFactory thread
|
return@ThreadFactory thread
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -146,8 +155,6 @@ object Starbound : ISBFileLocator {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val STRINGS: Interner<String> = interner(5)
|
val STRINGS: Interner<String> = interner(5)
|
||||||
|
|
||||||
private val LOGGER = LogManager.getLogger()
|
|
||||||
|
|
||||||
val gson: Gson = with(GsonBuilder()) {
|
val gson: Gson = with(GsonBuilder()) {
|
||||||
serializeNulls()
|
serializeNulls()
|
||||||
setDateFormat(DateFormat.LONG)
|
setDateFormat(DateFormat.LONG)
|
||||||
@ -236,6 +243,8 @@ object Starbound : ISBFileLocator {
|
|||||||
registerTypeAdapterFactory(ThingDescription.Factory(STRINGS))
|
registerTypeAdapterFactory(ThingDescription.Factory(STRINGS))
|
||||||
registerTypeAdapterFactory(TerrainSelectorType.Companion)
|
registerTypeAdapterFactory(TerrainSelectorType.Companion)
|
||||||
|
|
||||||
|
registerTypeAdapter(Directives.Companion)
|
||||||
|
|
||||||
registerTypeAdapter(EnumAdapter(DamageType::class, default = DamageType.DAMAGE))
|
registerTypeAdapter(EnumAdapter(DamageType::class, default = DamageType.DAMAGE))
|
||||||
|
|
||||||
registerTypeAdapter(InventoryIcon.Companion)
|
registerTypeAdapter(InventoryIcon.Companion)
|
||||||
|
@ -62,6 +62,8 @@ import ru.dbotthepony.kstarbound.client.world.ClientWorld
|
|||||||
import ru.dbotthepony.kstarbound.defs.image.Image
|
import ru.dbotthepony.kstarbound.defs.image.Image
|
||||||
import ru.dbotthepony.kstarbound.math.roundTowardsNegativeInfinity
|
import ru.dbotthepony.kstarbound.math.roundTowardsNegativeInfinity
|
||||||
import ru.dbotthepony.kstarbound.math.roundTowardsPositiveInfinity
|
import ru.dbotthepony.kstarbound.math.roundTowardsPositiveInfinity
|
||||||
|
import ru.dbotthepony.kstarbound.server.StarboundServer
|
||||||
|
import ru.dbotthepony.kstarbound.util.ExceptionLogger
|
||||||
import ru.dbotthepony.kstarbound.util.ExecutionSpinner
|
import ru.dbotthepony.kstarbound.util.ExecutionSpinner
|
||||||
import ru.dbotthepony.kstarbound.util.formatBytesShort
|
import ru.dbotthepony.kstarbound.util.formatBytesShort
|
||||||
import ru.dbotthepony.kstarbound.world.Direction
|
import ru.dbotthepony.kstarbound.world.Direction
|
||||||
@ -117,7 +119,7 @@ class StarboundClient private constructor(val clientID: Int) : Closeable {
|
|||||||
}
|
}
|
||||||
}, null, false)
|
}, null, false)
|
||||||
|
|
||||||
val mailbox = MailboxExecutorService(thread)
|
val mailbox = MailboxExecutorService(thread).also { it.exceptionHandler = ExceptionLogger(LOGGER) }
|
||||||
val capabilities: GLCapabilities
|
val capabilities: GLCapabilities
|
||||||
|
|
||||||
var viewportX: Int = 0
|
var viewportX: Int = 0
|
||||||
|
@ -116,7 +116,7 @@ class Parallax(
|
|||||||
|
|
||||||
return Layer(
|
return Layer(
|
||||||
parallaxValue = parallax.map({ Vector2d(it, it) }, { it }),
|
parallaxValue = parallax.map({ Vector2d(it, it) }, { it }),
|
||||||
repeat = repeatX to repeatY,
|
repeat = Either.left(repeatX to repeatY),
|
||||||
tileLimitTop = tileLimitTop,
|
tileLimitTop = tileLimitTop,
|
||||||
tileLimitBottom = tileLimitBottom,
|
tileLimitBottom = tileLimitBottom,
|
||||||
verticalOrigin = verticalOrigin,
|
verticalOrigin = verticalOrigin,
|
||||||
@ -138,9 +138,9 @@ class Parallax(
|
|||||||
data class Layer(
|
data class Layer(
|
||||||
var directives: Directives,
|
var directives: Directives,
|
||||||
val textures: ImmutableList<String>,
|
val textures: ImmutableList<String>,
|
||||||
val alpha: Double,
|
val alpha: Double = 1.0,
|
||||||
val parallaxValue: Vector2d,
|
val parallaxValue: Vector2d,
|
||||||
val repeat: Pair<Boolean, Boolean>,
|
val repeat: Either<Pair<Boolean, Boolean>, Pair<Int, Int>>,
|
||||||
val tileLimitTop: Double? = null,
|
val tileLimitTop: Double? = null,
|
||||||
val tileLimitBottom: Double? = null,
|
val tileLimitBottom: Double? = null,
|
||||||
val verticalOrigin: Double,
|
val verticalOrigin: Double,
|
||||||
|
@ -9,6 +9,7 @@ import ru.dbotthepony.kstarbound.network.packets.clientbound.UniverseTimeUpdateP
|
|||||||
import ru.dbotthepony.kstarbound.server.world.ServerUniverse
|
import ru.dbotthepony.kstarbound.server.world.ServerUniverse
|
||||||
import ru.dbotthepony.kstarbound.server.world.ServerWorld
|
import ru.dbotthepony.kstarbound.server.world.ServerWorld
|
||||||
import ru.dbotthepony.kstarbound.util.Clock
|
import ru.dbotthepony.kstarbound.util.Clock
|
||||||
|
import ru.dbotthepony.kstarbound.util.ExceptionLogger
|
||||||
import ru.dbotthepony.kstarbound.util.ExecutionSpinner
|
import ru.dbotthepony.kstarbound.util.ExecutionSpinner
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -30,7 +31,7 @@ sealed class StarboundServer(val root: File) : Closeable {
|
|||||||
val worlds: MutableList<ServerWorld> = Collections.synchronizedList(ArrayList<ServerWorld>())
|
val worlds: MutableList<ServerWorld> = Collections.synchronizedList(ArrayList<ServerWorld>())
|
||||||
|
|
||||||
val serverID = threadCounter.getAndIncrement()
|
val serverID = threadCounter.getAndIncrement()
|
||||||
val mailbox = MailboxExecutorService()
|
val mailbox = MailboxExecutorService().also { it.exceptionHandler = ExceptionLogger(LOGGER) }
|
||||||
val spinner = ExecutionSpinner(mailbox::executeQueuedTasks, ::spin, Starbound.TIMESTEP_NANOS)
|
val spinner = ExecutionSpinner(mailbox::executeQueuedTasks, ::spin, Starbound.TIMESTEP_NANOS)
|
||||||
val thread = Thread(spinner, "Starbound Server $serverID")
|
val thread = Thread(spinner, "Starbound Server $serverID")
|
||||||
val universe = ServerUniverse()
|
val universe = ServerUniverse()
|
||||||
|
@ -21,6 +21,7 @@ import ru.dbotthepony.kstarbound.network.packets.clientbound.CentralStructureUpd
|
|||||||
import ru.dbotthepony.kstarbound.network.packets.clientbound.WorldStartPacket
|
import ru.dbotthepony.kstarbound.network.packets.clientbound.WorldStartPacket
|
||||||
import ru.dbotthepony.kstarbound.server.StarboundServer
|
import ru.dbotthepony.kstarbound.server.StarboundServer
|
||||||
import ru.dbotthepony.kstarbound.server.ServerConnection
|
import ru.dbotthepony.kstarbound.server.ServerConnection
|
||||||
|
import ru.dbotthepony.kstarbound.util.AssetPathStack
|
||||||
import ru.dbotthepony.kstarbound.util.ExecutionSpinner
|
import ru.dbotthepony.kstarbound.util.ExecutionSpinner
|
||||||
import ru.dbotthepony.kstarbound.world.ChunkPos
|
import ru.dbotthepony.kstarbound.world.ChunkPos
|
||||||
import ru.dbotthepony.kstarbound.world.IChunkListener
|
import ru.dbotthepony.kstarbound.world.IChunkListener
|
||||||
@ -483,15 +484,17 @@ class ServerWorld private constructor(
|
|||||||
|
|
||||||
fun load(server: StarboundServer, storage: WorldStorage): CompletableFuture<ServerWorld> {
|
fun load(server: StarboundServer, storage: WorldStorage): CompletableFuture<ServerWorld> {
|
||||||
return storage.loadMetadata().thenApply {
|
return storage.loadMetadata().thenApply {
|
||||||
val meta = it.map { Starbound.gson.fromJson(it.data.content, MetadataJson::class.java) }.orThrow { NoSuchElementException("No world metadata is present") }
|
AssetPathStack("/") { _ ->
|
||||||
|
val meta = it.map { Starbound.gson.fromJson(it.data.content, MetadataJson::class.java) }.orThrow { NoSuchElementException("No world metadata is present") }
|
||||||
|
|
||||||
val world = create(server, WorldTemplate.fromJson(meta.worldTemplate), storage)
|
val world = create(server, WorldTemplate.fromJson(meta.worldTemplate), storage)
|
||||||
world.playerSpawnPosition = meta.playerStart
|
world.playerSpawnPosition = meta.playerStart
|
||||||
world.respawnInWorld = meta.respawnInWorld
|
world.respawnInWorld = meta.respawnInWorld
|
||||||
world.adjustPlayerSpawn = meta.adjustPlayerStart
|
world.adjustPlayerSpawn = meta.adjustPlayerStart
|
||||||
world.centralStructure = meta.centralStructure
|
world.centralStructure = meta.centralStructure
|
||||||
world.protectedDungeonIDs.addAll(meta.protectedDungeonIds)
|
world.protectedDungeonIDs.addAll(meta.protectedDungeonIds)
|
||||||
world
|
world
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package ru.dbotthepony.kstarbound.util
|
package ru.dbotthepony.kstarbound.util
|
||||||
|
|
||||||
|
import com.google.gson.TypeAdapter
|
||||||
|
import com.google.gson.stream.JsonReader
|
||||||
|
import com.google.gson.stream.JsonWriter
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap
|
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap
|
import it.unimi.dsi.fastutil.objects.Object2ObjectMap
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps
|
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps
|
||||||
|
import ru.dbotthepony.kommons.gson.consumeNull
|
||||||
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
|
|
||||||
class Directives private constructor(private val directivesInternal: Object2ObjectAVLTreeMap<String, String>) {
|
class Directives private constructor(private val directivesInternal: Object2ObjectAVLTreeMap<String, String>) {
|
||||||
constructor() : this(Object2ObjectAVLTreeMap())
|
constructor() : this(Object2ObjectAVLTreeMap())
|
||||||
@ -14,8 +19,8 @@ class Directives private constructor(private val directivesInternal: Object2Obje
|
|||||||
}
|
}
|
||||||
|
|
||||||
// assume it is just "name=value"
|
// assume it is just "name=value"
|
||||||
val key = directives.substringBefore('=')
|
val key = Starbound.STRINGS.intern(directives.substringBefore('='))
|
||||||
val value = directives.substringAfter('=')
|
val value = Starbound.STRINGS.intern(directives.substringAfter('='))
|
||||||
directivesInternal[key] = value
|
directivesInternal[key] = value
|
||||||
} else {
|
} else {
|
||||||
// gets interesting
|
// gets interesting
|
||||||
@ -24,8 +29,8 @@ class Directives private constructor(private val directivesInternal: Object2Obje
|
|||||||
throw IllegalArgumentException("Missing render directive delimiter in '$pair' (full string: '$directives')")
|
throw IllegalArgumentException("Missing render directive delimiter in '$pair' (full string: '$directives')")
|
||||||
}
|
}
|
||||||
|
|
||||||
val key = pair.substringBefore('=')
|
val key = Starbound.STRINGS.intern(pair.substringBefore('='))
|
||||||
val value = pair.substringAfter('=')
|
val value = Starbound.STRINGS.intern(pair.substringAfter('='))
|
||||||
directivesInternal[key] = value
|
directivesInternal[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,7 +43,14 @@ class Directives private constructor(private val directivesInternal: Object2Obje
|
|||||||
if (directivesInternal.isEmpty())
|
if (directivesInternal.isEmpty())
|
||||||
return "Directives[empty]"
|
return "Directives[empty]"
|
||||||
else
|
else
|
||||||
return "Directives[?${directivesInternal.entries.joinToString("?") { "${it.key}=${it.value}" }}]"
|
return "Directives[$directivesString]"
|
||||||
|
}
|
||||||
|
|
||||||
|
val directivesString by lazy {
|
||||||
|
if (directivesInternal.isEmpty())
|
||||||
|
""
|
||||||
|
else
|
||||||
|
"?${directivesInternal.entries.joinToString("?") { "${it.key}=${it.value}" }}"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
@ -65,8 +77,8 @@ class Directives private constructor(private val directivesInternal: Object2Obje
|
|||||||
}
|
}
|
||||||
|
|
||||||
// assume it is just "name=value"
|
// assume it is just "name=value"
|
||||||
val key = directives.substringBefore('=')
|
val key = Starbound.STRINGS.intern(directives.substringBefore('='))
|
||||||
val value = directives.substringAfter('=')
|
val value = Starbound.STRINGS.intern(directives.substringAfter('='))
|
||||||
return add(key, value)
|
return add(key, value)
|
||||||
} else {
|
} else {
|
||||||
// gets interesting
|
// gets interesting
|
||||||
@ -82,12 +94,28 @@ class Directives private constructor(private val directivesInternal: Object2Obje
|
|||||||
throw IllegalArgumentException("Missing render directive delimiter in '$pair' (full string: $directives)")
|
throw IllegalArgumentException("Missing render directive delimiter in '$pair' (full string: $directives)")
|
||||||
}
|
}
|
||||||
|
|
||||||
val key = pair.substringBefore('=')
|
val key = Starbound.STRINGS.intern(pair.substringBefore('='))
|
||||||
val value = pair.substringAfter('=')
|
val value = Starbound.STRINGS.intern(pair.substringAfter('='))
|
||||||
copy[key] = value
|
copy[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
return Directives(copy)
|
return Directives(copy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object : TypeAdapter<Directives>() {
|
||||||
|
override fun write(out: JsonWriter, value: Directives?) {
|
||||||
|
if (value == null)
|
||||||
|
out.nullValue()
|
||||||
|
else
|
||||||
|
out.value(value.directivesString)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(`in`: JsonReader): Directives? {
|
||||||
|
if (`in`.consumeNull())
|
||||||
|
return null
|
||||||
|
|
||||||
|
return Directives(`in`.nextString())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package ru.dbotthepony.kstarbound.util
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class ExceptionLogger(private val logger: Logger) : Consumer<Throwable> {
|
||||||
|
override fun accept(t: Throwable) {
|
||||||
|
logger.error("Error while executing queued task", t)
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.ints.IntArraySet
|
|||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.kommons.arrays.Object2DArray
|
import ru.dbotthepony.kommons.arrays.Object2DArray
|
||||||
import ru.dbotthepony.kommons.collect.filterNotNull
|
import ru.dbotthepony.kommons.collect.filterNotNull
|
||||||
import ru.dbotthepony.kommons.util.IStruct2d
|
import ru.dbotthepony.kommons.util.IStruct2d
|
||||||
@ -19,6 +20,8 @@ import ru.dbotthepony.kstarbound.defs.world.WorldTemplate
|
|||||||
import ru.dbotthepony.kstarbound.math.*
|
import ru.dbotthepony.kstarbound.math.*
|
||||||
import ru.dbotthepony.kstarbound.network.IPacket
|
import ru.dbotthepony.kstarbound.network.IPacket
|
||||||
import ru.dbotthepony.kstarbound.network.packets.clientbound.SetPlayerStartPacket
|
import ru.dbotthepony.kstarbound.network.packets.clientbound.SetPlayerStartPacket
|
||||||
|
import ru.dbotthepony.kstarbound.server.StarboundServer
|
||||||
|
import ru.dbotthepony.kstarbound.util.ExceptionLogger
|
||||||
import ru.dbotthepony.kstarbound.util.ParallelPerform
|
import ru.dbotthepony.kstarbound.util.ParallelPerform
|
||||||
import ru.dbotthepony.kstarbound.world.api.ICellAccess
|
import ru.dbotthepony.kstarbound.world.api.ICellAccess
|
||||||
import ru.dbotthepony.kstarbound.world.api.AbstractCell
|
import ru.dbotthepony.kstarbound.world.api.AbstractCell
|
||||||
@ -42,7 +45,7 @@ import java.util.stream.Stream
|
|||||||
abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, ChunkType>>(val template: WorldTemplate) : ICellAccess, Closeable {
|
abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, ChunkType>>(val template: WorldTemplate) : ICellAccess, Closeable {
|
||||||
val background = TileView.Background(this)
|
val background = TileView.Background(this)
|
||||||
val foreground = TileView.Foreground(this)
|
val foreground = TileView.Foreground(this)
|
||||||
val mailbox = MailboxExecutorService()
|
val mailbox = MailboxExecutorService().also { it.exceptionHandler = ExceptionLogger(LOGGER) }
|
||||||
val sky = Sky()
|
val sky = Sky()
|
||||||
val geometry: WorldGeometry = template.geometry
|
val geometry: WorldGeometry = template.geometry
|
||||||
|
|
||||||
@ -330,4 +333,8 @@ abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, Chun
|
|||||||
fun gravityAt(pos: IStruct2d): Vector2d {
|
fun gravityAt(pos: IStruct2d): Vector2d {
|
||||||
return gravity
|
return gravity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ru.dbotthepony.kstarbound.world.entities
|
package ru.dbotthepony.kstarbound.world.entities
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.kommons.util.MailboxExecutorService
|
import ru.dbotthepony.kommons.util.MailboxExecutorService
|
||||||
import ru.dbotthepony.kommons.vector.Vector2d
|
import ru.dbotthepony.kommons.vector.Vector2d
|
||||||
import ru.dbotthepony.kstarbound.Starbound
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
@ -11,12 +12,15 @@ import ru.dbotthepony.kstarbound.defs.JsonDriven
|
|||||||
import ru.dbotthepony.kstarbound.network.packets.EntityDestroyPacket
|
import ru.dbotthepony.kstarbound.network.packets.EntityDestroyPacket
|
||||||
import ru.dbotthepony.kstarbound.network.syncher.MasterElement
|
import ru.dbotthepony.kstarbound.network.syncher.MasterElement
|
||||||
import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup
|
import ru.dbotthepony.kstarbound.network.syncher.NetworkedGroup
|
||||||
|
import ru.dbotthepony.kstarbound.server.StarboundServer
|
||||||
|
import ru.dbotthepony.kstarbound.util.ExceptionLogger
|
||||||
import ru.dbotthepony.kstarbound.world.Chunk
|
import ru.dbotthepony.kstarbound.world.Chunk
|
||||||
import ru.dbotthepony.kstarbound.world.ChunkPos
|
import ru.dbotthepony.kstarbound.world.ChunkPos
|
||||||
import ru.dbotthepony.kstarbound.world.LightCalculator
|
import ru.dbotthepony.kstarbound.world.LightCalculator
|
||||||
import ru.dbotthepony.kstarbound.world.World
|
import ru.dbotthepony.kstarbound.world.World
|
||||||
import ru.dbotthepony.kstarbound.world.entities.player.PlayerEntity
|
import ru.dbotthepony.kstarbound.world.entities.player.PlayerEntity
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
|
import java.util.function.Consumer
|
||||||
import kotlin.concurrent.withLock
|
import kotlin.concurrent.withLock
|
||||||
|
|
||||||
abstract class AbstractEntity(path: String) : JsonDriven(path) {
|
abstract class AbstractEntity(path: String) : JsonDriven(path) {
|
||||||
@ -67,7 +71,11 @@ abstract class AbstractEntity(path: String) : JsonDriven(path) {
|
|||||||
var connectionID: Int = 0
|
var connectionID: Int = 0
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var mailbox = MailboxExecutorService()
|
private val exceptionLogger = Consumer<Throwable> {
|
||||||
|
LOGGER.error("Error while executing queued task on $this", it)
|
||||||
|
}
|
||||||
|
|
||||||
|
var mailbox = MailboxExecutorService().also { it.exceptionHandler = exceptionLogger }
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private var innerWorld: World<*, *>? = null
|
private var innerWorld: World<*, *>? = null
|
||||||
@ -117,7 +125,7 @@ abstract class AbstractEntity(path: String) : JsonDriven(path) {
|
|||||||
check(!world.entities.containsKey(entityID)) { "Duplicate entity ID: $entityID" }
|
check(!world.entities.containsKey(entityID)) { "Duplicate entity ID: $entityID" }
|
||||||
|
|
||||||
if (mailbox.isShutdown)
|
if (mailbox.isShutdown)
|
||||||
mailbox = MailboxExecutorService()
|
mailbox = MailboxExecutorService().also { it.exceptionHandler = exceptionLogger }
|
||||||
|
|
||||||
innerWorld = world
|
innerWorld = world
|
||||||
world.entities[entityID] = this
|
world.entities[entityID] = this
|
||||||
@ -169,4 +177,8 @@ abstract class AbstractEntity(path: String) : JsonDriven(path) {
|
|||||||
open fun addLights(lightCalculator: LightCalculator, xOffset: Int, yOffset: Int) {
|
open fun addLights(lightCalculator: LightCalculator, xOffset: Int, yOffset: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class RotateTerrainSelector(data: Data, parameters: TerrainSelectorParameters) :
|
|||||||
val source: JsonObject,
|
val source: JsonObject,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val source = TerrainSelectorType.create(data.source)
|
private val source = TerrainSelectorType.create(data.source, parameters)
|
||||||
private val deltaX = parameters.worldWidth * data.rotationWidth
|
private val deltaX = parameters.worldWidth * data.rotationWidth
|
||||||
private val deltaY = parameters.worldHeight * data.rotationHeight
|
private val deltaY = parameters.worldHeight * data.rotationHeight
|
||||||
|
|
||||||
|
@ -72,27 +72,41 @@ enum class TerrainSelectorType(val jsonName: String, private val data: Data<*, *
|
|||||||
if (`in`.consumeNull())
|
if (`in`.consumeNull())
|
||||||
return null
|
return null
|
||||||
|
|
||||||
return create(objects.read(`in`))
|
return load(objects.read(`in`))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun factory(json: JsonObject): Factory<*, *> {
|
fun factory(json: JsonObject, isSerializedForm: Boolean): Factory<*, *> {
|
||||||
val type = json["type"]?.asString?.lowercase() ?: throw JsonSyntaxException("Missing 'type' element of terrain json")
|
val type = json["type"]?.asString?.lowercase() ?: throw JsonSyntaxException("Missing 'type' element of terrain json")
|
||||||
|
|
||||||
for (value in entries) {
|
if (isSerializedForm) {
|
||||||
if (value.lowercase == type) {
|
val config = json["config"]?.asJsonObject ?: throw JsonSyntaxException("Missing 'config' element of terrain json")
|
||||||
return Factory(value.data.adapter.fromJsonTree(json), value.data.factory as ((Any, TerrainSelectorParameters) -> AbstractTerrainSelector<Any>))
|
|
||||||
|
for (value in entries) {
|
||||||
|
if (value.lowercase == type) {
|
||||||
|
return Factory(value.data.adapter.fromJsonTree(config), value.data.factory as ((Any, TerrainSelectorParameters) -> AbstractTerrainSelector<Any>))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (value in entries) {
|
||||||
|
if (value.lowercase == type) {
|
||||||
|
return Factory(value.data.adapter.fromJsonTree(json), value.data.factory as ((Any, TerrainSelectorParameters) -> AbstractTerrainSelector<Any>))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw IllegalArgumentException("Unknown terrain selector type $type")
|
throw IllegalArgumentException("Unknown terrain selector type $type")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(json: JsonObject): AbstractTerrainSelector<*> {
|
fun create(json: JsonObject, parameters: TerrainSelectorParameters): AbstractTerrainSelector<*> {
|
||||||
return factory(json).create(Starbound.gson.fromJson(json["parameters"] ?: throw JsonSyntaxException("Missing 'parameters' element of terrain json"), TerrainSelectorParameters::class.java))
|
return factory(json, false).create(parameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(json: JsonObject, parameters: TerrainSelectorParameters): AbstractTerrainSelector<*> {
|
fun load(json: JsonObject): AbstractTerrainSelector<*> {
|
||||||
return factory(json).create(parameters)
|
return factory(json, true).create(Starbound.gson.fromJson(json["parameters"] ?: throw JsonSyntaxException("Missing 'parameters' element of terrain json"), TerrainSelectorParameters::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load(json: JsonObject, parameters: TerrainSelectorParameters): AbstractTerrainSelector<*> {
|
||||||
|
return factory(json, true).create(parameters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user