Delay packets after switching capacity is reached
This commit is contained in:
parent
da8b600f31
commit
7cc96d78ad
|
@ -3,19 +3,24 @@ package net.shadowfacts.phycon.block.netswitch
|
|||
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.entity.BlockEntity
|
||||
import net.minecraft.entity.ItemEntity
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.util.Tickable
|
||||
import net.minecraft.util.math.Direction
|
||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||
import net.shadowfacts.phycon.api.Interface
|
||||
import net.shadowfacts.phycon.api.frame.EthernetFrame
|
||||
import net.shadowfacts.phycon.api.frame.PacketFrame
|
||||
import net.shadowfacts.phycon.api.util.IPAddress
|
||||
import net.shadowfacts.phycon.api.util.MACAddress
|
||||
import net.shadowfacts.phycon.frame.BasePacketFrame
|
||||
import net.shadowfacts.phycon.init.PhyBlockEntities
|
||||
import net.shadowfacts.phycon.util.NetworkUtil
|
||||
import net.shadowfacts.phycon.packet.ItemStackPacket
|
||||
import net.shadowfacts.phycon.util.NetworkUtil
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.Deque
|
||||
import java.util.LinkedList
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
|
@ -25,13 +30,14 @@ class SwitchBlockEntity: BlockEntity(PhyBlockEntities.SWITCH),
|
|||
Tickable {
|
||||
|
||||
companion object {
|
||||
var SWITCHING_CAPACITY = 256 // 256 items/tick
|
||||
var SWITCHING_CAPACITY = 256 // 256 packets/tick
|
||||
}
|
||||
|
||||
val interfaces = Direction.values().map { SwitchInterface(it, WeakReference(this), MACAddress.random()) }
|
||||
|
||||
private val macTable = mutableMapOf<MACAddress, Direction>()
|
||||
private var itemsHandledThisTick = 0
|
||||
private var packetsHandledThisTick = 0
|
||||
private var delayedPackets: Deque<Pair<PacketFrame, SwitchInterface>> = LinkedList()
|
||||
|
||||
fun interfaceForSide(side: Direction): SwitchInterface {
|
||||
return interfaces.find { it.side == side }!!
|
||||
|
@ -40,18 +46,20 @@ class SwitchBlockEntity: BlockEntity(PhyBlockEntities.SWITCH),
|
|||
private fun handle(frame: EthernetFrame, fromItf: SwitchInterface) {
|
||||
macTable[frame.source] = fromItf.side
|
||||
|
||||
if (frame is PacketFrame && frame.packet is ItemStackPacket) {
|
||||
val packet = frame.packet as ItemStackPacket
|
||||
if (itemsHandledThisTick + packet.stack.count > SWITCHING_CAPACITY) {
|
||||
// todo: calculate entity spawn point by finding non-obstructed location
|
||||
val entity = ItemEntity(world!!, pos.x.toDouble(), pos.y + 1.0, pos.z.toDouble(), packet.stack)
|
||||
world!!.spawnEntity(entity)
|
||||
if (frame is PacketFrame) {
|
||||
if (packetsHandledThisTick > SWITCHING_CAPACITY) {
|
||||
PhysicalConnectivity.NETWORK_LOGGER.debug("{} reached capacity, delaying forwarding {}", this, frame)
|
||||
delayedPackets.addLast(frame to fromItf)
|
||||
return
|
||||
} else {
|
||||
itemsHandledThisTick += packet.stack.count
|
||||
packetsHandledThisTick++
|
||||
}
|
||||
}
|
||||
|
||||
resend(frame, fromItf)
|
||||
}
|
||||
|
||||
private fun resend(frame: EthernetFrame, fromItf: SwitchInterface) {
|
||||
if (frame.destination.type != MACAddress.Type.BROADCAST && macTable.containsKey(frame.destination)) {
|
||||
val dir = macTable[frame.destination]!!
|
||||
PhysicalConnectivity.NETWORK_LOGGER.debug("{} ({}, {}) forwarding {} to side {}", this, fromItf.side, fromItf.macAddress, frame, dir)
|
||||
|
@ -75,11 +83,30 @@ class SwitchBlockEntity: BlockEntity(PhyBlockEntities.SWITCH),
|
|||
}
|
||||
|
||||
override fun tick() {
|
||||
itemsHandledThisTick = 0
|
||||
packetsHandledThisTick = 0
|
||||
|
||||
while (delayedPackets.isNotEmpty() && packetsHandledThisTick <= SWITCHING_CAPACITY) {
|
||||
val (frame, fromItf) = delayedPackets.pop()
|
||||
resend(frame, fromItf)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toTag(tag: CompoundTag): CompoundTag {
|
||||
tag.putLongArray("InterfaceAddresses", interfaces.map { it.macAddress.address })
|
||||
val list = ListTag()
|
||||
for ((frame, fromItf) in delayedPackets) {
|
||||
val packet = frame.packet
|
||||
if (packet !is ItemStackPacket) continue
|
||||
val compound = CompoundTag()
|
||||
compound.putInt("FromItfSide", fromItf.side.ordinal)
|
||||
compound.putInt("SourceIP", packet.source.address)
|
||||
compound.putInt("DestinationIP", packet.destination.address)
|
||||
compound.putLong("SourceMAC", frame.source.address)
|
||||
compound.putLong("DestinationMAC", frame.destination.address)
|
||||
compound.put("Stack", packet.stack.toTag(CompoundTag()))
|
||||
list.add(compound)
|
||||
}
|
||||
tag.put("DelayedStackPackets", list)
|
||||
return super.toTag(tag)
|
||||
}
|
||||
|
||||
|
@ -88,6 +115,21 @@ class SwitchBlockEntity: BlockEntity(PhyBlockEntities.SWITCH),
|
|||
tag.getLongArray("InterfaceAddresses")?.forEachIndexed { i, l ->
|
||||
interfaces[i].macAddress = MACAddress(l)
|
||||
}
|
||||
tag.getList("DelayedStackPackets", 10).forEach { it ->
|
||||
val compound = it as CompoundTag
|
||||
val fromItfSide = Direction.values()[compound.getInt("FromItfSide")]
|
||||
val fromItf = interfaces.find { it.side == fromItfSide }!!
|
||||
val sourceIP = IPAddress(compound.getInt("SourceIP"))
|
||||
val destinationIP = IPAddress(compound.getInt("DestinationIP"))
|
||||
val sourceMAC = MACAddress(compound.getLong("SourceMAC"))
|
||||
val destinationMAC = MACAddress(compound.getLong("DestinationMAC"))
|
||||
val stack = ItemStack.fromTag(compound.getCompound("Stack"))
|
||||
if (!stack.isEmpty) {
|
||||
val packet = ItemStackPacket(stack, sourceIP, destinationIP)
|
||||
val frame = BasePacketFrame(packet, sourceMAC, destinationMAC)
|
||||
delayedPackets.addLast(frame to fromItf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun toClientTag(tag: CompoundTag): CompoundTag {
|
||||
|
|
Loading…
Reference in New Issue