62 lines
1.7 KiB
Kotlin
62 lines
1.7 KiB
Kotlin
package net.shadowfacts.phycon.network.block.netswitch
|
|
|
|
import net.minecraft.util.math.Direction
|
|
import net.shadowfacts.phycon.api.PacketSink
|
|
import net.shadowfacts.phycon.api.packet.Packet
|
|
import net.shadowfacts.phycon.api.util.MACAddress
|
|
import net.shadowfacts.phycon.init.PhyBlockEntities
|
|
import net.shadowfacts.phycon.network.DeviceBlockEntity
|
|
import net.shadowfacts.phycon.network.NetworkUtil
|
|
import java.lang.RuntimeException
|
|
|
|
/**
|
|
* @author shadowfacts
|
|
*/
|
|
class SwitchBlockEntity: DeviceBlockEntity(PhyBlockEntities.SWITCH) {
|
|
|
|
private val macTable = mutableMapOf<MACAddress, Direction>()
|
|
|
|
override fun handlePacket(packet: Packet) {
|
|
throw RuntimeException("Unreachable")
|
|
}
|
|
|
|
override fun handle(packet: Packet) {
|
|
if (packet.destination == MACAddress.BROADCAST) {
|
|
val allDestinations = NetworkUtil.findDestinations(world!!, pos).filter { it.macAddress != packet.source }
|
|
sendToAll(packet, allDestinations)
|
|
} else {
|
|
val direction = macTable[packet.destination]
|
|
if (direction != null) {
|
|
val dest = findDestination(direction)
|
|
if (dest != null && packet.destination == dest.macAddress) {
|
|
send(packet, dest)
|
|
return
|
|
}
|
|
}
|
|
flood(packet)
|
|
}
|
|
}
|
|
|
|
private fun findDestination(direction: Direction): PacketSink? {
|
|
val allDestinations = NetworkUtil.findDestinations(world!!, pos, direction)
|
|
if (allDestinations.size > 1) {
|
|
// todo: do this better
|
|
println("Can't send packet, multiple destinations: $allDestinations")
|
|
return null
|
|
}
|
|
return allDestinations.firstOrNull()
|
|
}
|
|
|
|
private fun flood(packet: Packet) {
|
|
for (dir in Direction.values()) {
|
|
val dest = findDestination(dir)
|
|
if (dest != null && packet.destination == dest.macAddress) {
|
|
macTable[packet.destination] = dir
|
|
send(packet, dest)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|