From b511a208149671cc8b471418f7417d41e294962a Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 4 Mar 2021 15:34:17 -0800 Subject: [PATCH] Flappy packets. - Instead of sending the entire tile entity (and maybe even chunk), send just what we need to. - Avoids unnecessary chunk rebuilds when flaps flap. - Beginning of a larger process to replace calls to SyncedTileEntity#sendData --- .../belts/tunnel/BeltTunnelInstance.java | 4 +- .../belts/tunnel/BeltTunnelTileEntity.java | 43 ++++--------- .../block/funnel/FunnelTileEntity.java | 20 +++--- .../logistics/packet/FunnelFlapPacket.java | 33 ++++++++++ .../logistics/packet/TunnelFlapPacket.java | 62 +++++++++++++++++++ .../foundation/networking/AllPackets.java | 6 +- .../networking/TileEntityDataPacket.java | 56 +++++++++++++++++ .../tileEntity/SyncedTileEntity.java | 11 ++++ 8 files changed, 190 insertions(+), 45 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/logistics/packet/FunnelFlapPacket.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/packet/TunnelFlapPacket.java create mode 100644 src/main/java/com/simibubi/create/foundation/networking/TileEntityDataPacket.java diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java index 05671ba32..afbfcc6a0 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java @@ -3,7 +3,7 @@ package com.simibubi.create.content.logistics.block.belts.tunnel; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.logistics.block.FlapData; -import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; +import com.simibubi.create.foundation.gui.widgets.InterpolatedValue; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.tileentity.TileEntityType; @@ -73,7 +73,7 @@ public class BeltTunnelInstance extends TileEntityInstance @Override public void tick() { tunnelFlaps.forEach((direction, keys) -> { - InterpolatedChasingValue flapValue = tile.flaps.get(direction); + InterpolatedValue flapValue = tile.flaps.get(direction); if (flapValue == null) { return; } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java index 77938f65f..c6e805287 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java @@ -3,6 +3,9 @@ package com.simibubi.create.content.logistics.block.belts.tunnel; import java.util.*; import com.simibubi.create.CreateClient; +import com.simibubi.create.content.logistics.packet.TunnelFlapPacket; +import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; +import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import net.minecraftforge.api.distmarker.Dist; @@ -12,7 +15,6 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock.Shape; import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock; -import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.Iterate; @@ -68,22 +70,6 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe compound.put("Sides", sidesNBT); super.write(compound, clientPacket); - - if (!clientPacket) - return; - - flapsNBT = new ListNBT(); - if (!flapsToSend.isEmpty()) { - for (Pair pair : flapsToSend) { - CompoundNBT flap = new CompoundNBT(); - flap.putInt("Flap", pair.getKey() - .getIndex()); - flap.putBoolean("FlapInward", pair.getValue()); - flapsNBT.add(flap); - } - compound.put("TriggerFlaps", flapsNBT); - flapsToSend.clear(); - } } @Override @@ -116,17 +102,6 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe if (clientPacket) DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this)); - - if (!clientPacket) - return; - if (!compound.contains("TriggerFlaps")) - return; - flapsNBT = compound.getList("TriggerFlaps", NBT.TAG_COMPOUND); - for (INBT inbt : flapsNBT) { - CompoundNBT flap = (CompoundNBT) inbt; - Direction side = Direction.byIndex(flap.getInt("Flap")); - flap(side, flap.getBoolean("FlapInward")); - } } public void updateTunnelConnections() { @@ -158,8 +133,8 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe continue; flaps.put(direction, new InterpolatedChasingValue().start(.25f) - .target(0) - .withSpeed(.05f)); + .target(0) + .withSpeed(.05f)); } sendData(); } @@ -188,12 +163,18 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe super.tick(); if (!world.isRemote) { if (!flapsToSend.isEmpty()) - sendData(); + sendFlaps(); return; } flaps.forEach((d, value) -> value.tick()); } + private void sendFlaps() { + AllPackets.channel.send(packetTarget(), new TunnelFlapPacket(this, flapsToSend)); + + flapsToSend.clear(); + } + @Override public void addBehaviours(List behaviours) {} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java index 665f49802..c4d0516a1 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java @@ -12,9 +12,12 @@ import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity; import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape; +import com.simibubi.create.content.logistics.packet.FunnelFlapPacket; +import com.simibubi.create.content.logistics.packet.TunnelFlapPacket; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; import com.simibubi.create.foundation.item.TooltipHelper; +import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; @@ -39,6 +42,7 @@ import net.minecraft.util.math.Vec3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -50,7 +54,6 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn private WeakReference lastObserved; // In-world Extractors only - int sendFlap; InterpolatedChasingValue flap; static enum Mode { @@ -285,8 +288,11 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn } public void flap(boolean inward) { - sendFlap = inward ? 1 : -1; - sendData(); + if (!world.isRemote) { + AllPackets.channel.send(packetTarget(), new FunnelFlapPacket(this, inward)); + } else { + flap.set(inward ? 1 : -1); + } } public boolean hasFlap() { @@ -318,20 +324,12 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn protected void write(CompoundNBT compound, boolean clientPacket) { super.write(compound, clientPacket); compound.putInt("TransferCooldown", extractionCooldown); - if (clientPacket && sendFlap != 0) { - compound.putInt("Flap", sendFlap); - sendFlap = 0; - } } @Override protected void read(CompoundNBT compound, boolean clientPacket) { super.read(compound, clientPacket); extractionCooldown = compound.getInt("TransferCooldown"); - if (clientPacket && compound.contains("Flap")) { - int direction = compound.getInt("Flap"); - flap.set(direction); - } if (clientPacket) DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this)); diff --git a/src/main/java/com/simibubi/create/content/logistics/packet/FunnelFlapPacket.java b/src/main/java/com/simibubi/create/content/logistics/packet/FunnelFlapPacket.java new file mode 100644 index 000000000..554643ce5 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/packet/FunnelFlapPacket.java @@ -0,0 +1,33 @@ +package com.simibubi.create.content.logistics.packet; + +import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity; +import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity; +import com.simibubi.create.foundation.networking.TileEntityDataPacket; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.Direction; + +public class FunnelFlapPacket extends TileEntityDataPacket { + + private final boolean inwards; + + public FunnelFlapPacket(PacketBuffer buffer) { + super(buffer); + + inwards = buffer.readBoolean(); + } + + public FunnelFlapPacket(FunnelTileEntity tile, boolean inwards) { + super(tile.getPos()); + this.inwards = inwards; + } + + @Override + protected void writeData(PacketBuffer buffer) { + buffer.writeBoolean(inwards); + } + + @Override + protected void handlePacket(FunnelTileEntity tile) { + tile.flap(inwards); + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/packet/TunnelFlapPacket.java b/src/main/java/com/simibubi/create/content/logistics/packet/TunnelFlapPacket.java new file mode 100644 index 000000000..d57360ac2 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/packet/TunnelFlapPacket.java @@ -0,0 +1,62 @@ +package com.simibubi.create.content.logistics.packet; + +import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance; +import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity; +import com.simibubi.create.foundation.networking.SimplePacketBase; +import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket; +import com.simibubi.create.foundation.networking.TileEntityDataPacket; +import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.network.NetworkEvent; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class TunnelFlapPacket extends TileEntityDataPacket { + + private List> flaps; + + public TunnelFlapPacket(PacketBuffer buffer) { + super(buffer); + + byte size = buffer.readByte(); + + this.flaps = new ArrayList<>(size); + + for (int i = 0; i < size; i++) { + Direction direction = Direction.byIndex(buffer.readByte()); + boolean inwards = buffer.readBoolean(); + + flaps.add(Pair.of(direction, inwards)); + } + } + + public TunnelFlapPacket(BeltTunnelTileEntity tile, List> flaps) { + super(tile.getPos()); + + this.flaps = new ArrayList<>(flaps); + } + + @Override + protected void writeData(PacketBuffer buffer) { + buffer.writeByte(flaps.size()); + + for (Pair flap : flaps) { + buffer.writeByte(flap.getLeft().getIndex()); + buffer.writeBoolean(flap.getRight()); + } + } + + @Override + protected void handlePacket(BeltTunnelTileEntity tile) { + for (Pair flap : flaps) { + tile.flap(flap.getLeft(), flap.getRight()); + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index 0f5fca06b..044e806d5 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -28,6 +28,8 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.ArmPlacementPac import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket; import com.simibubi.create.content.logistics.packet.ConfigureFlexcratePacket; import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket; +import com.simibubi.create.content.logistics.packet.FunnelFlapPacket; +import com.simibubi.create.content.logistics.packet.TunnelFlapPacket; import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket; import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; @@ -86,7 +88,9 @@ public enum AllPackets { FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new, PLAY_TO_CLIENT), CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new, PLAY_TO_CLIENT), GANTRY_UPDATE(GantryContraptionUpdatePacket.class, GantryContraptionUpdatePacket::new, PLAY_TO_CLIENT), - BLOCK_HIGHLIGHT(HighlightPacket.class, HighlightPacket::new, PLAY_TO_CLIENT) + BLOCK_HIGHLIGHT(HighlightPacket.class, HighlightPacket::new, PLAY_TO_CLIENT), + TUNNEL_FLAP(TunnelFlapPacket.class, TunnelFlapPacket::new, PLAY_TO_CLIENT), + FUNNEL_FLAP(FunnelFlapPacket.class, FunnelFlapPacket::new, PLAY_TO_CLIENT), ; diff --git a/src/main/java/com/simibubi/create/foundation/networking/TileEntityDataPacket.java b/src/main/java/com/simibubi/create/foundation/networking/TileEntityDataPacket.java new file mode 100644 index 000000000..2acdffb6d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/networking/TileEntityDataPacket.java @@ -0,0 +1,56 @@ +package com.simibubi.create.foundation.networking; + +import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity; +import com.simibubi.create.foundation.tileEntity.SyncedTileEntity; +import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.network.NetworkEvent; + +import java.util.function.Supplier; + +/** + * A server to client version of {@link TileEntityConfigurationPacket} + * @param + */ +public abstract class TileEntityDataPacket extends SimplePacketBase { + + protected BlockPos tilePos; + + public TileEntityDataPacket(PacketBuffer buffer) { + tilePos = buffer.readBlockPos(); + } + + public TileEntityDataPacket(BlockPos pos) { + this.tilePos = pos; + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeBlockPos(tilePos); + writeData(buffer); + } + + @Override + public void handle(Supplier context) { + NetworkEvent.Context ctx = context.get(); + ctx.enqueueWork(() -> { + ClientWorld world = Minecraft.getInstance().world; + + if (world == null) return; + + TileEntity tile = world.getTileEntity(tilePos); + + if (tile instanceof SyncedTileEntity) { + handlePacket((TE) tile); + } + }); + ctx.setPacketHandled(true); + } + + protected abstract void writeData(PacketBuffer buffer); + + protected abstract void handlePacket(TE tile); +} diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/SyncedTileEntity.java b/src/main/java/com/simibubi/create/foundation/tileEntity/SyncedTileEntity.java index be1c6b74d..2d2a1293c 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/SyncedTileEntity.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/SyncedTileEntity.java @@ -5,6 +5,9 @@ import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SUpdateTileEntityPacket; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.math.SectionPos; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.fml.network.PacketDistributor; public abstract class SyncedTileEntity extends TileEntity { @@ -60,4 +63,12 @@ public abstract class SyncedTileEntity extends TileEntity { sendData(); } + public PacketDistributor.PacketTarget packetTarget() { + return PacketDistributor.TRACKING_CHUNK.with(this::containedChunk); + } + + public Chunk containedChunk() { + SectionPos sectionPos = SectionPos.from(pos); + return world.getChunk(sectionPos.getSectionX(), sectionPos.getSectionZ()); + } }