package net.shadowfacts.phycon.network import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.BlockEntityType import net.minecraft.nbt.CompoundTag import net.minecraft.util.Tickable import net.shadowfacts.phycon.api.PacketSink import net.shadowfacts.phycon.api.packet.Packet import net.shadowfacts.phycon.api.util.MACAddress import java.lang.ref.WeakReference import java.util.* /** * @author shadowfacts */ abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), Tickable, PacketSink { var macAddress = MACAddress.random() protected set private val sendQueue = LinkedList>>() override fun getMACAddress(): MACAddress { return macAddress } override fun handle(packet: Packet) { if (acceptsPacket(packet)) { handlePacket(packet) } } protected abstract fun handlePacket(packet: Packet) fun acceptsPacket(packet: Packet): Boolean { return when (packet.destination.type) { MACAddress.Type.BROADCAST -> true MACAddress.Type.UNICAST -> macAddress == packet.destination MACAddress.Type.MULTICAST -> acceptsMulticastPacket(packet) } } open fun acceptsMulticastPacket(packet: Packet): Boolean { return false } fun enqueue(packet: Packet, destination: PacketSink) { sendQueue.add(packet to WeakReference(destination)) } // todo: better name for this fun enqueueToSingle(packet: Packet) { val destinations = NetworkUtil.findDestinations(world!!, pos) if (destinations.size != 1) { // todo: handle this better println("Can't send packet, multiple destinations available: $destinations") return } enqueue(packet, destinations.first()) } fun enqueueToAll(packet: Packet) { enqueueToAll(packet, NetworkUtil.findDestinations(world!!, pos)) } fun enqueueToAll(packet: Packet, destinations: Iterable) { sendQueue.addAll(destinations.map { packet to WeakReference(it) }) } override fun tick() { if (sendQueue.isNotEmpty()) { val (packet, destination) = sendQueue.pop() destination.get()?.handle(packet) } } override fun toTag(tag: CompoundTag): CompoundTag { tag.putLong("MACAddress", macAddress.address) return super.toTag(tag) } override fun fromTag(tag: CompoundTag) { super.fromTag(tag) macAddress = MACAddress(tag.getLong("MACAddress")) } }