Unify client configuration packets

This commit is contained in:
Shadowfacts 2021-03-02 22:32:30 -05:00
parent 3cd4a7aa0d
commit 2958fa295a
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
15 changed files with 94 additions and 193 deletions

View File

@ -26,10 +26,7 @@ object PhysicalConnectivity: ModInitializer {
registerGlobalReceiver(C2STerminalRequestItem)
registerGlobalReceiver(C2STerminalUpdateDisplayedItems)
registerGlobalReceiver(C2SConfigureActivationMode)
registerGlobalReceiver(C2SConfigureRedstoneController)
registerGlobalReceiver(C2SConfigureInserterAmount)
registerGlobalReceiver(C2SConfigureRedstoneEmitterAmount)
registerGlobalReceiver(C2SConfigureDevice)
}
private fun registerGlobalReceiver(receiver: ServerReceiver) {

View File

@ -19,6 +19,7 @@ import net.shadowfacts.phycon.packet.CapacityPacket
import net.shadowfacts.phycon.packet.ItemStackPacket
import net.shadowfacts.phycon.packet.RemoteActivationPacket
import net.shadowfacts.phycon.util.ActivationMode
import net.shadowfacts.phycon.util.ClientConfigurableDevice
import kotlin.properties.Delegates
/**
@ -26,7 +27,8 @@ import kotlin.properties.Delegates
*/
class ExtractorBlockEntity: DeviceBlockEntity(PhyBlockEntities.EXTRACTOR),
NetworkStackDispatcher<ExtractorBlockEntity.PendingInsertion>,
ActivationController.ActivatableDevice {
ActivationController.ActivatableDevice,
ClientConfigurableDevice {
companion object {
val SLEEP_TIME = 40L
@ -101,11 +103,19 @@ class ExtractorBlockEntity: DeviceBlockEntity(PhyBlockEntities.EXTRACTOR),
override fun toCommonTag(tag: CompoundTag) {
super.toCommonTag(tag)
tag.putString("ActivationMode", controller.activationMode.name)
writeDeviceConfiguration(tag)
}
override fun fromCommonTag(tag: CompoundTag) {
super.fromCommonTag(tag)
loadDeviceConfiguration(tag)
}
override fun writeDeviceConfiguration(tag: CompoundTag) {
tag.putString("ActivationMode", controller.activationMode.name)
}
override fun loadDeviceConfiguration(tag: CompoundTag) {
controller.activationMode = ActivationMode.valueOf(tag.getString("ActivationMode"))
}

View File

@ -18,6 +18,7 @@ import net.shadowfacts.phycon.component.handleItemStack
import net.shadowfacts.phycon.init.PhyBlockEntities
import net.shadowfacts.phycon.packet.*
import net.shadowfacts.phycon.util.ActivationMode
import net.shadowfacts.phycon.util.ClientConfigurableDevice
import kotlin.math.min
/**
@ -25,7 +26,8 @@ import kotlin.math.min
*/
class InserterBlockEntity: DeviceBlockEntity(PhyBlockEntities.INSERTER),
ItemStackPacketHandler,
ActivationController.ActivatableDevice {
ActivationController.ActivatableDevice,
ClientConfigurableDevice {
companion object {
val SLEEP_TIME = 40L
@ -127,17 +129,26 @@ class InserterBlockEntity: DeviceBlockEntity(PhyBlockEntities.INSERTER),
override fun toCommonTag(tag: CompoundTag) {
super.toCommonTag(tag)
tag.putString("ActivationMode", controller.activationMode.name)
writeDeviceConfiguration(tag)
tag.put("StackToExtract", stackToExtract.toTag(CompoundTag()))
tag.putInt("AmountToExtract", amountToExtract)
}
override fun fromCommonTag(tag: CompoundTag) {
super.fromCommonTag(tag)
controller.activationMode = ActivationMode.valueOf(tag.getString("ActivationMode"))
loadDeviceConfiguration(tag)
stackToExtract = ItemStack.fromTag(tag.getCompound("StackToExtract"))
}
override fun writeDeviceConfiguration(tag: CompoundTag) {
tag.putString("ActivationMode", controller.activationMode.name)
tag.putInt("AmountToExtract", amountToExtract)
}
override fun loadDeviceConfiguration(tag: CompoundTag) {
controller.activationMode = ActivationMode.valueOf(tag.getString("ActivationMode"))
amountToExtract = tag.getInt("AmountToExtract")
}
class PendingExtractRequest(
val stack: ItemStack,
val timestamp: Long,

View File

@ -9,10 +9,9 @@ import net.minecraft.screen.slot.Slot
import net.minecraft.screen.slot.SlotActionType
import net.minecraft.text.LiteralText
import net.minecraft.text.Text
import net.minecraft.text.TranslatableText
import net.minecraft.util.Identifier
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.networking.C2SConfigureInserterAmount
import net.shadowfacts.phycon.networking.C2SConfigureDevice
import java.lang.NumberFormatException
/**
@ -67,7 +66,7 @@ class InserterScreen(
fun amountUpdated() {
if (amountField.text.isNotEmpty()) {
handler.inserter.amountToExtract = Integer.parseInt(amountField.text)
client!!.player!!.networkHandler.sendPacket(C2SConfigureInserterAmount(handler.inserter))
client!!.player!!.networkHandler.sendPacket(C2SConfigureDevice(handler.inserter))
}
}

View File

@ -1,18 +1,19 @@
package net.shadowfacts.phycon.block.redstone_controller
import net.minecraft.block.BlockState
import net.minecraft.nbt.CompoundTag
import net.shadowfacts.phycon.api.packet.Packet
import net.shadowfacts.phycon.api.util.IPAddress
import net.shadowfacts.phycon.init.PhyBlockEntities
import net.shadowfacts.phycon.block.DeviceBlockEntity
import net.shadowfacts.phycon.packet.RemoteActivationPacket
import net.shadowfacts.phycon.util.ClientConfigurableDevice
import net.shadowfacts.phycon.util.RedstoneMode
/**
* @author shadowfacts
*/
class RedstoneControllerBlockEntity: DeviceBlockEntity(PhyBlockEntities.REDSTONE_CONTROLLER) {
class RedstoneControllerBlockEntity: DeviceBlockEntity(PhyBlockEntities.REDSTONE_CONTROLLER),
ClientConfigurableDevice {
var managedDevices = Array<IPAddress?>(5) { null }
var redstoneMode = RedstoneMode.HIGH
@ -48,12 +49,20 @@ class RedstoneControllerBlockEntity: DeviceBlockEntity(PhyBlockEntities.REDSTONE
override fun toCommonTag(tag: CompoundTag) {
super.toCommonTag(tag)
tag.putIntArray("ManagedDevices", managedDevices.mapNotNull { it?.address })
tag.putString("RedstoneMode", redstoneMode.name)
writeDeviceConfiguration(tag)
}
override fun fromCommonTag(tag: CompoundTag) {
super.fromCommonTag(tag)
loadDeviceConfiguration(tag)
}
override fun writeDeviceConfiguration(tag: CompoundTag) {
tag.putIntArray("ManagedDevices", managedDevices.mapNotNull { it?.address })
tag.putString("RedstoneMode", redstoneMode.name)
}
override fun loadDeviceConfiguration(tag: CompoundTag) {
val addresses = tag.getIntArray("ManagedDevices")
managedDevices = (0..4).map { if (it >= addresses.size) null else IPAddress(addresses[it]) }.toTypedArray()
redstoneMode = RedstoneMode.valueOf(tag.getString("RedstoneMode"))

View File

@ -11,12 +11,14 @@ import net.shadowfacts.phycon.init.PhyBlockEntities
import net.shadowfacts.phycon.packet.DeviceRemovedPacket
import net.shadowfacts.phycon.packet.ReadInventoryPacket
import net.shadowfacts.phycon.packet.RequestInventoryPacket
import net.shadowfacts.phycon.util.ClientConfigurableDevice
import kotlin.math.round
/**
* @author shadowfacts
*/
class RedstoneEmitterBlockEntity: DeviceBlockEntity(PhyBlockEntities.REDSTONE_EMITTER) {
class RedstoneEmitterBlockEntity: DeviceBlockEntity(PhyBlockEntities.REDSTONE_EMITTER),
ClientConfigurableDevice {
private val inventoryCache = mutableMapOf<IPAddress, GroupedItemInvView>()
var cachedEmittedPower: Int = 0
@ -85,13 +87,21 @@ class RedstoneEmitterBlockEntity: DeviceBlockEntity(PhyBlockEntities.REDSTONE_EM
super.toCommonTag(tag)
tag.putInt("CachedEmittedPower", cachedEmittedPower)
tag.put("StackToMonitor", stackToMonitor.toTag(CompoundTag()))
tag.putInt("MaxAmount", maxAmount)
writeDeviceConfiguration(tag)
}
override fun fromCommonTag(tag: CompoundTag) {
super.fromCommonTag(tag)
cachedEmittedPower = tag.getInt("CachedEmittedPower")
stackToMonitor = ItemStack.fromTag(tag.getCompound("StackToMonitor"))
loadDeviceConfiguration(tag)
}
override fun writeDeviceConfiguration(tag: CompoundTag) {
tag.putInt("MaxAmount", maxAmount)
}
override fun loadDeviceConfiguration(tag: CompoundTag) {
maxAmount = tag.getInt("MaxAmount")
}
}

View File

@ -18,7 +18,7 @@ import net.shadowfacts.cacao.window.ScreenHandlerWindow
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.init.PhyBlocks
import net.shadowfacts.phycon.networking.C2SConfigureRedstoneEmitterAmount
import net.shadowfacts.phycon.networking.C2SConfigureDevice
import no.birkett.kiwi.Variable
import kotlin.math.ceil
@ -77,7 +77,7 @@ class RedstoneEmitterScreen(
val field = NumberField(emitter.maxAmount) {
if (it.number != null) {
emitter.maxAmount = it.number!!
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureRedstoneEmitterAmount(emitter))
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureDevice(emitter))
}
updateLabelTexts()
}

View File

@ -3,6 +3,7 @@ package net.shadowfacts.phycon.component
import net.minecraft.block.entity.BlockEntity
import net.shadowfacts.phycon.packet.RemoteActivationPacket
import net.shadowfacts.phycon.util.ActivationMode
import net.shadowfacts.phycon.util.ClientConfigurableDevice
/**
* @author shadowfacts
@ -50,7 +51,7 @@ class ActivationController<T>(
}
}
interface ActivatableDevice {
interface ActivatableDevice: ClientConfigurableDevice {
val controller: ActivationController<*>
val counter: Long

View File

@ -1,49 +0,0 @@
package net.shadowfacts.phycon.networking
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
import net.fabricmc.fabric.api.networking.v1.PacketSender
import net.minecraft.network.Packet
import net.minecraft.network.PacketByteBuf
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayNetworkHandler
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry
import net.minecraft.util.registry.RegistryKey
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.block.DeviceBlockEntity
import net.shadowfacts.phycon.component.ActivationController
import net.shadowfacts.phycon.util.ActivationMode
/**
* @author shadowfacts
*/
object C2SConfigureActivationMode: ServerReceiver {
override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "configure_activation_mode")
operator fun <T> invoke(be: T): Packet<*> where T: DeviceBlockEntity, T: ActivationController.ActivatableDevice {
val buf = PacketByteBufs.create()
buf.writeIdentifier(be.world!!.registryKey.value)
buf.writeBlockPos(be.pos)
buf.writeString(be.controller.activationMode.name)
return createPacket(buf)
}
override fun receive(server: MinecraftServer, player: ServerPlayerEntity, handler: ServerPlayNetworkHandler, buf: PacketByteBuf, responseSender: PacketSender) {
val dimID = buf.readIdentifier()
val pos = buf.readBlockPos()
val mode = ActivationMode.valueOf(buf.readString())
server.execute {
// todo: check the player is close enough
val key = RegistryKey.of(Registry.DIMENSION, dimID)
val world = server.getWorld(key) ?: return@execute
val device = world.getBlockEntity(pos) ?: return@execute
if (device !is ActivationController.ActivatableDevice) return@execute
device.controller.activationMode = mode
device.markDirty()
}
}
}

View File

@ -2,29 +2,31 @@ package net.shadowfacts.phycon.networking
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
import net.fabricmc.fabric.api.networking.v1.PacketSender
import net.minecraft.block.entity.BlockEntity
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.Packet
import net.minecraft.network.PacketByteBuf
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayNetworkHandler
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry
import net.minecraft.util.registry.RegistryKey
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.block.inserter.InserterBlockEntity
import net.shadowfacts.phycon.util.ClientConfigurableDevice
/**
* @author shadowfacts
*/
object C2SConfigureInserterAmount: ServerReceiver {
override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "configure_inserter_amount")
object C2SConfigureDevice: ServerReceiver {
override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "configure_device")
operator fun invoke(be: InserterBlockEntity): Packet<*> {
operator fun <T> invoke(be: T): Packet<*> where T: BlockEntity, T: ClientConfigurableDevice {
val buf = PacketByteBufs.create()
buf.writeIdentifier(be.world!!.registryKey.value)
buf.writeBlockPos(be.pos)
buf.writeVarInt(be.amountToExtract)
val tag = CompoundTag()
be.writeDeviceConfiguration(tag)
buf.writeCompoundTag(tag)
return createPacket(buf)
}
@ -32,13 +34,15 @@ object C2SConfigureInserterAmount: ServerReceiver {
override fun receive(server: MinecraftServer, player: ServerPlayerEntity, handler: ServerPlayNetworkHandler, buf: PacketByteBuf, responseSender: PacketSender) {
val dimID = buf.readIdentifier()
val pos = buf.readBlockPos()
val amount = buf.readVarInt()
val tag = buf.readCompoundTag() ?: return
server.execute {
val key = RegistryKey.of(Registry.DIMENSION, dimID)
val world = server.getWorld(key) ?: return@execute
val be = world.getBlockEntity(pos) as? InserterBlockEntity ?: return@execute
be.amountToExtract = amount
// todo: check if the player is close enough
val world = player.world
if (world.registryKey.value != dimID) return@execute
val be = world.getBlockEntity(pos) ?: return@execute
val device = be as? ClientConfigurableDevice ?: return@execute
device.loadDeviceConfiguration(tag)
be.markDirty()
}
}

View File

@ -1,59 +0,0 @@
package net.shadowfacts.phycon.networking
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
import net.fabricmc.fabric.api.networking.v1.PacketSender
import net.minecraft.network.Packet
import net.minecraft.network.PacketByteBuf
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayNetworkHandler
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry
import net.minecraft.util.registry.RegistryKey
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.api.util.IPAddress
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlockEntity
import net.shadowfacts.phycon.util.RedstoneMode
/**
* @author shadowfacts
*/
object C2SConfigureRedstoneController: ServerReceiver {
// todo: it would be nice if there wasn't so much duplication with C2SConfigureActivationMode
override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "configure_redstone_controller")
operator fun invoke(be: RedstoneControllerBlockEntity): Packet<*> {
val buf = PacketByteBufs.create()
buf.writeIdentifier(be.world!!.registryKey.value)
buf.writeBlockPos(be.pos)
buf.writeString(be.redstoneMode.name)
be.managedDevices.forEach {
buf.writeInt(it?.address ?: 0)
}
return createPacket(buf)
}
override fun receive(server: MinecraftServer, player: ServerPlayerEntity, handler: ServerPlayNetworkHandler, buf: PacketByteBuf, responseSender: PacketSender) {
val dimID = buf.readIdentifier()
val pos = buf.readBlockPos()
val mode = RedstoneMode.valueOf(buf.readString())
val managedDevices = Array<IPAddress?>(5) { null }
(0..4).map {
val v = buf.readInt()
managedDevices[it] = if (v == 0) null else IPAddress(v)
}
server.execute {
// todo: check if the player is close enough
val key = RegistryKey.of(Registry.DIMENSION, dimID)
val world = server.getWorld(key) ?: return@execute
val device = world.getBlockEntity(pos) as? RedstoneControllerBlockEntity ?: return@execute
device.redstoneMode = mode
device.managedDevices = managedDevices
device.markDirty()
}
}
}

View File

@ -1,46 +0,0 @@
package net.shadowfacts.phycon.networking
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
import net.fabricmc.fabric.api.networking.v1.PacketSender
import net.minecraft.network.Packet
import net.minecraft.network.PacketByteBuf
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayNetworkHandler
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry
import net.minecraft.util.registry.RegistryKey
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.block.inserter.InserterBlockEntity
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlockEntity
/**
* @author shadowfacts
*/
object C2SConfigureRedstoneEmitterAmount: ServerReceiver {
override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "configure_redstone_emitter_amount")
operator fun invoke(be: RedstoneEmitterBlockEntity): Packet<*> {
val buf = PacketByteBufs.create()
buf.writeIdentifier(be.world!!.registryKey.value)
buf.writeBlockPos(be.pos)
buf.writeVarInt(be.maxAmount)
return createPacket(buf)
}
override fun receive(server: MinecraftServer, player: ServerPlayerEntity, handler: ServerPlayNetworkHandler, buf: PacketByteBuf, responseSender: PacketSender) {
val dimID = buf.readIdentifier()
val pos = buf.readBlockPos()
val amount = buf.readVarInt()
server.execute {
val key = RegistryKey.of(Registry.DIMENSION, dimID)
val world = server.getWorld(key) ?: return@execute
val be = world.getBlockEntity(pos) as? RedstoneEmitterBlockEntity ?: return@execute
be.maxAmount = amount
be.markDirty()
}
}
}

View File

@ -9,7 +9,7 @@ import net.shadowfacts.cacao.viewcontroller.ViewController
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.phycon.block.DeviceBlockEntity
import net.shadowfacts.phycon.component.ActivationController
import net.shadowfacts.phycon.networking.C2SConfigureActivationMode
import net.shadowfacts.phycon.networking.C2SConfigureDevice
import net.shadowfacts.phycon.util.ActivationMode
/**
@ -30,7 +30,7 @@ class ActivatableDeviceViewController<T>(
val mode = EnumButton(device.controller.activationMode, ActivationMode::friendlyName)
mode.handler = {
device.controller.activationMode = it.value
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureActivationMode(device))
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureDevice(device))
}
view.addSubview(mode)

View File

@ -12,7 +12,7 @@ import net.shadowfacts.cacao.viewcontroller.ViewController
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.phycon.api.util.IPAddress
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlockEntity
import net.shadowfacts.phycon.networking.C2SConfigureRedstoneController
import net.shadowfacts.phycon.networking.C2SConfigureDevice
import net.shadowfacts.phycon.util.RedstoneMode
/**
@ -39,14 +39,14 @@ class RedstoneControllerViewController(val device: RedstoneControllerBlockEntity
val mode = EnumButton(device.redstoneMode, RedstoneMode::friendlyName)
mode.handler = {
device.redstoneMode = it.value
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureRedstoneController(device))
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureDevice(device))
}
controls.addArrangedSubview(mode)
val textFields = (0 until 5).map { i ->
TextField(device.managedDevices[i]?.toString() ?: "") {
device.managedDevices[i] = IPAddress.parse(it.text)
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureRedstoneController(device))
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureDevice(device))
}
}
textFields.forEach(controls::addArrangedSubview)

View File

@ -0,0 +1,14 @@
package net.shadowfacts.phycon.util
import net.minecraft.nbt.CompoundTag
/**
* @author shadowfacts
*/
interface ClientConfigurableDevice {
fun writeDeviceConfiguration(tag: CompoundTag)
fun loadDeviceConfiguration(tag: CompoundTag)
}