diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java index 2b6d3ca8f..4334c3aa2 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java @@ -11,6 +11,7 @@ import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.world.ContainerHelper; import net.minecraft.world.MenuProvider; import net.minecraft.world.WorldlyContainer; @@ -18,6 +19,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -119,17 +121,49 @@ public ITextComponent getDisplayName() { }*/ @Override - public void saveAdditional(@NotNull CompoundTag compound) { + public void load(@NotNull CompoundTag compound) { + ContainerHelper.loadAllItems(compound, items); + peripheralSettings = compound.getCompound(PERIPHERAL_SETTINGS_KEY); + super.load(compound); + } + + /** + * will automatically adds shared data at the end + * + * @see saveShared + */ + @Override + protected void saveAdditional(@NotNull CompoundTag compound) { super.saveAdditional(compound); + this.saveShared(compound); ContainerHelper.saveAllItems(compound, items); if (!peripheralSettings.isEmpty()) compound.put(PERIPHERAL_SETTINGS_KEY, peripheralSettings); } + /** + * will automatically adds shared data at the end + * + * @return combined update tag and shared data + * @see saveShared + */ @Override - public void load(@NotNull CompoundTag compound) { - ContainerHelper.loadAllItems(compound, items); - peripheralSettings = compound.getCompound(PERIPHERAL_SETTINGS_KEY); - super.load(compound); + public CompoundTag getUpdateTag() { + final CompoundTag compound = super.getUpdateTag(); + this.saveShared(compound); + return compound; + } + + /** + * define datas that should both be saved on server and sync to client + * + * @see saveAdditional + * @see getUpdateTag + */ + protected void saveShared(@NotNull CompoundTag compound) {} + + @Override + public ClientboundBlockEntityDataPacket getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); } @Override @@ -171,12 +205,13 @@ public int getContainerSize() { @Override public boolean isEmpty() { for (ItemStack itemStack : items) { - if (itemStack.isEmpty()) return true; + if (!itemStack.isEmpty()) { + return false; + } } - return false; + return true; } - @NotNull @Override public ItemStack getItem(int index) { @@ -189,7 +224,11 @@ public ItemStack getItem(int index) { @NotNull @Override public ItemStack removeItem(int index, int count) { - return ContainerHelper.removeItem(items, index, count); + ItemStack removed = ContainerHelper.removeItem(items, index, count); + if (!removed.isEmpty()) { + this.setChanged(); + } + return removed; } @NotNull @@ -204,6 +243,7 @@ public void setItem(int index, @NotNull ItemStack stack) { if (stack.getCount() > getMaxStackSize()) { stack.setCount(getMaxStackSize()); } + this.setChanged(); } @Override @@ -214,6 +254,7 @@ public boolean stillValid(@NotNull Player player) { @Override public void clearContent() { items.clear(); + this.setChanged(); } public CompoundTag getPeripheralSettings() { @@ -222,7 +263,22 @@ public CompoundTag getPeripheralSettings() { @Override public void markSettingsChanged() { - setChanged(); + this.setChanged(); + } + + /** + * set this block entity as {@link setChanged changed}, and sync the change to client + * + * @see saveShared + * @see getUpdateTag + */ + public void markDataSync() { + Level level = this.getLevel(); + if (level == null || level.isClientSide) { + return; + } + this.setChanged(); + level.sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 0 /* no use on server-side */); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/InventoryManagerEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/InventoryManagerEntity.java index 533be4028..4131bc519 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/InventoryManagerEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/InventoryManagerEntity.java @@ -6,8 +6,6 @@ import de.srendi.advancedperipherals.common.container.InventoryManagerContainer; import de.srendi.advancedperipherals.common.items.MemoryCardItem; import de.srendi.advancedperipherals.common.setup.BlockEntityTypes; -import de.srendi.advancedperipherals.network.APNetworking; -import de.srendi.advancedperipherals.network.toclient.InventoryManagerUpdatePacket; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -39,9 +37,6 @@ protected InventoryManagerPeripheral createPeripheral() { @Override public InventoryManagerContainer createContainer(int id, Inventory playerInventory, BlockPos pos, Level world) { - // Update the clients instance of the inventory manager so the UI shows the correct owner - updateClient(); - return new InventoryManagerContainer(id, playerInventory, pos, world); } @@ -58,6 +53,7 @@ public boolean canPlaceItemThroughFace(int index, @NotNull ItemStack itemStackIn @Override public void setItem(int index, @NotNull ItemStack stack) { + boolean shouldClearOwner = false; if (stack.getItem() instanceof MemoryCardItem) { if (stack.hasTag() && stack.getTag().contains("ownerId")) { UUID owner = stack.getTag().getUUID("ownerId"); @@ -66,12 +62,14 @@ public void setItem(int index, @NotNull ItemStack stack) { stack.getTag().remove("owner"); } else if (stack != this.getItem(index)) { // Only clear owner when the new card item is not the current item - this.owner = null; + shouldClearOwner = true; } } else { - owner = null; + shouldClearOwner = true; + } + if (shouldClearOwner && this.getLevel() != null && !this.getLevel().isClientSide) { + this.owner = null; } - updateClient(); super.setItem(index, stack); } @@ -87,22 +85,24 @@ public void load(@NotNull CompoundTag data) { this.owner = data.getUUID("ownerId"); } super.load(data); - // Fresh the memory card for backward compatibility - this.setItem(0, this.getItem(0)); } @Override - public void saveAdditional(@NotNull CompoundTag data) { - super.saveAdditional(data); + protected void saveShared(@NotNull CompoundTag data) { + super.saveShared(data); if (this.owner != null) { data.putUUID("ownerId", this.owner); } } - public void updateClient() { - if (level.isClientSide()) - return; - APNetworking.sendToAllAround(new InventoryManagerUpdatePacket(owner != null, this.owner, this.getBlockPos()), this.getLevel().dimension(), this.getBlockPos(), 10); + @Override + public void onLoad() { + super.onLoad(); + // Fresh the memory card for backward compatibility + // TODO: remove in 0.8 + if (!this.getLevel().isClientSide) { + this.setItem(0, this.getItem(0)); + } } public Player getOwnerPlayer() { @@ -113,11 +113,11 @@ public Player getOwnerPlayer() { return player; } - public void setOwner(UUID owner) { - this.owner = owner; - } - public UUID getOwner() { return owner; } + + public void setOwner(UUID owner) { + this.owner = owner; + } } diff --git a/src/main/java/de/srendi/advancedperipherals/network/APNetworking.java b/src/main/java/de/srendi/advancedperipherals/network/APNetworking.java index d399c1338..89089c80d 100644 --- a/src/main/java/de/srendi/advancedperipherals/network/APNetworking.java +++ b/src/main/java/de/srendi/advancedperipherals/network/APNetworking.java @@ -2,7 +2,6 @@ import de.srendi.advancedperipherals.AdvancedPeripherals; import de.srendi.advancedperipherals.network.base.IPacket; -import de.srendi.advancedperipherals.network.toclient.InventoryManagerUpdatePacket; import de.srendi.advancedperipherals.network.toclient.ToastToClientPacket; import de.srendi.advancedperipherals.network.toclient.UsernameToCachePacket; import de.srendi.advancedperipherals.network.toserver.RetrieveUsernamePacket; @@ -33,7 +32,6 @@ public class APNetworking { public static void init() { registerServerToClient(ToastToClientPacket.class, ToastToClientPacket::decode); registerServerToClient(UsernameToCachePacket.class, UsernameToCachePacket::decode); - registerServerToClient(InventoryManagerUpdatePacket.class, InventoryManagerUpdatePacket::decode); registerClientToServer(RetrieveUsernamePacket.class, RetrieveUsernamePacket::decode); } diff --git a/src/main/java/de/srendi/advancedperipherals/network/toclient/InventoryManagerUpdatePacket.java b/src/main/java/de/srendi/advancedperipherals/network/toclient/InventoryManagerUpdatePacket.java deleted file mode 100644 index 67046ef33..000000000 --- a/src/main/java/de/srendi/advancedperipherals/network/toclient/InventoryManagerUpdatePacket.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.srendi.advancedperipherals.network.toclient; - -import de.srendi.advancedperipherals.common.blocks.blockentities.InventoryManagerEntity; -import de.srendi.advancedperipherals.network.base.IPacket; -import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.network.NetworkEvent; - -import java.util.UUID; - -public class InventoryManagerUpdatePacket implements IPacket { - - public boolean hasOwner; - public UUID owner; - public BlockPos pos; - - public InventoryManagerUpdatePacket(boolean hasOwner, UUID owner, BlockPos pos) { - this.hasOwner = hasOwner; - this.owner = owner; - this.pos = pos; - } - - @Override - public void handle(NetworkEvent.Context context) { - Minecraft minecraft = Minecraft.getInstance(); - BlockEntity blockEntity = minecraft.level.getBlockEntity(pos); - if (blockEntity instanceof InventoryManagerEntity inventoryManagerEntity) - inventoryManagerEntity.setOwner(hasOwner ? owner : null); - } - - @Override - public void encode(FriendlyByteBuf buffer) { - buffer.writeBoolean(hasOwner); - if (hasOwner) - buffer.writeUUID(owner); - buffer.writeBlockPos(pos); - } - - public static InventoryManagerUpdatePacket decode(FriendlyByteBuf buffer) { - boolean hasOwner = buffer.readBoolean(); - return new InventoryManagerUpdatePacket(hasOwner, hasOwner ? buffer.readUUID() : null, buffer.readBlockPos()); - } -}