diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index 6054957ac0a..379f791465c 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -1,7 +1,16 @@ package gregtech.api.capability; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.apache.commons.lang3.ArrayUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + public class GregtechDataCodes { + public static final int UPDATE_PRIVATE = assignId(); + public static final int LOCK_FILL = assignId(); private static int nextId = 0; public static int assignId() { @@ -180,4 +189,36 @@ public static int assignId() { // ME Parts public static final int UPDATE_AUTO_PULL = assignId(); public static final int UPDATE_ONLINE_STATUS = assignId(); + + // Everything below MUST be last in the class! + public static final Int2ObjectMap NAMES = new Int2ObjectArrayMap<>(); + + static { + registerFields(GregtechDataCodes.class); + } + + public static String getNameFor(int id) { + return NAMES.getOrDefault(id, "Unknown_DataCode:" + id); + } + + /** + * Registers all fields from the passed in class to the name registry. + * Optionally, you can pass in a list of valid ids to check against so that errant ids are not added + * + * @param clazz Class to iterate fields + * @param validIds optional array of valid ids to check against class fields + */ + public static void registerFields(Class clazz, int... validIds) { + try { + for (Field field : clazz.getDeclaredFields()) { + if (field.getType() != Integer.TYPE) continue; + if (!Modifier.isStatic(field.getModifiers())) continue; + if (!Modifier.isFinal(field.getModifiers())) continue; + int id = field.getInt(null); + if (!ArrayUtils.isEmpty(validIds) && !ArrayUtils.contains(validIds, id)) + continue; + NAMES.put(id, field.getName() + ":" + id); + } + } catch (IllegalAccessException ignored) {} + } } diff --git a/src/main/java/gregtech/api/cover/CoverSaveHandler.java b/src/main/java/gregtech/api/cover/CoverSaveHandler.java index fe62aa782a9..e9041d022f3 100644 --- a/src/main/java/gregtech/api/cover/CoverSaveHandler.java +++ b/src/main/java/gregtech/api/cover/CoverSaveHandler.java @@ -1,5 +1,6 @@ package gregtech.api.cover; +import gregtech.api.metatileentity.interfaces.ISyncedTileEntity; import gregtech.api.util.GTLog; import net.minecraft.nbt.NBTTagCompound; @@ -66,6 +67,7 @@ public static void receiveInitialSyncData(@NotNull PacketBuffer buf, @NotNull Co } else { Cover cover = definition.createCover(coverHolder, facing); cover.readInitialSyncData(buf); + ISyncedTileEntity.checkInitialData(buf, cover); coverHolder.addCover(facing, cover); } } @@ -107,6 +109,7 @@ public static void readCoverPlacement(@NotNull PacketBuffer buf, @NotNull CoverH coverHolder.addCover(placementSide, cover); cover.readInitialSyncData(buf); + ISyncedTileEntity.checkInitialData(buf, cover); } coverHolder.scheduleRenderUpdate(); } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 723df6f6808..611cb125922 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -1043,7 +1043,10 @@ public void receiveInitialSyncData(@NotNull PacketBuffer buf) { MTETrait trait = mteTraitByNetworkId.get(traitNetworkId); if (trait == null) { GTLog.logger.warn("Could not find MTETrait for id: {} at position {}.", traitNetworkId, getPos()); - } else trait.receiveInitialData(buf); + } else { + trait.receiveInitialSyncData(buf); + ISyncedTileEntity.checkInitialData(buf, trait); + } } CoverSaveHandler.receiveInitialSyncData(buf, this); this.muffled = buf.readBoolean(); @@ -1076,10 +1079,14 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { scheduleRenderUpdate(); } else if (dataId == SYNC_MTE_TRAITS) { int traitNetworkId = buf.readVarInt(); + int internalId = buf.readVarInt(); MTETrait trait = mteTraitByNetworkId.get(traitNetworkId); if (trait == null) { GTLog.logger.warn("Could not find MTETrait for id: {} at position {}.", traitNetworkId, getPos()); - } else trait.receiveCustomData(buf.readVarInt(), buf); + } else { + trait.receiveCustomData(internalId, buf); + ISyncedTileEntity.checkCustomData(internalId, buf, trait); + } } else if (dataId == COVER_ATTACHED_MTE) { CoverSaveHandler.readCoverPlacement(buf, this); } else if (dataId == COVER_REMOVED_MTE) { @@ -1095,6 +1102,7 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { int internalId = buf.readVarInt(); if (cover != null) { cover.readCustomData(internalId, buf); + ISyncedTileEntity.checkCustomData(internalId, buf, cover); } } else if (dataId == UPDATE_SOUND_MUFFLED) { this.muffled = buf.readBoolean(); diff --git a/src/main/java/gregtech/api/metatileentity/SyncedTileEntityBase.java b/src/main/java/gregtech/api/metatileentity/SyncedTileEntityBase.java index 4e29fe09328..9b42003a0dc 100644 --- a/src/main/java/gregtech/api/metatileentity/SyncedTileEntityBase.java +++ b/src/main/java/gregtech/api/metatileentity/SyncedTileEntityBase.java @@ -4,7 +4,6 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.interfaces.ISyncedTileEntity; import gregtech.api.network.PacketDataList; -import gregtech.api.util.GTLog; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTBase; @@ -80,20 +79,13 @@ public final void onDataPacket(@NotNull NetworkManager net, @NotNull SPacketUpda NBTTagCompound entryTag = (NBTTagCompound) entryBase; for (String discriminatorKey : entryTag.getKeySet()) { ByteBuf backedBuffer = Unpooled.copiedBuffer(entryTag.getByteArray(discriminatorKey)); - receiveCustomData(Integer.parseInt(discriminatorKey), new PacketBuffer(backedBuffer)); - if (backedBuffer.readableBytes() != 0) { - String className = null; - if (this instanceof IGregTechTileEntity gtte) { - MetaTileEntity mte = gtte.getMetaTileEntity(); - if (mte != null) className = mte.getClass().getName(); - } - if (className == null) { - className = this.getClass().getName(); - } - GTLog.logger.error( - "Class {} failed to finish reading receiveCustomData with discriminator {} and {} bytes remaining", - className, discriminatorKey, backedBuffer.readableBytes()); - } + int dataId = Integer.parseInt(discriminatorKey); + receiveCustomData(dataId, new PacketBuffer(backedBuffer)); + + MetaTileEntity mte = null; + if (this instanceof IGregTechTileEntity gtte) + mte = gtte.getMetaTileEntity(); + ISyncedTileEntity.checkCustomData(dataId, backedBuffer, mte == null ? this : mte); } } } @@ -114,18 +106,10 @@ public final void handleUpdateTag(@NotNull NBTTagCompound tag) { byte[] updateData = tag.getByteArray("d"); ByteBuf backedBuffer = Unpooled.copiedBuffer(updateData); receiveInitialSyncData(new PacketBuffer(backedBuffer)); - if (backedBuffer.readableBytes() != 0) { - String className = null; - if (this instanceof IGregTechTileEntity gtte) { - MetaTileEntity mte = gtte.getMetaTileEntity(); - if (mte != null) className = mte.getClass().getName(); - } - if (className == null) { - className = this.getClass().getName(); - } - GTLog.logger.error("Class {} failed to finish reading initialSyncData with {} bytes remaining", - className, backedBuffer.readableBytes()); - } + MetaTileEntity mte = null; + if (this instanceof IGregTechTileEntity gtte) + mte = gtte.getMetaTileEntity(); + ISyncedTileEntity.checkInitialData(backedBuffer, mte == null ? this : mte); } } diff --git a/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java b/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java index 0222ffdbe47..97bff58419b 100644 --- a/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java @@ -1,7 +1,15 @@ package gregtech.api.metatileentity.interfaces; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.cover.Cover; +import gregtech.api.cover.CoverableView; +import gregtech.api.util.GTLog; + import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; @@ -25,7 +33,7 @@ public interface ISyncedTileEntity { *

* This method is called Server-Side. *

- * Equivalent to {@link net.minecraft.tileentity.TileEntity#getUpdateTag}. + * Equivalent to {@link TileEntity#getUpdateTag}. * * @param buf the buffer to write data to */ @@ -43,7 +51,7 @@ public interface ISyncedTileEntity { *

* This method is called Client-Side. *

- * Equivalent to {@link net.minecraft.tileentity.TileEntity#handleUpdateTag}. + * Equivalent to {@link TileEntity#handleUpdateTag}. * * @param buf the buffer to read data from */ @@ -62,11 +70,11 @@ public interface ISyncedTileEntity { *

* This method is called Server-Side. *

- * Equivalent to {@link net.minecraft.tileentity.TileEntity#getUpdatePacket} + * Equivalent to {@link TileEntity#getUpdatePacket} * * @param discriminator the discriminator determining the packet sent. * @param dataWriter a consumer which writes packet data to a buffer. - * @see gregtech.api.capability.GregtechDataCodes + * @see GregtechDataCodes */ void writeCustomData(int discriminator, @NotNull Consumer<@NotNull PacketBuffer> dataWriter); @@ -82,10 +90,10 @@ public interface ISyncedTileEntity { *

* This method is called Server-Side. *

- * Equivalent to {@link net.minecraft.tileentity.TileEntity#getUpdatePacket} + * Equivalent to {@link TileEntity#getUpdatePacket} * * @param discriminator the discriminator determining the packet sent. - * @see gregtech.api.capability.GregtechDataCodes + * @see GregtechDataCodes */ default void writeCustomData(int discriminator) { writeCustomData(discriminator, NO_OP); @@ -103,11 +111,51 @@ default void writeCustomData(int discriminator) { *

* This method is called Client-Side. *

- * Equivalent to {@link net.minecraft.tileentity.TileEntity#onDataPacket} + * Equivalent to {@link TileEntity#onDataPacket} * * @param discriminator the discriminator determining the packet sent. * @param buf the buffer containing the packet data. - * @see gregtech.api.capability.GregtechDataCodes + * @see GregtechDataCodes */ void receiveCustomData(int discriminator, @NotNull PacketBuffer buf); + + static void checkCustomData(int discriminator, @NotNull ByteBuf buf, Object obj) { + if (buf.readableBytes() == 0) return; + + GTLog.logger.error( + "Class {} failed to finish reading receiveCustomData with discriminator {} and {} bytes remaining", + stringify(obj), GregtechDataCodes.getNameFor(discriminator), buf.readableBytes()); + + buf.clear(); // clear to prevent further logging + } + + static void checkInitialData(@NotNull ByteBuf buf, Object obj) { + if (buf.readableBytes() == 0) return; + + GTLog.logger.error("Class {} failed to finish reading initialSyncData with {} bytes remaining", + stringify(obj), buf.readableBytes()); + + buf.clear(); // clear to prevent further logging + } + + static String stringify(Object obj) { + StringBuilder builder = new StringBuilder(obj.getClass().getSimpleName()); + + BlockPos pos = null; + if (obj instanceof TileEntity tileEntity) { + pos = tileEntity.getPos(); // TE pos + } else if (obj instanceof CoverableView view) { + pos = view.getPos(); // MTE pos + } else if (obj instanceof Cover cover) { + pos = cover.getPos(); // Cover pos and side + builder.append("[side=").append(cover.getAttachedSide()).append("]"); + } + + if (pos != null) builder.append(" @ {") + .append(pos.getX()).append("X, ") + .append(pos.getY()).append("Y, ") + .append(pos.getZ()).append("Z}"); + + return builder.toString(); + } } diff --git a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java index 53701cacd6b..4ed97afcc0e 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java @@ -60,7 +60,6 @@ public abstract class CoverAbstractEnderLink extends Cov implements CoverWithUI, ITickable, IControllable { protected static final Pattern COLOR_INPUT_PATTERN = Pattern.compile("[0-9a-fA-F]*"); - public static final int UPDATE_PRIVATE = GregtechDataCodes.assignId(); protected T activeEntry = null; protected String color = VirtualEntry.DEFAULT_COLOR; @@ -100,7 +99,7 @@ protected final UUID getOwner() { @Override public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { super.readCustomData(discriminator, buf); - if (discriminator == UPDATE_PRIVATE) { + if (discriminator == GregtechDataCodes.UPDATE_PRIVATE) { setPrivate(buf.readBoolean()); updateLink(); } @@ -246,7 +245,7 @@ private boolean isPrivate() { private void setPrivate(boolean isPrivate) { this.isPrivate = isPrivate; updateLink(); - writeCustomData(UPDATE_PRIVATE, buffer -> buffer.writeBoolean(this.isPrivate)); + writeCustomData(GregtechDataCodes.UPDATE_PRIVATE, buffer -> buffer.writeBoolean(this.isPrivate)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java index 935d40d451f..153c93bdb12 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java @@ -54,7 +54,6 @@ public class MetaTileEntityFluidHatch extends MetaTileEntityMultiblockNotifiable implements IMultiblockAbilityPart, IControllable { public static final int INITIAL_INVENTORY_SIZE = 8000; - public static final int LOCK_FILL = GregtechDataCodes.assignId(); // only holding this for convenience protected final HatchFluidTank fluidTank; @@ -168,7 +167,7 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == GregtechDataCodes.WORKING_ENABLED) { this.workingEnabled = buf.readBoolean(); - } else if (dataId == LOCK_FILL) { + } else if (dataId == GregtechDataCodes.LOCK_FILL) { this.lockedFluid = NetworkUtils.readFluidStack(buf); } } @@ -352,7 +351,8 @@ public int fillInternal(FluidStack resource, boolean doFill) { if (doFill && locked && lockedFluid == null) { lockedFluid = resource.copy(); lockedFluid.amount = 1; - writeCustomData(LOCK_FILL, buffer -> NetworkUtils.writeFluidStack(buffer, lockedFluid)); + writeCustomData(GregtechDataCodes.LOCK_FILL, + buffer -> NetworkUtils.writeFluidStack(buffer, lockedFluid)); } return accepted; }