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
This commit is contained in:
JozsefA 2021-03-04 15:34:17 -08:00
parent 9062f1c8fa
commit b511a20814
8 changed files with 190 additions and 45 deletions

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.logistics.block.belts.tunnel;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
import com.simibubi.create.content.logistics.block.FlapData; 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.render.backend.instancing.*;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
@ -73,7 +73,7 @@ public class BeltTunnelInstance extends TileEntityInstance<BeltTunnelTileEntity>
@Override @Override
public void tick() { public void tick() {
tunnelFlaps.forEach((direction, keys) -> { tunnelFlaps.forEach((direction, keys) -> {
InterpolatedChasingValue flapValue = tile.flaps.get(direction); InterpolatedValue flapValue = tile.flaps.get(direction);
if (flapValue == null) { if (flapValue == null) {
return; return;
} }

View file

@ -3,6 +3,9 @@ package com.simibubi.create.content.logistics.block.belts.tunnel;
import java.util.*; import java.util.*;
import com.simibubi.create.CreateClient; 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.FastRenderDispatcher;
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
import net.minecraftforge.api.distmarker.Dist; 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.AllBlocks;
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock.Shape; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock.Shape;
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock; 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.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -68,22 +70,6 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe
compound.put("Sides", sidesNBT); compound.put("Sides", sidesNBT);
super.write(compound, clientPacket); super.write(compound, clientPacket);
if (!clientPacket)
return;
flapsNBT = new ListNBT();
if (!flapsToSend.isEmpty()) {
for (Pair<Direction, Boolean> 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 @Override
@ -116,17 +102,6 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe
if (clientPacket) if (clientPacket)
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this)); 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() { public void updateTunnelConnections() {
@ -158,8 +133,8 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe
continue; continue;
flaps.put(direction, new InterpolatedChasingValue().start(.25f) flaps.put(direction, new InterpolatedChasingValue().start(.25f)
.target(0) .target(0)
.withSpeed(.05f)); .withSpeed(.05f));
} }
sendData(); sendData();
} }
@ -188,12 +163,18 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe
super.tick(); super.tick();
if (!world.isRemote) { if (!world.isRemote) {
if (!flapsToSend.isEmpty()) if (!flapsToSend.isEmpty())
sendData(); sendFlaps();
return; return;
} }
flaps.forEach((d, value) -> value.tick()); flaps.forEach((d, value) -> value.tick());
} }
private void sendFlaps() {
AllPackets.channel.send(packetTarget(), new TunnelFlapPacket(this, flapsToSend));
flapsToSend.clear();
}
@Override @Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {} public void addBehaviours(List<TileEntityBehaviour> behaviours) {}

View file

@ -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.contraptions.relays.belt.transport.TransportedItemStack;
import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity; 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.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.config.AllConfigs;
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
import com.simibubi.create.foundation.item.TooltipHelper; 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.FastRenderDispatcher;
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; 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.api.distmarker.Dist;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.network.PacketDistributor;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
@ -50,7 +54,6 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
private WeakReference<ItemEntity> lastObserved; // In-world Extractors only private WeakReference<ItemEntity> lastObserved; // In-world Extractors only
int sendFlap;
InterpolatedChasingValue flap; InterpolatedChasingValue flap;
static enum Mode { static enum Mode {
@ -285,8 +288,11 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
} }
public void flap(boolean inward) { public void flap(boolean inward) {
sendFlap = inward ? 1 : -1; if (!world.isRemote) {
sendData(); AllPackets.channel.send(packetTarget(), new FunnelFlapPacket(this, inward));
} else {
flap.set(inward ? 1 : -1);
}
} }
public boolean hasFlap() { public boolean hasFlap() {
@ -318,20 +324,12 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
protected void write(CompoundNBT compound, boolean clientPacket) { protected void write(CompoundNBT compound, boolean clientPacket) {
super.write(compound, clientPacket); super.write(compound, clientPacket);
compound.putInt("TransferCooldown", extractionCooldown); compound.putInt("TransferCooldown", extractionCooldown);
if (clientPacket && sendFlap != 0) {
compound.putInt("Flap", sendFlap);
sendFlap = 0;
}
} }
@Override @Override
protected void read(CompoundNBT compound, boolean clientPacket) { protected void read(CompoundNBT compound, boolean clientPacket) {
super.read(compound, clientPacket); super.read(compound, clientPacket);
extractionCooldown = compound.getInt("TransferCooldown"); extractionCooldown = compound.getInt("TransferCooldown");
if (clientPacket && compound.contains("Flap")) {
int direction = compound.getInt("Flap");
flap.set(direction);
}
if (clientPacket) if (clientPacket)
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this)); DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this));

View file

@ -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<FunnelTileEntity> {
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);
}
}

View file

@ -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<BeltTunnelTileEntity> {
private List<Pair<Direction, Boolean>> 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<Pair<Direction, Boolean>> flaps) {
super(tile.getPos());
this.flaps = new ArrayList<>(flaps);
}
@Override
protected void writeData(PacketBuffer buffer) {
buffer.writeByte(flaps.size());
for (Pair<Direction, Boolean> flap : flaps) {
buffer.writeByte(flap.getLeft().getIndex());
buffer.writeBoolean(flap.getRight());
}
}
@Override
protected void handlePacket(BeltTunnelTileEntity tile) {
for (Pair<Direction, Boolean> flap : flaps) {
tile.flap(flap.getLeft(), flap.getRight());
}
}
}

View file

@ -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.item.filter.FilterScreenPacket;
import com.simibubi.create.content.logistics.packet.ConfigureFlexcratePacket; import com.simibubi.create.content.logistics.packet.ConfigureFlexcratePacket;
import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket; 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.ConfigureSchematicannonPacket;
import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
@ -86,7 +88,9 @@ public enum AllPackets {
FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new, PLAY_TO_CLIENT), FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new, PLAY_TO_CLIENT), CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new, PLAY_TO_CLIENT),
GANTRY_UPDATE(GantryContraptionUpdatePacket.class, GantryContraptionUpdatePacket::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),
; ;

View file

@ -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 <TE>
*/
public abstract class TileEntityDataPacket<TE extends SyncedTileEntity> 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<NetworkEvent.Context> 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);
}

View file

@ -5,6 +5,9 @@ import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket; import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType; 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 { public abstract class SyncedTileEntity extends TileEntity {
@ -60,4 +63,12 @@ public abstract class SyncedTileEntity extends TileEntity {
sendData(); 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());
}
} }