Players now can place objects

This commit is contained in:
DBotThePony 2024-04-22 22:57:26 +07:00
parent ab516d91a9
commit 68ec91e1e8
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 27 additions and 19 deletions

View File

@ -43,7 +43,11 @@ class EntityCreatePacket(val entityType: EntityType, val storeData: ByteArrayLis
else -> null else -> null
} }
entity ?: return if (entity == null) {
connection.disconnect("Illegal entity type to be created as owned by client: $entityType")
return
}
entity.networkGroup.read(firstNetState, isLegacy = true) entity.networkGroup.read(firstNetState, isLegacy = true)
entity.entityID = entityID entity.entityID = entityID
entity.isRemote = true entity.isRemote = true

View File

@ -1,13 +1,18 @@
package ru.dbotthepony.kstarbound.network.packets.serverbound package ru.dbotthepony.kstarbound.network.packets.serverbound
import com.google.gson.JsonObject
import it.unimi.dsi.fastutil.bytes.ByteArrayList import it.unimi.dsi.fastutil.bytes.ByteArrayList
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
import ru.dbotthepony.kommons.io.readByteArray import ru.dbotthepony.kommons.io.readByteArray
import ru.dbotthepony.kommons.io.writeByteArray import ru.dbotthepony.kommons.io.writeByteArray
import ru.dbotthepony.kstarbound.Registries
import ru.dbotthepony.kstarbound.defs.EntityType import ru.dbotthepony.kstarbound.defs.EntityType
import ru.dbotthepony.kstarbound.io.readInternedString
import ru.dbotthepony.kstarbound.json.readJsonElement
import ru.dbotthepony.kstarbound.network.IServerPacket import ru.dbotthepony.kstarbound.network.IServerPacket
import ru.dbotthepony.kstarbound.server.ServerConnection import ru.dbotthepony.kstarbound.server.ServerConnection
import ru.dbotthepony.kstarbound.world.entities.ItemDropEntity import ru.dbotthepony.kstarbound.world.entities.ItemDropEntity
import ru.dbotthepony.kstarbound.world.entities.tile.WorldObject
import java.io.DataInputStream import java.io.DataInputStream
import java.io.DataOutputStream import java.io.DataOutputStream
@ -28,6 +33,21 @@ class SpawnEntityPacket(val entityType: EntityType, val storeData: ByteArrayList
override fun play(connection: ServerConnection) { override fun play(connection: ServerConnection) {
val entity = when (entityType) { val entity = when (entityType) {
EntityType.ITEM_DROP -> ItemDropEntity(DataInputStream(FastByteArrayInputStream(storeData.elements(), 0, storeData.size)), connection.isLegacy) EntityType.ITEM_DROP -> ItemDropEntity(DataInputStream(FastByteArrayInputStream(storeData.elements(), 0, storeData.size)), connection.isLegacy)
EntityType.OBJECT -> {
val stream = DataInputStream(FastByteArrayInputStream(storeData.elements(), 0, storeData.size))
val name = stream.readInternedString()
val parameters = stream.readJsonElement()
val config = Registries.worldObjects[name]
if (config == null) {
connection.disconnect("Unknown world object type $name!")
return
}
WorldObject.create(config, parameters = parameters as? JsonObject ?: JsonObject())
}
else -> null else -> null
} }

View File

@ -47,7 +47,6 @@ class NetworkedList<E>(
private val clearEntry = Entry<E>(Type.CLEAR, 0, KOptional()) private val clearEntry = Entry<E>(Type.CLEAR, 0, KOptional())
private var isInterpolating = false private var isInterpolating = false
private var isRemote = false
private val listeners = CopyOnWriteArrayList<Runnable>() private val listeners = CopyOnWriteArrayList<Runnable>()
fun addListener(listener: Runnable) { fun addListener(listener: Runnable) {
@ -85,7 +84,6 @@ class NetworkedList<E>(
} }
override fun readInitial(data: DataInputStream, isLegacy: Boolean) { override fun readInitial(data: DataInputStream, isLegacy: Boolean) {
isRemote = true
backlog.clear() backlog.clear()
backlog.add(currentVersion() to clearEntry) backlog.add(currentVersion() to clearEntry)
queue.clear() queue.clear()
@ -135,8 +133,6 @@ class NetworkedList<E>(
} }
override fun readDelta(data: DataInputStream, interpolationDelay: Double, isLegacy: Boolean) { override fun readDelta(data: DataInputStream, interpolationDelay: Double, isLegacy: Boolean) {
isRemote = true
if (isLegacy) { if (isLegacy) {
readInitial(data, true) readInitial(data, true)
} else { } else {
@ -249,7 +245,6 @@ class NetworkedList<E>(
} }
override fun add(index: Int, element: E) { override fun add(index: Int, element: E) {
check(!isRemote) { "List is not owned by this side" }
elements.add(index, element) elements.add(index, element)
backlog.add(currentVersion() to Entry(index, element)) backlog.add(currentVersion() to Entry(index, element))
purgeBacklog() purgeBacklog()
@ -267,7 +262,6 @@ class NetworkedList<E>(
} }
override fun clear() { override fun clear() {
check(!isRemote) { "List is not owned by this side" }
backlog.clear() backlog.clear()
backlog.add(currentVersion() to clearEntry) backlog.add(currentVersion() to clearEntry)
elements.clear() elements.clear()
@ -283,7 +277,6 @@ class NetworkedList<E>(
} }
override fun remove(element: E): Boolean { override fun remove(element: E): Boolean {
check(!isRemote) { "List is not owned by this side" }
val indexOf = elements.indexOf(element) val indexOf = elements.indexOf(element)
if (indexOf == -1) if (indexOf == -1)
@ -294,14 +287,12 @@ class NetworkedList<E>(
} }
override fun removeAll(elements: Collection<E>): Boolean { override fun removeAll(elements: Collection<E>): Boolean {
check(!isRemote) { "List is not owned by this side" }
var any = false var any = false
elements.forEach { any = remove(it) || any } elements.forEach { any = remove(it) || any }
return any return any
} }
override fun removeAt(index: Int): E { override fun removeAt(index: Int): E {
check(!isRemote) { "List is not owned by this side" }
val element = elements.removeAt(index) val element = elements.removeAt(index)
backlog.add(currentVersion() to Entry(index)) backlog.add(currentVersion() to Entry(index))
purgeBacklog() purgeBacklog()
@ -310,7 +301,6 @@ class NetworkedList<E>(
} }
override fun retainAll(elements: Collection<E>): Boolean { override fun retainAll(elements: Collection<E>): Boolean {
check(!isRemote) { "List is not owned by this side" }
val itr = iterator() val itr = iterator()
var modified = false var modified = false
@ -325,7 +315,6 @@ class NetworkedList<E>(
} }
override fun set(index: Int, element: E): E { override fun set(index: Int, element: E): E {
check(!isRemote) { "List is not owned by this side" }
val old = elements.set(index, element) val old = elements.set(index, element)
backlog.add(currentVersion() to Entry(index, element)) backlog.add(currentVersion() to Entry(index, element))
purgeBacklog() purgeBacklog()

View File

@ -51,7 +51,6 @@ class NetworkedMap<K, V>(
map.addListener(object : ListenableMap.MapListener<K, V> { map.addListener(object : ListenableMap.MapListener<K, V> {
override fun onClear() { override fun onClear() {
if (isReading > 0) return if (isReading > 0) return
check(!isRemote) { "This map is not owned by this side" }
// this is fragile (due to interpolation fuckery, we remove everything before applying delayed changes), // this is fragile (due to interpolation fuckery, we remove everything before applying delayed changes),
// but let's hope it doesn't break // but let's hope it doesn't break
@ -64,7 +63,6 @@ class NetworkedMap<K, V>(
override fun onValueAdded(key: K, value: V) { override fun onValueAdded(key: K, value: V) {
if (isReading > 0) return if (isReading > 0) return
check(!isRemote) { "This map is not owned by this side" }
backlog.add(currentVersion() to Entry(Action.ADD, KOptional(nativeKey.copy(key)), KOptional(nativeValue.copy(value)))) backlog.add(currentVersion() to Entry(Action.ADD, KOptional(nativeKey.copy(key)), KOptional(nativeValue.copy(value))))
purgeBacklog() purgeBacklog()
listeners.forEach { it.listener.onValueAdded(key, value) } listeners.forEach { it.listener.onValueAdded(key, value) }
@ -72,7 +70,6 @@ class NetworkedMap<K, V>(
override fun onValueRemoved(key: K, value: V) { override fun onValueRemoved(key: K, value: V) {
if (isReading > 0) return if (isReading > 0) return
check(!isRemote) { "This map is not owned by this side" }
backlog.add(currentVersion() to Entry(Action.REMOVE, KOptional(nativeKey.copy(key)), KOptional())) backlog.add(currentVersion() to Entry(Action.REMOVE, KOptional(nativeKey.copy(key)), KOptional()))
purgeBacklog() purgeBacklog()
listeners.forEach { it.listener.onValueRemoved(key, value) } listeners.forEach { it.listener.onValueRemoved(key, value) }
@ -176,7 +173,6 @@ class NetworkedMap<K, V>(
} }
private var isReading = 0 private var isReading = 0
private var isRemote = false
private var isInterpolating = false private var isInterpolating = false
val legacyKey get() = keyCodec.second val legacyKey get() = keyCodec.second
@ -196,7 +192,6 @@ class NetworkedMap<K, V>(
override fun readInitial(data: DataInputStream, isLegacy: Boolean) { override fun readInitial(data: DataInputStream, isLegacy: Boolean) {
try { try {
isRemote = true
isReading++ isReading++
backlog.clear() backlog.clear()

View File

@ -358,7 +358,7 @@ open class WorldObject(val config: Registry.Entry<ObjectDefinition>) : TileEntit
stream.writeBinaryString(config.key) stream.writeBinaryString(config.key)
stream.writeJsonElement(JsonObject().also { stream.writeJsonElement(JsonObject().also {
for ((k, v) in parameters) { for ((k, v) in parameters) {
it[k] = v.deepCopy() it[k] = v
} }
}) })
} }
@ -753,7 +753,7 @@ open class WorldObject(val config: Registry.Entry<ObjectDefinition>) : TileEntit
return result return result
} }
fun create(prototype: Registry.Entry<ObjectDefinition>, position: Vector2i, parameters: JsonObject = JsonObject()): WorldObject? { fun create(prototype: Registry.Entry<ObjectDefinition>, position: Vector2i = Vector2i.ZERO, parameters: JsonObject = JsonObject()): WorldObject? {
val result = when (prototype.value.objectType) { val result = when (prototype.value.objectType) {
ObjectType.OBJECT -> WorldObject(prototype) ObjectType.OBJECT -> WorldObject(prototype)
ObjectType.LOUNGEABLE -> LoungeableObject(prototype) ObjectType.LOUNGEABLE -> LoungeableObject(prototype)