Add network messages for bus and run states.

This commit is contained in:
Florian Nücke
2020-12-09 13:12:06 +01:00
parent b7fc45f958
commit 772e592558
4 changed files with 160 additions and 11 deletions

View File

@@ -6,8 +6,10 @@ import li.cil.oc2.common.network.message.ComputerRunStateMessage;
import li.cil.oc2.common.network.message.TerminalBlockInputMessage;
import li.cil.oc2.common.network.message.TerminalBlockOutputMessage;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.fml.network.NetworkDirection;
import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.PacketDistributor;
import net.minecraftforge.fml.network.simple.SimpleChannel;
public final class Network {
@@ -33,6 +35,22 @@ public final class Network {
.decoder(TerminalBlockInputMessage::new)
.consumer(TerminalBlockInputMessage::handleMessage)
.add();
INSTANCE.messageBuilder(ComputerRunStateMessage.class, getNextPacketId(), NetworkDirection.PLAY_TO_CLIENT)
.encoder(ComputerRunStateMessage::toBytes)
.decoder(ComputerRunStateMessage::new)
.consumer(ComputerRunStateMessage::handleMessage)
.add();
INSTANCE.messageBuilder(ComputerBusStateMessage.class, getNextPacketId(), NetworkDirection.PLAY_TO_CLIENT)
.encoder(ComputerBusStateMessage::toBytes)
.decoder(ComputerBusStateMessage::new)
.consumer(ComputerBusStateMessage::handleMessage)
.add();
}
public static <T> void sendToClientsTrackingChunk(final T message, final Chunk chunk) {
Network.INSTANCE.send(PacketDistributor.TRACKING_CHUNK.with(() -> chunk), message);
}
private static int getNextPacketId() {

View File

@@ -0,0 +1,40 @@
package li.cil.oc2.common.network.message;
import li.cil.oc2.common.bus.TileEntityDeviceBusController;
import li.cil.oc2.common.network.MessageUtils;
import li.cil.oc2.common.tile.ComputerTileEntity;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.network.NetworkEvent;
import java.util.function.Supplier;
public class ComputerBusStateMessage {
private BlockPos pos;
private TileEntityDeviceBusController.State busState;
public ComputerBusStateMessage(final ComputerTileEntity tileEntity) {
this.pos = tileEntity.getPos();
this.busState = tileEntity.getBusState();
}
public ComputerBusStateMessage(final PacketBuffer buffer) {
fromBytes(buffer);
}
public static boolean handleMessage(final ComputerBusStateMessage message, final Supplier<NetworkEvent.Context> context) {
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
(tileEntity) -> tileEntity.setBusStateClient(message.busState)));
return true;
}
public void fromBytes(final PacketBuffer buffer) {
pos = buffer.readBlockPos();
busState = buffer.readEnumValue(TileEntityDeviceBusController.State.class);
}
public static void toBytes(final ComputerBusStateMessage message, final PacketBuffer buffer) {
buffer.writeBlockPos(message.pos);
buffer.writeEnumValue(message.busState);
}
}

View File

@@ -0,0 +1,39 @@
package li.cil.oc2.common.network.message;
import li.cil.oc2.common.network.MessageUtils;
import li.cil.oc2.common.tile.ComputerTileEntity;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.network.NetworkEvent;
import java.util.function.Supplier;
public class ComputerRunStateMessage {
private BlockPos pos;
private ComputerTileEntity.RunState runState;
public ComputerRunStateMessage(final ComputerTileEntity tileEntity) {
this.pos = tileEntity.getPos();
this.runState = tileEntity.getRunState();
}
public ComputerRunStateMessage(final PacketBuffer buffer) {
fromBytes(buffer);
}
public static boolean handleMessage(final ComputerRunStateMessage message, final Supplier<NetworkEvent.Context> context) {
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
(tileEntity) -> tileEntity.setRunStateClient(message.runState)));
return true;
}
public void fromBytes(final PacketBuffer buffer) {
pos = buffer.readBlockPos();
runState = buffer.readEnumValue(ComputerTileEntity.RunState.class);
}
public static void toBytes(final ComputerRunStateMessage message, final PacketBuffer buffer) {
buffer.writeBlockPos(message.pos);
buffer.writeEnumValue(message.runState);
}
}

View File

@@ -30,9 +30,11 @@ import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.fml.network.PacketDistributor;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -58,7 +60,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
private static final int DEVICE_LOAD_RETRY_INTERVAL = 10 * 20; // In ticks.
private enum RunState {
public enum RunState {
STOPPED,
LOADING_DEVICES,
RUNNING,
@@ -110,7 +112,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
return;
}
runState = RunState.LOADING_DEVICES;
setRunState(RunState.LOADING_DEVICES);
loadDevicesDelay = 0;
}
@@ -120,15 +122,39 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
}
if (runState == RunState.LOADING_DEVICES) {
runState = RunState.STOPPED;
setRunState(RunState.STOPPED);
return;
}
stopRunnerAndUnloadDevices();
}
public boolean isRunning() {
return runner != null;
public TileEntityDeviceBusController.State getBusState() {
return busState;
}
public RunState getRunState() {
return runState;
}
public void handleNeighborChanged(final BlockPos pos) {
busElement.handleNeighborChanged(pos);
}
@OnlyIn(Dist.CLIENT)
public void setRunStateClient(final RunState value) {
final World world = getWorld();
if (world != null && world.isRemote()) {
runState = value;
}
}
@OnlyIn(Dist.CLIENT)
public void setBusStateClient(final TileEntityDeviceBusController.State value) {
final World world = getWorld();
if (world != null && world.isRemote()) {
busState = value;
}
}
@Override
@@ -168,7 +194,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
runner = new ConsoleRunner(virtualMachine);
}
runState = RunState.RUNNING;
setRunState(RunState.RUNNING);
// Only start running next tick. This gives loaded devices one tick to do async
// initialization. This is used by RAM to restore data from disk, for example.
@@ -188,6 +214,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
@Override
protected void initializeClient() {
super.initializeClient();
terminal.setDisplayOnly(true);
}
@@ -195,6 +222,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
protected void initializeServer() {
super.initializeServer();
busElement.initialize();
ServerScheduler.schedule(() -> chunk = requireNonNull(getWorld()).getChunkAt(getPos()));
}
@@ -212,6 +240,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
result.put(TERMINAL_NBT_TAG_NAME, NBTSerialization.serialize(terminal));
result.putInt(BUS_STATE_NBT_TAG_NAME, busState.ordinal());
result.putInt(RUN_STATE_NBT_TAG_NAME, runState.ordinal());
return result;
}
@@ -222,6 +251,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
NBTSerialization.deserialize(tag.getCompound(TERMINAL_NBT_TAG_NAME), terminal);
busState = TileEntityDeviceBusController.State.values()[tag.getInt(BUS_STATE_NBT_TAG_NAME)];
runState = RunState.values()[tag.getInt(RUN_STATE_NBT_TAG_NAME)];
}
@Override
@@ -283,7 +313,9 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
runState = RunState.LOADING_DEVICES;
} else {
runState = NBTUtils.getEnum(compound, RUN_STATE_NBT_TAG_NAME, RunState.class);
if (runState == RunState.RUNNING) {
if (runState == null) {
runState = RunState.STOPPED;
} else if (runState == RunState.RUNNING) {
runState = RunState.LOADING_DEVICES;
}
}
@@ -349,10 +381,30 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
virtualMachine.vmAdapter.unload();
}
private void setBusState(final TileEntityDeviceBusController.State value) {
if (value == busState) {
return;
}
busState = value;
Network.sendToClientsTrackingChunk(new ComputerBusStateMessage(this), chunk);
}
private void setRunState(final RunState value) {
if (value == runState) {
return;
}
runState = value;
Network.sendToClientsTrackingChunk(new ComputerRunStateMessage(this), chunk);
}
private void stopRunnerAndUnloadDevices() {
joinVirtualMachine();
runner = null;
runState = RunState.STOPPED;
setRunState(RunState.STOPPED);
unloadDevices();
virtualMachine.reset();
@@ -467,8 +519,8 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
terminal.putOutput(output);
output.flip();
final TerminalBlockOutputMessage message = new TerminalBlockOutputMessage(ComputerTileEntity.this, output);
Network.INSTANCE.send(PacketDistributor.TRACKING_CHUNK.with(() -> chunk), message);
Network.sendToClientsTrackingChunk(
new TerminalBlockOutputMessage(ComputerTileEntity.this, output), chunk);
}
}
}