2019-10-27 01:36:31 +00:00
|
|
|
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
|
2019-10-27 02:09:16 +00:00
|
|
|
import java.lang.ref.WeakReference
|
2019-10-27 01:36:31 +00:00
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author shadowfacts
|
|
|
|
*/
|
|
|
|
abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), Tickable, PacketSink {
|
|
|
|
|
|
|
|
var macAddress = MACAddress.random()
|
|
|
|
protected set
|
|
|
|
|
2019-10-27 02:09:16 +00:00
|
|
|
private val sendQueue = LinkedList<Pair<Packet, WeakReference<PacketSink>>>()
|
2019-10-27 01:36:31 +00:00
|
|
|
|
2019-10-27 03:13:26 +00:00
|
|
|
override fun getMACAddress(): MACAddress {
|
|
|
|
return macAddress
|
|
|
|
}
|
|
|
|
|
2019-10-27 01:36:31 +00:00
|
|
|
override fun handle(packet: Packet) {
|
|
|
|
if (acceptsPacket(packet)) {
|
|
|
|
handlePacket(packet)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-27 03:13:26 +00:00
|
|
|
protected abstract fun handlePacket(packet: Packet)
|
2019-10-27 01:36:31 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-27 02:09:16 +00:00
|
|
|
open fun acceptsMulticastPacket(packet: Packet): Boolean {
|
2019-10-27 01:36:31 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-10-27 02:09:16 +00:00
|
|
|
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) {
|
2019-10-27 03:13:26 +00:00
|
|
|
enqueueToAll(packet, NetworkUtil.findDestinations(world!!, pos))
|
|
|
|
}
|
|
|
|
|
|
|
|
fun enqueueToAll(packet: Packet, destinations: Iterable<PacketSink>) {
|
|
|
|
sendQueue.addAll(destinations.map { packet to WeakReference(it) })
|
2019-10-27 01:36:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun tick() {
|
|
|
|
if (sendQueue.isNotEmpty()) {
|
2019-10-27 02:09:16 +00:00
|
|
|
val (packet, destination) = sendQueue.pop()
|
|
|
|
destination.get()?.handle(packet)
|
2019-10-27 01:36:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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"))
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|