Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add to Buffers to DataSlots #279

Merged
merged 13 commits into from
Aug 3, 2023
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
- Fixed IO Config Overlay text rendering. Text has a Z-offset now.
- Fixed negative scale for IO Config for multi blocks
- Fixed Primitive Alloy Smelter not serializing burn time
- Fixed linking between conduit connector shape and selected conduit.
- Fixed linking between conduit connector shape and selected conduit
- Fixed redstone control icons, consistent with 1.12 now.

## 6.0.3-alpha - 2023-07-08
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.enderio.core.common.network.slot.NetworkDataSlot;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;

import java.util.function.Supplier;

Expand All @@ -21,7 +22,7 @@ public void fromNBT(Tag nbt) {
if (nbt instanceof CompoundTag compoundTag) {
getter.get().deserializeNBT(compoundTag);
} else {
throw new IllegalStateException("Invalid compound tag was passed over the network.");
throw new IllegalStateException("Invalid conduit/compound tag was passed over the network.");
}
}

Expand All @@ -36,4 +37,20 @@ protected int hashCode(ConduitBundle value) {
int code = value.serializeNBT().hashCode();
return code;
}

@Override
public void toBuffer(FriendlyByteBuf buf, ConduitBundle value) {
buf.writeNbt(value.serializeNBT());
}

@Override
public ConduitBundle valueFromBuffer(FriendlyByteBuf buf) {
try {
ConduitBundle conduitBundle = getter.get();
conduitBundle.deserializeNBT(buf.readNbt());
return conduitBundle;
} catch (Exception e) {
throw new IllegalStateException("Invalid conduit/compound tag buffer was passed over the network.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
import com.enderio.core.common.network.CoreNetwork;
import com.enderio.core.common.network.S2CDataSlotUpdate;
import com.enderio.core.common.network.slot.NetworkDataSlot;
import io.netty.buffer.Unpooled;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
Expand All @@ -21,14 +24,19 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Base block entity class for EnderIO.
* Handles data slot syncing and capability providers.
*/
public class EnderBlockEntity extends BlockEntity {

public static final String DATA = "Data";
public static final String INDEX = "Index";
private final List<NetworkDataSlot<?>> dataSlots = new ArrayList<>();

private final List<Runnable> afterDataSync = new ArrayList<>();
Expand Down Expand Up @@ -77,43 +85,68 @@ public void clientTick() {
*/
@Override
public CompoundTag getUpdateTag() {
return createDataSlotUpdate(true);
}

/**
* This is the client handling the tag above.
* @param tag The {@link CompoundTag} sent from {@link BlockEntity#getUpdateTag()}
*/
@Override
public void handleUpdateTag(CompoundTag tag) {
clientHandleDataSync(tag);
}

@Nullable
private CompoundTag createDataSlotUpdate(boolean fullUpdate) {
ListTag dataList = new ListTag();
for (int i = 0; i < dataSlots.size(); i++) {
var slot = dataSlots.get(i);
var nbt = slot.serializeNBT(fullUpdate);
var nbt = slot.serializeNBT(true);
if (nbt == null)
continue;

CompoundTag slotTag = new CompoundTag();
slotTag.putInt("Index", i);
slotTag.put("Data", nbt);
slotTag.putInt(INDEX, i);
slotTag.put(DATA, nbt);

dataList.add(slotTag);
}

if (!fullUpdate && dataList.isEmpty()) {
return null;
}

CompoundTag data = new CompoundTag();
data.put("Data", dataList);
data.put(DATA, dataList);
return data;
}

/**
* This is the client handling the tag above.
* @param syncData The {@link CompoundTag} sent from {@link BlockEntity#getUpdateTag()}
*/
@Override
public void handleUpdateTag(CompoundTag syncData) {
if (syncData.contains(DATA, Tag.TAG_LIST)) {
ListTag dataList = syncData.getList(DATA, Tag.TAG_COMPOUND);

for (Tag dataEntry : dataList) {
if (dataEntry instanceof CompoundTag slotData) {
int slotIdx = slotData.getInt(INDEX);
dataSlots.get(slotIdx).fromNBT(slotData.get(DATA));
}
}

for (Runnable task : afterDataSync) {
task.run();
}
}
}

@Nullable
private FriendlyByteBuf createBufferSlotUpdate() {
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
int amount = 0;
for (int i = 0; i < dataSlots.size(); i++) {
NetworkDataSlot<?> networkDataSlot = dataSlots.get(i);
if (networkDataSlot.needsUpdate()) {
amount ++;
buf.writeInt(i);
networkDataSlot.writeBuffer(buf);
}
}
if (amount == 0) {
return null;
}
FriendlyByteBuf result = new FriendlyByteBuf(Unpooled.buffer()); //Use 2 buffers to be able to write the amount of data
result.writeInt(amount);
result.writeBytes(buf.copy());
return result;
}

public void addDataSlot(NetworkDataSlot<?> slot) {
dataSlots.add(slot);
}
Expand All @@ -132,10 +165,11 @@ public <T> void clientUpdateSlot(@Nullable NetworkDataSlot<T> slot, T value) {
}

if (dataSlots.contains(slot)) {
CompoundTag updateData = new CompoundTag();
updateData.putInt("Index", dataSlots.indexOf(slot));
updateData.put("Data", slot.serializeValueNBT(value));
CoreNetwork.sendToServer(new C2SDataSlotChange(getBlockPos(), updateData));
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
buf.writeInt(dataSlots.indexOf(slot));
slot.toBuffer(buf, value);
CoreNetwork.sendToServer(new C2SDataSlotChange(getBlockPos(), buf));
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), Block.UPDATE_NEIGHBORS);
justliliandev marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand All @@ -144,36 +178,34 @@ public <T> void clientUpdateSlot(@Nullable NetworkDataSlot<T> slot, T value) {
*/
@UseOnly(LogicalSide.SERVER)
public void sync() {
var syncData = createDataSlotUpdate(false);
var syncData = createBufferSlotUpdate();
if (syncData != null) {
CoreNetwork.sendToTracking(level.getChunkAt(getBlockPos()), new S2CDataSlotUpdate(getBlockPos(), syncData));
}
}

@UseOnly(LogicalSide.CLIENT)
public void clientHandleDataSync(CompoundTag syncData) {
if (syncData.contains("Data", Tag.TAG_LIST)) {
ListTag dataList = syncData.getList("Data", Tag.TAG_COMPOUND);

for (Tag dataEntry : dataList) {
if (dataEntry instanceof CompoundTag slotData) {
int slotIdx = slotData.getInt("Index");
dataSlots.get(slotIdx).fromNBT(slotData.get("Data"));
}
}
public void clientHandleBufferSync(FriendlyByteBuf buf) {
int amount = buf.readInt();
for (; amount>0; amount--) { //read until we can't
int index = buf.readInt();
dataSlots.get(index).fromBuffer(buf);
}

for (Runnable task : afterDataSync) {
task.run();
}
for (Runnable task : afterDataSync) {
task.run();
}
}

@UseOnly(LogicalSide.SERVER)
public void serverHandleDataChange(CompoundTag data) {
if (data.contains("Index", Tag.TAG_INT) && data.contains("Data")) {
int slotIdx = data.getInt("Index");
dataSlots.get(slotIdx).fromNBT(data.get("Data"));
public void serverHandleBufferChange(FriendlyByteBuf buf) {
int index = -1;
try {
index = buf.readInt();
} catch (Exception e) {
throw new IllegalStateException("Invalid buffer was passed over the network to the server.");
}
dataSlots.get(index).fromBuffer(buf);
}

// endregion
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.enderio.core.common.network;

import com.enderio.core.common.blockentity.EnderBlockEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
Expand All @@ -21,16 +17,16 @@ public class C2SDataSlotChange implements Packet {

// You shouldn't really send null, but its "technically" valid.
@Nullable
private final CompoundTag updateData;
private final FriendlyByteBuf updateData;

public C2SDataSlotChange(BlockPos pos, CompoundTag updateData) {
public C2SDataSlotChange(BlockPos pos, FriendlyByteBuf updateData) {
this.pos = pos;
this.updateData = updateData;
}

public C2SDataSlotChange(FriendlyByteBuf buf) {
pos = buf.readBlockPos();
updateData = buf.readNbt();
updateData = new FriendlyByteBuf(buf.copy());
}

@Override
Expand All @@ -44,13 +40,13 @@ public void handle(NetworkEvent.Context context) {

BlockEntity be = level.getBlockEntity(pos);
if (be instanceof EnderBlockEntity enderBlockEntity) {
enderBlockEntity.serverHandleDataChange(updateData);
enderBlockEntity.serverHandleBufferChange(updateData);
}
}

protected void write(FriendlyByteBuf writeInto) {
writeInto.writeBlockPos(pos);
writeInto.writeNbt(updateData);
writeInto.writeBytes(updateData);
ferriarnus marked this conversation as resolved.
Show resolved Hide resolved
}

public static class Handler extends PacketHandler<C2SDataSlotChange> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
Expand All @@ -19,16 +19,16 @@ public class S2CDataSlotUpdate implements Packet {

// You shouldn't really send null, but its "technically" valid.
@Nullable
private final CompoundTag slotData;
private final FriendlyByteBuf slotData;

public S2CDataSlotUpdate(BlockPos pos, CompoundTag slotData) {
public S2CDataSlotUpdate(BlockPos pos, FriendlyByteBuf buf) {
this.pos = pos;
this.slotData = slotData;
this.slotData = buf;
}

public S2CDataSlotUpdate(FriendlyByteBuf buf) {
pos = buf.readBlockPos();
slotData = buf.readNbt();
slotData = new FriendlyByteBuf(buf.copy());
}

@Override
Expand All @@ -42,14 +42,14 @@ public void handle(NetworkEvent.Context context) {
if (level != null) {
BlockEntity be = level.getBlockEntity(pos);
if (be instanceof EnderBlockEntity enderBlockEntity) {
enderBlockEntity.clientHandleDataSync(slotData);
enderBlockEntity.clientHandleBufferSync(slotData);
}
}
}

protected void write(FriendlyByteBuf writeInto) {
writeInto.writeBlockPos(pos);
writeInto.writeNbt(slotData);
writeInto.writeBytes(slotData);
}

public static class Handler extends PacketHandler<S2CDataSlotUpdate> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.enderio.core.common.network.slot;

import com.enderio.core.EnderCore;
import net.minecraft.nbt.ByteTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;

import java.util.function.Consumer;
import java.util.function.Supplier;
Expand All @@ -26,4 +26,18 @@ protected Boolean valueFromNBT(Tag nbt) {
throw new IllegalStateException("Invalid boolean tag was passed over the network.");
}
}

@Override
public void toBuffer(FriendlyByteBuf buf, Boolean value) {
buf.writeBoolean(value);
}

@Override
public Boolean valueFromBuffer(FriendlyByteBuf buf) {
try {
return buf.readBoolean();
} catch (Exception e) {
throw new IllegalStateException("Invalid boolean buffer was passed over the network.");
}
}
}