Separate networked fields in mattery player to private and public

This commit is contained in:
DBotThePony 2022-10-21 17:06:38 +07:00
parent 286174d8a7
commit 13802c0cb2
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 61 additions and 14 deletions

View File

@ -41,7 +41,7 @@ abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: Matt
} }
open fun applyNetworkPayload(stream: InputStream) { open fun applyNetworkPayload(stream: InputStream) {
synchronizer.applyNetworkPayload(DataInputStream(stream)) synchronizer.applyNetworkPayload(stream)
} }
override fun serializeNBT(): CompoundTag { override fun serializeNBT(): CompoundTag {

View File

@ -192,7 +192,7 @@ class AndroidResearch(val type: AndroidResearchType, val capability: MatteryPlay
} }
fun applyNetworkPayload(stream: InputStream) { fun applyNetworkPayload(stream: InputStream) {
synchronizer.applyNetworkPayload(DataInputStream(stream)) synchronizer.applyNetworkPayload(stream)
} }
val canResearch: Boolean get() { val canResearch: Boolean get() {

View File

@ -75,9 +75,21 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
} }
} }
/**
* For fields that need to be synchronized only to owning player
*/
val synchronizer = FieldSynchronizer() val synchronizer = FieldSynchronizer()
var hasExoSuit by synchronizer.bool() /**
* For fields that need to be synchronized to everyone
*/
val publicSynchronizer = FieldSynchronizer()
init {
publicSynchronizer.defaultEndpoint.markUnused()
}
var hasExoSuit by publicSynchronizer.bool()
private val exoSuitSlotCountModifiersMap: MutableMap<UUID, Int> by synchronizer.Map( private val exoSuitSlotCountModifiersMap: MutableMap<UUID, Int> by synchronizer.Map(
keyCodec = UUIDValueCodec, keyCodec = UUIDValueCodec,
@ -99,7 +111,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
} }
}, backingMap = this.exoSuitSlotCountModifiersMap) }, backingMap = this.exoSuitSlotCountModifiersMap)
var exoSuitSlotCount by synchronizer.int(setter = setter@{ value, access, _ -> var exoSuitSlotCount by publicSynchronizer.int(setter = setter@{ value, access, _ ->
require(value >= 0) { "Invalid slot count $value" } require(value >= 0) { "Invalid slot count $value" }
if (value != access.read()) { if (value != access.read()) {
@ -113,7 +125,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
private set(value) { private set(value) {
_exoSuitMenu = null _exoSuitMenu = null
@Suppress("SENSELESS_COMPARISON") @Suppress("SENSELESS_COMPARISON") // false positive - fields of player can easily be nulls, despite annotations saying otherwise
if (ply.containerMenu != null && (ply !is ServerPlayer || ply.connection != null)) { if (ply.containerMenu != null && (ply !is ServerPlayer || ply.connection != null)) {
ply.closeContainer() ply.closeContainer()
} }
@ -131,7 +143,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
field = value field = value
} }
var isExoSuitCraftingUpgraded by synchronizer.bool(setter = setter@{ value, access, _ -> var isExoSuitCraftingUpgraded by publicSynchronizer.bool(setter = setter@{ value, access, _ ->
if (value != access.read()) { if (value != access.read()) {
access.write(value) access.write(value)
_exoSuitMenu = null _exoSuitMenu = null
@ -177,8 +189,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
var ticksIExist = 0 var ticksIExist = 0
private set private set
var willBecomeAndroid by synchronizer.bool() var willBecomeAndroid by publicSynchronizer.bool()
var isAndroid by synchronizer.bool() var isAndroid by publicSynchronizer.bool()
val androidEnergy = AndroidPowerSource(ply, synchronizer, ServerConfig.ANDROID_MAX_ENERGY, ServerConfig.ANDROID_MAX_ENERGY) val androidEnergy = AndroidPowerSource(ply, synchronizer, ServerConfig.ANDROID_MAX_ENERGY, ServerConfig.ANDROID_MAX_ENERGY)
@ -636,6 +648,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
if (invalidateNetworkIn > 0 && --invalidateNetworkIn == 0) { if (invalidateNetworkIn > 0 && --invalidateNetworkIn == 0) {
synchronizer.invalidate() synchronizer.invalidate()
publicSynchronizer.invalidate()
for (instance in research.values) { for (instance in research.values) {
instance.invalidateNetwork() instance.invalidateNetwork()
@ -655,7 +668,16 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
val payload = synchronizer.collectNetworkPayload() val payload = synchronizer.collectNetworkPayload()
if (payload != null) { if (payload != null) {
MatteryPlayerNetworkChannel.send(ply, MatteryPlayerFieldPacket(payload)) MatteryPlayerNetworkChannel.send(ply, MatteryPlayerFieldPacket(payload, false))
}
for (ply in MINECRAFT_SERVER.playerList.players) {
val endpoint = publicSynchronizer.computeEndpointFor(ply)
val payload2 = endpoint.collectNetworkPayload()
if (payload2 != null) {
MatteryPlayerNetworkChannel.send(ply, MatteryPlayerFieldPacket(payload2, true, this.ply.uuid))
}
} }
if (networkQueue.size != 0) { if (networkQueue.size != 0) {

View File

@ -22,6 +22,7 @@ import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.android.feature.TriggerJumpBoostPacket import ru.dbotthepony.mc.otm.android.feature.TriggerJumpBoostPacket
import ru.dbotthepony.mc.otm.android.feature.TriggerShockwavePacket import ru.dbotthepony.mc.otm.android.feature.TriggerShockwavePacket
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.MatteryGUI import ru.dbotthepony.mc.otm.client.MatteryGUI
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
@ -35,27 +36,51 @@ import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
import ru.dbotthepony.mc.otm.registry.AndroidFeatures import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.util.UUID
import java.util.function.Supplier import java.util.function.Supplier
class MatteryPlayerFieldPacket(val bytes: ByteArray, val length: Int) : MatteryPacket { class MatteryPlayerFieldPacket(val bytes: ByteArray, val length: Int, val isPublic: Boolean, val target: UUID? = null) : MatteryPacket {
constructor(stream: FastByteArrayOutputStream) : this(stream.array, stream.length) constructor(stream: FastByteArrayOutputStream, isPublic: Boolean, target: UUID? = null) : this(stream.array, stream.length, isPublic, target)
override fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeBoolean(target != null)
if (target != null)
buff.writeUUID(target)
buff.writeBoolean(isPublic)
buff.writeBytes(bytes, 0, length) buff.writeBytes(bytes, 0, length)
} }
override fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true context.packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
val player = minecraft.player?.matteryPlayer ?: return@enqueueWork val player: MatteryPlayerCapability
if (target != null) {
player = minecraft.level?.players()?.firstOrNull { it.uuid == target }?.matteryPlayer ?: return@enqueueWork
} else {
player = minecraft.player?.matteryPlayer ?: return@enqueueWork
}
if (isPublic) {
player.publicSynchronizer.applyNetworkPayload(ByteArrayInputStream(bytes, 0, length))
} else {
player.synchronizer.applyNetworkPayload(ByteArrayInputStream(bytes, 0, length)) player.synchronizer.applyNetworkPayload(ByteArrayInputStream(bytes, 0, length))
} }
} }
}
companion object { companion object {
fun read(buff: FriendlyByteBuf): MatteryPlayerFieldPacket { fun read(buff: FriendlyByteBuf): MatteryPlayerFieldPacket {
val target = if (buff.readBoolean())
buff.readUUID()
else
null
val isPublic = buff.readBoolean()
val readable = buff.readableBytes() val readable = buff.readableBytes()
return MatteryPlayerFieldPacket(ByteArray(readable).also(buff::readBytes), readable) return MatteryPlayerFieldPacket(ByteArray(readable).also(buff::readBytes), readable, isPublic, target)
} }
} }
} }