Skip to content

Commit 1a1fa75

Browse files
committed
fix: manually synchronize block entity data, component nullability errors
1 parent ab92236 commit 1a1fa75

20 files changed

+325
-104
lines changed

src/main/java/dev/galacticraft/machinelib/api/block/entity/MachineBlockEntity.java

+54-15
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@
4343
import dev.galacticraft.machinelib.client.api.screen.MachineScreen;
4444
import dev.galacticraft.machinelib.impl.Constant;
4545
import dev.galacticraft.machinelib.impl.MachineLib;
46+
import dev.galacticraft.machinelib.impl.network.s2c.BaseMachineUpdatePayload;
47+
import dev.galacticraft.machinelib.impl.network.s2c.SideConfigurationUpdatePayload;
4648
import io.netty.buffer.ByteBuf;
4749
import io.netty.buffer.Unpooled;
4850
import net.fabricmc.fabric.api.blockview.v2.RenderDataBlockEntity;
51+
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
4952
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
5053
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage;
5154
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
@@ -55,31 +58,38 @@
5558
import net.minecraft.core.BlockPos;
5659
import net.minecraft.core.Direction;
5760
import net.minecraft.core.HolderLookup;
58-
import net.minecraft.nbt.*;
61+
import net.minecraft.nbt.ByteTag;
62+
import net.minecraft.nbt.CompoundTag;
63+
import net.minecraft.nbt.LongTag;
64+
import net.minecraft.nbt.Tag;
5965
import net.minecraft.network.RegistryFriendlyByteBuf;
6066
import net.minecraft.network.chat.Component;
6167
import net.minecraft.network.protocol.Packet;
68+
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
69+
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
6270
import net.minecraft.network.protocol.game.ClientGamePacketListener;
63-
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
6471
import net.minecraft.resources.ResourceLocation;
6572
import net.minecraft.server.level.ServerLevel;
6673
import net.minecraft.server.level.ServerPlayer;
6774
import net.minecraft.util.profiling.ProfilerFiller;
6875
import net.minecraft.world.entity.player.Player;
6976
import net.minecraft.world.item.Item;
7077
import net.minecraft.world.item.crafting.RecipeHolder;
78+
import net.minecraft.world.level.ChunkPos;
7179
import net.minecraft.world.level.block.Block;
7280
import net.minecraft.world.level.block.Blocks;
7381
import net.minecraft.world.level.block.entity.BlockEntity;
7482
import net.minecraft.world.level.block.entity.BlockEntityType;
7583
import net.minecraft.world.level.block.state.BlockState;
7684
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
7785
import net.minecraft.world.level.material.Fluid;
78-
import org.jetbrains.annotations.*;
86+
import org.jetbrains.annotations.ApiStatus;
87+
import org.jetbrains.annotations.Contract;
88+
import org.jetbrains.annotations.NotNull;
89+
import org.jetbrains.annotations.Nullable;
7990
import team.reborn.energy.api.EnergyStorage;
8091
import team.reborn.energy.api.EnergyStorageUtil;
8192

82-
import javax.crypto.Mac;
8393
import java.util.Collections;
8494
import java.util.Objects;
8595
import java.util.Optional;
@@ -206,7 +216,7 @@ protected MachineBlockEntity(@NotNull MachineType<? extends MachineBlockEntity,
206216

207217
MachineIOFace[] faces = new MachineIOFace[6];
208218
for (int i = 0; i < faces.length; i++) {
209-
faces[i] = new InternalMachineIoFace();
219+
faces[i] = new InternalMachineIoFace(i);
210220
}
211221
this.configuration = new MachineIOConfig(faces);
212222
this.security = new InternalSecuritySettings();
@@ -334,7 +344,6 @@ public void setRedstoneMode(@NotNull RedstoneMode redstone) {
334344
* Used to determine who can interact with this machine.
335345
*
336346
* @return the security settings of this machine.
337-
* @see MachineConfiguration
338347
*/
339348
@Contract(pure = true)
340349
public final @NotNull SecuritySettings getSecurity() {
@@ -782,6 +791,8 @@ public RegistryFriendlyByteBuf getScreenOpeningData(ServerPlayer player) {
782791

783792
buf.writeBlockPos(this.getBlockPos());
784793
this.configuration.writePacket(buf);
794+
this.security.writePacket(buf);
795+
this.redstone.writePacket(buf);
785796
this.state.writePacket(buf);
786797
this.energyStorage.writePacket(buf);
787798
this.itemStorage.writePacket(buf);
@@ -802,7 +813,7 @@ public RegistryFriendlyByteBuf getScreenOpeningData(ServerPlayer player) {
802813

803814
@Override
804815
public @NotNull MachineRenderData getRenderData() {
805-
return this.getIOConfig();
816+
return this.configuration;
806817
}
807818

808819
@Override
@@ -815,7 +826,26 @@ public CompoundTag getUpdateTag(HolderLookup.Provider registryLookup) {
815826
@Nullable
816827
@Override
817828
public Packet<ClientGamePacketListener> getUpdatePacket() {
818-
return ClientboundBlockEntityDataPacket.create(this);
829+
// safe cast because the ClientCommonPacketListener is a superclass of ClientGamePacketListener
830+
// noinspection unchecked, rawtypes
831+
return (Packet) new ClientboundCustomPayloadPacket(new BaseMachineUpdatePayload(this.worldPosition, this.configuration));
832+
}
833+
834+
@Override
835+
public void setChanged() {
836+
super.setChanged();
837+
}
838+
839+
protected void broadcastUpdate(CustomPacketPayload payload) {
840+
if (this.level != null && !this.level.isClientSide) {
841+
for (ServerPlayer player : ((ServerLevel) MachineBlockEntity.this.level).getChunkSource().chunkMap.getPlayers(new ChunkPos(MachineBlockEntity.this.worldPosition), false)) {
842+
ServerPlayNetworking.getSender(player).sendPacket(payload);
843+
}
844+
}
845+
}
846+
847+
public void markForRerender() {
848+
this.level.sendBlockUpdated(this.worldPosition, this.getBlockState(), this.getBlockState(), 0);
819849
}
820850

821851
public void awardUsedRecipes(@NotNull ServerPlayer player, @NotNull Set<ResourceLocation> recipes) {
@@ -870,24 +900,33 @@ public void setAccessLevel(@NotNull AccessLevel accessLevel) {
870900
}
871901

872902
private class InternalMachineIoFace extends MachineIOFace {
903+
private final BlockFace face;
873904
private @Nullable ExposedStorage<Item, ItemVariant> cachedItemStorage = null;
874905
private @Nullable ExposedStorage<Fluid, FluidVariant> cachedFluidStorage = null;
875906
private @Nullable EnergyStorage cachedEnergyStorage = null;
876907

877-
public InternalMachineIoFace() {
908+
public InternalMachineIoFace(int i) {
878909
super(ResourceType.NONE, ResourceFlow.BOTH);
910+
this.face = BlockFace.values()[i];
879911
}
880912

881913
@Override
882914
public void setOption(@NotNull ResourceType type, @NotNull ResourceFlow flow) {
883-
this.type = type;
884-
this.flow = flow;
915+
if (this.type != type || this.flow != flow) {
916+
this.type = type;
917+
this.flow = flow;
885918

886-
MachineBlockEntity.this.setChanged();
919+
MachineBlockEntity.this.setChanged();
920+
if (MachineBlockEntity.this.level.isClientSide) {
921+
MachineBlockEntity.this.markForRerender();
922+
} else {
923+
MachineBlockEntity.this.broadcastUpdate(new SideConfigurationUpdatePayload(MachineBlockEntity.this.worldPosition, this.face, type, flow));
924+
}
887925

888-
this.cachedItemStorage = null;
889-
this.cachedFluidStorage = null;
890-
this.cachedEnergyStorage = null;
926+
this.cachedItemStorage = null;
927+
this.cachedFluidStorage = null;
928+
this.cachedEnergyStorage = null;
929+
}
891930
}
892931

893932
@Override

src/main/java/dev/galacticraft/machinelib/api/menu/MachineData.java

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
/*
2+
* Copyright (c) 2021-2024 Team Galacticraft
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
123
package dev.galacticraft.machinelib.api.menu;
224

325
import dev.galacticraft.machinelib.api.misc.DeltaPacketSerializable;
@@ -36,8 +58,8 @@ public void registerInt(IntSupplier getter, IntConsumer setter) {
3658
this.delta.add(new int[1]);
3759
}
3860
public <E extends Enum<E>> void registerEnum(E[] world, Supplier<E> getter, Consumer<E> setter) {
39-
this.data.add(new EnumPacketSerializable(world, getter, setter));
40-
this.delta.add(new int[1]);
61+
this.data.add(new EnumPacketSerializable<>(world, getter, setter));
62+
this.delta.add(null);
4163
}
4264

4365
public void registerLong(LongSupplier getter, LongConsumer setter) {

src/main/java/dev/galacticraft/machinelib/api/menu/MachineMenu.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@
6161
import net.minecraft.world.inventory.Slot;
6262
import net.minecraft.world.item.Item;
6363
import net.minecraft.world.item.ItemStack;
64-
import org.jetbrains.annotations.*;
64+
import org.jetbrains.annotations.ApiStatus;
65+
import org.jetbrains.annotations.Contract;
66+
import org.jetbrains.annotations.MustBeInvokedByOverriders;
67+
import org.jetbrains.annotations.NotNull;
6568

6669
import java.util.ArrayList;
6770
import java.util.List;
@@ -78,14 +81,14 @@ public class MachineMenu<Machine extends MachineBlockEntity> extends AbstractCon
7881
public static final StreamCodec<RegistryFriendlyByteBuf, RegistryFriendlyByteBuf> BUF_IDENTITY_CODEC = new StreamCodec<>() {
7982
@Override
8083
public void encode(RegistryFriendlyByteBuf src, RegistryFriendlyByteBuf dst) {
81-
dst.writeBytes(src);
84+
src.writeBytes(dst);
8285
}
8386

8487
@Override
8588
public RegistryFriendlyByteBuf decode(RegistryFriendlyByteBuf src) {
8689
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(ByteBufAllocator.DEFAULT.buffer(src.capacity()), src.registryAccess());
8790
buf.writeBytes(src);
88-
return src;
91+
return buf;
8992
}
9093
};
9194

src/main/java/dev/galacticraft/machinelib/api/misc/Equivalent.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
1-
package dev.galacticraft.machinelib.api.misc;
1+
/*
2+
* Copyright (c) 2021-2024 Team Galacticraft
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
222

3-
import org.jetbrains.annotations.NotNull;
23+
package dev.galacticraft.machinelib.api.misc;
424

525
public interface Equivalent<T> {
626
boolean hasChanged(T previous);

src/main/java/dev/galacticraft/machinelib/client/api/screen/MachineScreen.java

+8-17
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,14 @@
2525
import com.google.common.base.Suppliers;
2626
import com.google.common.collect.Lists;
2727
import com.mojang.authlib.GameProfile;
28-
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
2928
import com.mojang.blaze3d.systems.RenderSystem;
3029
import com.mojang.blaze3d.vertex.PoseStack;
3130
import dev.galacticraft.machinelib.api.block.entity.MachineBlockEntity;
3231
import dev.galacticraft.machinelib.api.machine.configuration.AccessLevel;
3332
import dev.galacticraft.machinelib.api.machine.configuration.MachineIOFace;
3433
import dev.galacticraft.machinelib.api.machine.configuration.RedstoneMode;
3534
import dev.galacticraft.machinelib.api.menu.MachineMenu;
36-
import dev.galacticraft.machinelib.api.storage.slot.FluidResourceSlot;
37-
import dev.galacticraft.machinelib.api.storage.slot.ItemResourceSlot;
3835
import dev.galacticraft.machinelib.api.transfer.InputType;
39-
import dev.galacticraft.machinelib.api.transfer.ResourceFlow;
4036
import dev.galacticraft.machinelib.api.transfer.ResourceType;
4137
import dev.galacticraft.machinelib.api.util.BlockFace;
4238
import dev.galacticraft.machinelib.client.api.render.MachineRenderData;
@@ -45,19 +41,15 @@
4541
import dev.galacticraft.machinelib.client.impl.model.MachineBakedModel;
4642
import dev.galacticraft.machinelib.impl.Constant;
4743
import dev.galacticraft.machinelib.impl.compat.vanilla.StorageSlot;
48-
import dev.galacticraft.machinelib.impl.network.c2s.AccessLevelPacket;
49-
import dev.galacticraft.machinelib.impl.network.c2s.RedstoneModePacket;
50-
import dev.galacticraft.machinelib.impl.network.c2s.SideConfigurationClickPacket;
51-
import dev.galacticraft.machinelib.impl.network.c2s.TankInteractionPacket;
52-
import io.netty.buffer.ByteBufAllocator;
44+
import dev.galacticraft.machinelib.impl.network.c2s.AccessLevelPayload;
45+
import dev.galacticraft.machinelib.impl.network.c2s.RedstoneModePayload;
46+
import dev.galacticraft.machinelib.impl.network.c2s.SideConfigurationClickPayload;
47+
import dev.galacticraft.machinelib.impl.network.c2s.TankInteractionPayload;
5348
import lol.bai.badpackets.api.PacketSender;
54-
import lol.bai.badpackets.api.play.PlayPackets;
5549
import net.fabricmc.api.EnvType;
5650
import net.fabricmc.api.Environment;
5751
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
5852
import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext;
59-
import net.fabricmc.fabric.api.transfer.v1.item.PlayerInventoryStorage;
60-
import net.fabricmc.fabric.impl.transfer.context.PlayerContainerItemContext;
6153
import net.minecraft.client.Minecraft;
6254
import net.minecraft.client.gui.GuiGraphics;
6355
import net.minecraft.client.gui.components.PlayerFaceRenderer;
@@ -67,7 +59,6 @@
6759
import net.minecraft.client.resources.PlayerSkin;
6860
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
6961
import net.minecraft.core.registries.BuiltInRegistries;
70-
import net.minecraft.network.FriendlyByteBuf;
7162
import net.minecraft.network.chat.Component;
7263
import net.minecraft.resources.ResourceLocation;
7364
import net.minecraft.sounds.SoundEvents;
@@ -551,7 +542,7 @@ public boolean checkConfigurationPanelClick(double mouseX, double mouseY, int bu
551542
*/
552543
protected void setAccessibility(@NotNull AccessLevel accessLevel) {
553544
this.menu.security.setAccessLevel(accessLevel);
554-
PacketSender.c2s().send(new AccessLevelPacket(accessLevel));
545+
PacketSender.c2s().send(new AccessLevelPayload(accessLevel));
555546
}
556547

557548
/**
@@ -561,7 +552,7 @@ protected void setAccessibility(@NotNull AccessLevel accessLevel) {
561552
*/
562553
protected void setRedstone(@NotNull RedstoneMode redstone) {
563554
this.menu.redstoneMode = redstone;
564-
PacketSender.c2s().send(new RedstoneModePacket(redstone));
555+
PacketSender.c2s().send(new RedstoneModePayload(redstone));
565556
}
566557

567558
/**
@@ -859,7 +850,7 @@ private void handleSlotHighlight(GuiGraphics graphics, int mouseX, int mouseY) {
859850
public boolean mouseClicked(double mouseX, double mouseY, int button) {
860851
if (this.hoveredTank != null && button == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
861852
if (this.hoveredTank.acceptStack(ContainerItemContext.ofPlayerCursor(this.menu.playerInventory.player, this.menu))) {
862-
PacketSender.c2s().send(new TankInteractionPacket(this.menu.containerId, this.hoveredTank.getIndex()));
853+
PacketSender.c2s().send(new TankInteractionPayload(this.menu.containerId, this.hoveredTank.getIndex()));
863854
}
864855
return true;
865856
}
@@ -928,7 +919,7 @@ public int getImageHeight() {
928919
private void modifyFace(int button, BlockFace face) {
929920
if (this.menu.isFaceLocked(face)) return;
930921
if (button == 0) {
931-
ClientPlayNetworking.send(new SideConfigurationClickPacket(face, Screen.hasShiftDown(), Screen.hasControlDown()));
922+
ClientPlayNetworking.send(new SideConfigurationClickPayload(face, Screen.hasShiftDown(), Screen.hasControlDown()));
932923
this.menu.cycleFaceConfig(face, Screen.hasShiftDown(), Screen.hasControlDown());
933924
}
934925
this.playButtonSound();

src/main/java/dev/galacticraft/machinelib/client/api/util/DisplayUtil.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import net.minecraft.client.gui.screens.Screen;
3535
import net.minecraft.client.resources.language.I18n;
3636
import net.minecraft.core.component.DataComponentPatch;
37-
import net.minecraft.nbt.CompoundTag;
3837
import net.minecraft.network.chat.Component;
3938
import net.minecraft.network.chat.MutableComponent;
4039
import net.minecraft.network.chat.Style;
@@ -125,7 +124,8 @@ public static void createFluidTooltip(@NotNull List<Component> tooltip, @Nullabl
125124
return;
126125
}
127126

128-
tooltip.add(Component.translatable(Constant.TranslationKey.TANK_CONTENTS).setStyle(Constant.Text.GRAY_STYLE).append(FluidVariantAttributes.getName(FluidVariant.of(fluid, components))));
127+
assert fluid != null;
128+
tooltip.add(Component.translatable(Constant.TranslationKey.TANK_CONTENTS).setStyle(Constant.Text.GRAY_STYLE).append(FluidVariantAttributes.getName(FluidVariant.of(fluid, components == null ? DataComponentPatch.EMPTY : components))));
129129
tooltip.add(Component.translatable(Constant.TranslationKey.TANK_AMOUNT).setStyle(Constant.Text.GRAY_STYLE).append(DisplayUtil.formatFluid(amount, Screen.hasShiftDown()).setStyle(Style.EMPTY.withColor(ChatFormatting.WHITE))));
130130

131131
if (capacity != -1) {

src/main/java/dev/galacticraft/machinelib/client/impl/menu/sync/MachineDataClient.java

+22
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
/*
2+
* Copyright (c) 2021-2024 Team Galacticraft
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
123
package dev.galacticraft.machinelib.client.impl.menu.sync;
224

325
import dev.galacticraft.machinelib.api.menu.MachineData;

src/main/java/dev/galacticraft/machinelib/client/impl/model/MachineBakedModel.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ public MachineBakedModel(MachineModelRegistry.SpriteProviderFactory factory, Jso
118118

119119
private boolean transform(MachineRenderData renderData, @NotNull BlockState state, @NotNull MutableQuadView quad) {
120120
BlockFace face = BlockFace.toFace(state.getValue(BlockStateProperties.HORIZONTAL_FACING), quad.nominalFace());
121-
MachineIOFace machineFace = renderData == null ? new MachineIOFace() : renderData.getIOConfig().get(face);
122121
assert face != null;
122+
123+
MachineIOFace machineFace = renderData == null ? new MachineIOFace() : renderData.getIOConfig().get(face);
123124
quad.spriteBake(getSprite(face,
124125
renderData,
125126
machineFace.getType(), machineFace.getFlow()),

0 commit comments

Comments
 (0)