make it work a bit better in multiplayer
still needs work but at least the essential stuff works
This commit is contained in:
parent
849f12d907
commit
c72730f1a2
9 changed files with 120 additions and 36 deletions
|
|
@ -1,5 +1,7 @@
|
|||
package net.liquidev.dawd3.mixin;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.liquidev.dawd3.events.DebugHudEvents;
|
||||
import net.minecraft.client.gui.hud.DebugHud;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
@ -9,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Mixin(DebugHud.class)
|
||||
public class DebugHudMixin {
|
||||
@Inject(at = @At("RETURN"), method = "getLeftText")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package net.liquidev.dawd3.mixin;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.liquidev.dawd3.events.D3ClientEvents;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
|
@ -8,6 +10,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Mixin(MinecraftClient.class)
|
||||
public class PauseMixin {
|
||||
@Inject(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package net.liquidev.dawd3.block.device
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.PlayerLookup
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking
|
||||
import net.liquidev.dawd3.common.*
|
||||
import net.liquidev.dawd3.item.PatchCableItem
|
||||
import net.liquidev.dawd3.net.DisconnectPort
|
||||
import net.liquidev.dawd3.ui.Rack
|
||||
import net.minecraft.block.*
|
||||
import net.minecraft.block.entity.BlockEntity
|
||||
|
|
@ -110,6 +113,21 @@ class DeviceBlock(private val descriptor: AnyDeviceBlockDescriptor) :
|
|||
}
|
||||
if (usedPortName != null && player.isSneaking) {
|
||||
return if (blockEntity.severConnectionsInPort(usedPortName)) {
|
||||
if (!world.isClient) {
|
||||
val witnesses = PlayerLookup.tracking(blockEntity)
|
||||
for (witness in witnesses) {
|
||||
if (witness != player) {
|
||||
ServerPlayNetworking.send(
|
||||
witness,
|
||||
DisconnectPort.id,
|
||||
DisconnectPort(
|
||||
pos,
|
||||
usedPortName.id
|
||||
).serialize()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ActionResult.success(world.isClient)
|
||||
} else {
|
||||
ActionResult.PASS
|
||||
|
|
|
|||
|
|
@ -185,11 +185,14 @@ class DeviceBlockEntity(
|
|||
val world = world ?: return false
|
||||
|
||||
val clientState = clientState
|
||||
val severedConnections = if (clientState != null) {
|
||||
var severedAnyConnections = false
|
||||
severedAnyConnections = severedAnyConnections or if (clientState != null) {
|
||||
val resolvedPortName =
|
||||
if (portName is OutputPortName) portName.resolveInstance() else portName
|
||||
Devices.severAllConnectionsInPort(clientState.logicalDevice, resolvedPortName)
|
||||
} else 0
|
||||
Devices.severAllConnectionsInPort(clientState.logicalDevice, resolvedPortName) > 0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
when (portName) {
|
||||
is InputPortName -> {
|
||||
|
|
@ -199,6 +202,7 @@ class DeviceBlockEntity(
|
|||
if (blockEntity is DeviceBlockEntity) {
|
||||
blockEntity.outputConnections.remove(inputConnection.outputPortName)
|
||||
}
|
||||
severedAnyConnections = true
|
||||
}
|
||||
}
|
||||
is OutputPortName -> {
|
||||
|
|
@ -208,10 +212,11 @@ class DeviceBlockEntity(
|
|||
if (blockEntity is DeviceBlockEntity) {
|
||||
blockEntity.inputConnections.values.removeAll { it.outputPortName == portName }
|
||||
}
|
||||
severedAnyConnections = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return severedConnections != 0
|
||||
return severedAnyConnections
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ class DeviceBlockEntityRenderer(context: BlockEntityRendererFactory.Context) : B
|
|||
|
||||
matrixStack.push()
|
||||
rotateToFaceFront(blockState, matrixStack)
|
||||
for ((_, connection) in PatchCableItem.ongoingConnectionsServer) {
|
||||
for ((_, connection) in PatchCableItem.ongoingConnectionsClient) {
|
||||
if (connection.blockPosition == blockEntity.pos) {
|
||||
val port = blockEntity.descriptor.portLayout[connection.portName]
|
||||
if (port != null) {
|
||||
|
|
|
|||
|
|
@ -21,14 +21,16 @@ class PatchCableItem(settings: Settings, val color: Byte) : BasicItem(settings)
|
|||
override fun useOnBlock(context: ItemUsageContext): ActionResult {
|
||||
if (context.player?.isSneaking != true) {
|
||||
val blockEntity = context.world.getBlockEntity(context.blockPos)
|
||||
if (!context.world.isClient && blockEntity is DeviceBlockEntity) {
|
||||
if (blockEntity is DeviceBlockEntity) {
|
||||
val portName =
|
||||
DeviceBlockInteractions.findUsedPort(context.hitResult, blockEntity.descriptor)
|
||||
if (portName != null) {
|
||||
useOnPort(context, portName)
|
||||
}
|
||||
return ActionResult.success(context.world.isClient)
|
||||
} else {
|
||||
return ActionResult.PASS
|
||||
}
|
||||
return ActionResult.success(context.world.isClient)
|
||||
} else {
|
||||
return context.world.getBlockState(context.blockPos)
|
||||
.onUse(context.world, context.player, context.hand, context.hitResult)
|
||||
|
|
@ -36,41 +38,46 @@ class PatchCableItem(settings: Settings, val color: Byte) : BasicItem(settings)
|
|||
}
|
||||
|
||||
private fun useOnPort(context: ItemUsageContext, portName: PortName) {
|
||||
val player = context.player
|
||||
if (player == null || player !is ServerPlayerEntity) {
|
||||
return
|
||||
}
|
||||
val isClient = context.world.isClient
|
||||
val player = context.player ?: return
|
||||
|
||||
val ongoingConnection = ongoingConnectionsServer[player]
|
||||
val ongoingConnection =
|
||||
if (isClient) ongoingConnectionsClient[player] else ongoingConnectionsServer[player]
|
||||
if (ongoingConnection == null) {
|
||||
// Do this action both on the client and the server, such that the player visually
|
||||
// sees that a port is being connected.
|
||||
startConnecting(player, OngoingConnection(context.blockPos, portName, color))
|
||||
ServerPlayNetworking.send(
|
||||
player,
|
||||
StartConnectingPorts.id,
|
||||
StartConnectingPorts(context.blockPos, portName.toString(), color).serialize()
|
||||
)
|
||||
if (player is ServerPlayerEntity) {
|
||||
ServerPlayNetworking.send(
|
||||
player,
|
||||
StartConnectingPorts.id,
|
||||
StartConnectingPorts(context.blockPos, portName.toString(), color).serialize()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (portName.direction != ongoingConnection.portName.direction) {
|
||||
val world = context.world as ServerWorld
|
||||
val world = context.world
|
||||
|
||||
val fromPosition = ongoingConnection.blockPosition
|
||||
val fromPort = ongoingConnection.portName
|
||||
val toPosition = context.blockPos
|
||||
|
||||
val witnesses = PlayerLookup.tracking(world, fromPosition).toHashSet()
|
||||
witnesses.addAll(PlayerLookup.tracking(world, toPosition))
|
||||
for (witness in witnesses) {
|
||||
ServerPlayNetworking.send(
|
||||
witness,
|
||||
ConnectPorts.id,
|
||||
ConnectPorts(
|
||||
fromPosition,
|
||||
fromPort.id.toString(),
|
||||
toPosition,
|
||||
portName.id.toString(),
|
||||
ongoingConnection.color,
|
||||
).serialize()
|
||||
)
|
||||
if (world is ServerWorld) {
|
||||
val witnesses = PlayerLookup.tracking(world, fromPosition).toHashSet()
|
||||
witnesses.addAll(PlayerLookup.tracking(world, toPosition))
|
||||
for (witness in witnesses) {
|
||||
ServerPlayNetworking.send(
|
||||
witness,
|
||||
ConnectPorts.id,
|
||||
ConnectPorts(
|
||||
fromPosition,
|
||||
fromPort.id.toString(),
|
||||
toPosition,
|
||||
portName.id.toString(),
|
||||
ongoingConnection.color,
|
||||
).serialize()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val fromBlockEntity = world.getBlockEntity(fromPosition)
|
||||
|
|
@ -105,8 +112,10 @@ class PatchCableItem(settings: Settings, val color: Byte) : BasicItem(settings)
|
|||
internal val ongoingConnectionsClient = hashMapOf<ClientPlayerEntity, OngoingConnection>()
|
||||
|
||||
private fun clearOngoingConnection(player: PlayerEntity) {
|
||||
ongoingConnectionsServer.remove(player)
|
||||
ongoingConnectionsClient.remove(player)
|
||||
when (player) {
|
||||
is ServerPlayerEntity -> ongoingConnectionsServer.remove(player)
|
||||
is ClientPlayerEntity -> ongoingConnectionsClient.remove(player)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun removeAllConnectionsAtBlock(blockPosition: BlockPos) {
|
||||
|
|
|
|||
43
src/main/kotlin/net/liquidev/dawd3/net/DisconnectPort.kt
Normal file
43
src/main/kotlin/net/liquidev/dawd3/net/DisconnectPort.kt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package net.liquidev.dawd3.net
|
||||
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
|
||||
import net.liquidev.dawd3.Mod
|
||||
import net.liquidev.dawd3.audio.device.PortName
|
||||
import net.liquidev.dawd3.block.device.DeviceBlockEntity
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
/** S2C packet notifying clients about a client disconnecting the cables from a port. */
|
||||
data class DisconnectPort(
|
||||
val position: BlockPos,
|
||||
val port: Identifier,
|
||||
) {
|
||||
companion object {
|
||||
val id = Identifier(Mod.id, "disconnect_port")
|
||||
|
||||
fun registerClientReceiver() {
|
||||
ClientPlayNetworking.registerGlobalReceiver(id) { client, _, buffer, _ ->
|
||||
val packet = deserialize(buffer)
|
||||
client.execute {
|
||||
val world = client.world ?: return@execute
|
||||
val blockEntity = world.getBlockEntity(packet.position) as? DeviceBlockEntity
|
||||
?: return@execute
|
||||
val portName = PortName.fromString(packet.port.toString()) ?: return@execute
|
||||
blockEntity.severConnectionsInPort(portName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserialize(buffer: PacketByteBuf) =
|
||||
DisconnectPort(
|
||||
position = buffer.readBlockPos(),
|
||||
port = buffer.readIdentifier(),
|
||||
)
|
||||
}
|
||||
|
||||
fun serialize() = PacketByteBufs.create()
|
||||
.writeBlockPos(position)
|
||||
.writeIdentifier(port)
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ object Packets {
|
|||
fun registerClientReceivers() {
|
||||
StartConnectingPorts.registerClientReceiver()
|
||||
ConnectPorts.registerClientReceiver()
|
||||
DisconnectPort.registerClientReceiver()
|
||||
TweakControl.registerClientReceiver()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@
|
|||
"defaultRequire": 1
|
||||
},
|
||||
"mixins": [
|
||||
"DebugHudMixin",
|
||||
"PauseMixin",
|
||||
"PlayerItemSwitchMixin"
|
||||
],
|
||||
"client": [
|
||||
"DebugHudMixin",
|
||||
"PauseMixin"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue