Fix P2P receiver not invalidating target on netsplit
This commit is contained in:
parent
33614e0dc6
commit
73de26387a
|
@ -19,6 +19,7 @@ import net.shadowfacts.phycon.api.util.MACAddress
|
||||||
import net.shadowfacts.phycon.frame.ARPQueryFrame
|
import net.shadowfacts.phycon.frame.ARPQueryFrame
|
||||||
import net.shadowfacts.phycon.frame.ARPResponseFrame
|
import net.shadowfacts.phycon.frame.ARPResponseFrame
|
||||||
import net.shadowfacts.phycon.frame.BasePacketFrame
|
import net.shadowfacts.phycon.frame.BasePacketFrame
|
||||||
|
import net.shadowfacts.phycon.frame.NetworkSplitFrame
|
||||||
import net.shadowfacts.phycon.packet.*
|
import net.shadowfacts.phycon.packet.*
|
||||||
import net.shadowfacts.phycon.util.NetworkUtil
|
import net.shadowfacts.phycon.util.NetworkUtil
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
@ -75,6 +76,7 @@ abstract class DeviceBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state:
|
||||||
when (frame) {
|
when (frame) {
|
||||||
is ARPQueryFrame -> handleARPQuery(frame)
|
is ARPQueryFrame -> handleARPQuery(frame)
|
||||||
is ARPResponseFrame -> handleARPResponse(frame)
|
is ARPResponseFrame -> handleARPResponse(frame)
|
||||||
|
is NetworkSplitFrame -> handleNetworkSplit()
|
||||||
is PacketFrame -> {
|
is PacketFrame -> {
|
||||||
if (frame.packet.destination.isBroadcast || frame.packet.destination == ipAddress) {
|
if (frame.packet.destination.isBroadcast || frame.packet.destination == ipAddress) {
|
||||||
doHandlePacket(frame.packet)
|
doHandlePacket(frame.packet)
|
||||||
|
@ -107,6 +109,11 @@ abstract class DeviceBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state:
|
||||||
packetQueue.removeAll(toRemove)
|
packetQueue.removeAll(toRemove)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun handleNetworkSplit() {
|
||||||
|
arpTable.clear()
|
||||||
|
cachedDestination = null
|
||||||
|
}
|
||||||
|
|
||||||
override fun sendPacket(packet: Packet) {
|
override fun sendPacket(packet: Packet) {
|
||||||
if (packet.destination.isBroadcast) {
|
if (packet.destination.isBroadcast) {
|
||||||
send(BasePacketFrame(packet, macAddress, MACAddress.BROADCAST))
|
send(BasePacketFrame(packet, macAddress, MACAddress.BROADCAST))
|
||||||
|
@ -140,6 +147,7 @@ abstract class DeviceBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state:
|
||||||
|
|
||||||
override fun cableDisconnected() {
|
override fun cableDisconnected() {
|
||||||
cachedDestination = null
|
cachedDestination = null
|
||||||
|
handleNetworkSplit()
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun tick() {
|
open fun tick() {
|
||||||
|
|
|
@ -2,8 +2,10 @@ package net.shadowfacts.phycon.block.cable
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.`object`.builder.v1.block.FabricBlockSettings
|
import net.fabricmc.fabric.api.`object`.builder.v1.block.FabricBlockSettings
|
||||||
import net.minecraft.block.*
|
import net.minecraft.block.*
|
||||||
|
import net.minecraft.block.entity.BlockEntity
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.item.ItemPlacementContext
|
import net.minecraft.item.ItemPlacementContext
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.state.StateManager
|
import net.minecraft.state.StateManager
|
||||||
import net.minecraft.state.property.EnumProperty
|
import net.minecraft.state.property.EnumProperty
|
||||||
import net.minecraft.util.ActionResult
|
import net.minecraft.util.ActionResult
|
||||||
|
@ -200,6 +202,7 @@ class CableBlock(
|
||||||
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
|
override fun onBreak(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) {
|
||||||
super.onBreak(world, pos, state, player)
|
super.onBreak(world, pos, state, player)
|
||||||
if (!world.isClient) {
|
if (!world.isClient) {
|
||||||
|
world.server?.execute {
|
||||||
// notify devices on either end that the connection was broken (i.e., unset the cached receivers)
|
// notify devices on either end that the connection was broken (i.e., unset the cached receivers)
|
||||||
val connectedSides = getNetworkConnectedSides(state, world, pos)
|
val connectedSides = getNetworkConnectedSides(state, world, pos)
|
||||||
for (side in connectedSides) {
|
for (side in connectedSides) {
|
||||||
|
@ -208,5 +211,6 @@ class CableBlock(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import net.shadowfacts.phycon.api.frame.PacketFrame
|
||||||
import net.shadowfacts.phycon.api.util.IPAddress
|
import net.shadowfacts.phycon.api.util.IPAddress
|
||||||
import net.shadowfacts.phycon.api.util.MACAddress
|
import net.shadowfacts.phycon.api.util.MACAddress
|
||||||
import net.shadowfacts.phycon.frame.BasePacketFrame
|
import net.shadowfacts.phycon.frame.BasePacketFrame
|
||||||
|
import net.shadowfacts.phycon.frame.NetworkSplitFrame
|
||||||
import net.shadowfacts.phycon.init.PhyBlockEntities
|
import net.shadowfacts.phycon.init.PhyBlockEntities
|
||||||
import net.shadowfacts.phycon.packet.ItemStackPacket
|
import net.shadowfacts.phycon.packet.ItemStackPacket
|
||||||
import net.shadowfacts.phycon.util.NetworkUtil
|
import net.shadowfacts.phycon.util.NetworkUtil
|
||||||
|
@ -66,12 +67,12 @@ class SwitchBlockEntity(pos: BlockPos, state: BlockState): BlockEntity(PhyBlockE
|
||||||
PhysicalConnectivity.NETWORK_LOGGER.debug("{} ({}, {}) forwarding {} to side {}", this, fromItf.side, fromItf.macAddress, frame, dir)
|
PhysicalConnectivity.NETWORK_LOGGER.debug("{} ({}, {}) forwarding {} to side {}", this, fromItf.side, fromItf.macAddress, frame, dir)
|
||||||
interfaceForSide(dir).send(frame)
|
interfaceForSide(dir).send(frame)
|
||||||
} else {
|
} else {
|
||||||
PhysicalConnectivity.NETWORK_LOGGER.debug("{} ({}, {}) flooding {}", this, fromItf.side, fromItf.macAddress, frame)
|
|
||||||
flood(frame, fromItf)
|
flood(frame, fromItf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun flood(frame: EthernetFrame, source: Interface) {
|
private fun flood(frame: EthernetFrame, source: SwitchInterface) {
|
||||||
|
PhysicalConnectivity.NETWORK_LOGGER.debug("{} ({}, {}) flooding {}", this, source.side, source.macAddress, frame)
|
||||||
for (itf in interfaces) {
|
for (itf in interfaces) {
|
||||||
if (source == itf) continue
|
if (source == itf) continue
|
||||||
itf.send(frame)
|
itf.send(frame)
|
||||||
|
@ -86,6 +87,16 @@ class SwitchBlockEntity(pos: BlockPos, state: BlockState): BlockEntity(PhyBlockE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun cableDisconnected(itf: SwitchInterface) {
|
||||||
|
macTable.entries.filter {
|
||||||
|
it.value == itf.side
|
||||||
|
}.forEach {
|
||||||
|
macTable.remove(it.key)
|
||||||
|
}
|
||||||
|
destinationCache[itf.side.ordinal] = null
|
||||||
|
flood(NetworkSplitFrame(itf.macAddress), itf)
|
||||||
|
}
|
||||||
|
|
||||||
fun tick() {
|
fun tick() {
|
||||||
packetsHandledThisTick = 0
|
packetsHandledThisTick = 0
|
||||||
|
|
||||||
|
@ -164,7 +175,7 @@ class SwitchBlockEntity(pos: BlockPos, state: BlockState): BlockEntity(PhyBlockE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cableDisconnected() {
|
override fun cableDisconnected() {
|
||||||
switch.get()?.destinationCache?.set(side.ordinal, null)
|
switch.get()?.cableDisconnected(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,11 @@ import net.shadowfacts.phycon.api.packet.Packet
|
||||||
import net.shadowfacts.phycon.api.util.IPAddress
|
import net.shadowfacts.phycon.api.util.IPAddress
|
||||||
import net.shadowfacts.phycon.block.DeviceBlockEntity
|
import net.shadowfacts.phycon.block.DeviceBlockEntity
|
||||||
import net.shadowfacts.phycon.block.FaceDeviceBlock
|
import net.shadowfacts.phycon.block.FaceDeviceBlock
|
||||||
|
import net.shadowfacts.phycon.frame.NetworkSplitFrame
|
||||||
import net.shadowfacts.phycon.init.PhyBlockEntities
|
import net.shadowfacts.phycon.init.PhyBlockEntities
|
||||||
import net.shadowfacts.phycon.packet.*
|
import net.shadowfacts.phycon.packet.*
|
||||||
import net.shadowfacts.phycon.util.ClientConfigurableDevice
|
import net.shadowfacts.phycon.util.ClientConfigurableDevice
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -50,17 +52,21 @@ class P2PReceiverBlockEntity(pos: BlockPos, state: BlockState): DeviceBlockEntit
|
||||||
var clientObserver: (() -> Unit)? = null
|
var clientObserver: (() -> Unit)? = null
|
||||||
|
|
||||||
private var isFirstTick = true
|
private var isFirstTick = true
|
||||||
// todo: need some way of removing this when there's no network path to the p2p interface
|
private var targetInventory: WeakReference<Storage<ItemVariant>>? = null
|
||||||
private var targetInventory: Storage<ItemVariant>? = null
|
|
||||||
|
|
||||||
override fun handle(packet: Packet) {
|
override fun handle(packet: Packet) {
|
||||||
when (packet) {
|
when (packet) {
|
||||||
is PongPacket -> if (packet.source == target) status = Status.OK
|
is PongPacket -> if (packet.source == target) status = Status.OK
|
||||||
is ReadItemStoragePacket -> targetInventory = packet.inventory
|
is ReadItemStoragePacket -> targetInventory = WeakReference(packet.inventory)
|
||||||
is DeviceRemovedPacket -> if (packet.source == target) targetInventory = null
|
is DeviceRemovedPacket -> if (packet.source == target) targetInventory = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun handleNetworkSplit() {
|
||||||
|
super.handleNetworkSplit()
|
||||||
|
targetInventory = null
|
||||||
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
|
|
||||||
|
@ -74,10 +80,10 @@ class P2PReceiverBlockEntity(pos: BlockPos, state: BlockState): DeviceBlockEntit
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
if (targetInventory == null) {
|
if (targetInventory?.get() == null) {
|
||||||
sendPacket(RequestInventoryPacket(RequestInventoryPacket.Kind.SIDED, ipAddress, target!!))
|
sendPacket(RequestInventoryPacket(RequestInventoryPacket.Kind.SIDED, ipAddress, target!!))
|
||||||
}
|
}
|
||||||
return targetInventory
|
return targetInventory?.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateStatus() {
|
private fun updateStatus() {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import net.shadowfacts.phycon.api.packet.Packet
|
||||||
import net.shadowfacts.phycon.api.util.IPAddress
|
import net.shadowfacts.phycon.api.util.IPAddress
|
||||||
import net.shadowfacts.phycon.block.DeviceBlockEntity
|
import net.shadowfacts.phycon.block.DeviceBlockEntity
|
||||||
import net.shadowfacts.phycon.component.*
|
import net.shadowfacts.phycon.component.*
|
||||||
|
import net.shadowfacts.phycon.frame.NetworkSplitFrame
|
||||||
import net.shadowfacts.phycon.packet.*
|
import net.shadowfacts.phycon.packet.*
|
||||||
import net.shadowfacts.phycon.util.NetworkUtil
|
import net.shadowfacts.phycon.util.NetworkUtil
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
@ -69,6 +70,11 @@ abstract class AbstractTerminalBlockEntity(type: BlockEntityType<*>, pos: BlockP
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun handleNetworkSplit() {
|
||||||
|
super.handleNetworkSplit()
|
||||||
|
inventoryCache.clear()
|
||||||
|
}
|
||||||
|
|
||||||
override fun handle(packet: Packet) {
|
override fun handle(packet: Packet) {
|
||||||
when (packet) {
|
when (packet) {
|
||||||
is ReadGroupedInventoryPacket -> handleReadInventory(packet)
|
is ReadGroupedInventoryPacket -> handleReadInventory(packet)
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package net.shadowfacts.phycon.frame
|
||||||
|
|
||||||
|
import net.shadowfacts.phycon.api.util.MACAddress
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class NetworkSplitFrame(source: MACAddress): BaseFrame(source, MACAddress.BROADCAST)
|
Loading…
Reference in New Issue