Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
bf69e88
Frozen (2013) is the best movie ever made, hell, the best piece of ME…
purebluez Oct 22, 2025
892e263
commit for frosty to look at
purebluez Oct 26, 2025
b33bf68
it doesnt quite work
purebluez Oct 26, 2025
e49d334
a little better somehow
purebluez Oct 27, 2025
245c0e5
Merge remote-tracking branch 'upstream/mui2-refactor' into theme
purebluez Oct 27, 2025
cec655e
nvm i guess
purebluez Oct 28, 2025
dc8ae00
we'll love again
purebluez Oct 31, 2025
795d01e
we'll laugh again
purebluez Oct 31, 2025
b1d5196
we'll cry again
purebluez Oct 31, 2025
9cc1d5d
jurrejelle recommendations
purebluez Oct 31, 2025
70f1a7c
Merge remote-tracking branch 'upstream/mui2-refactor' into theme
purebluez Feb 13, 2026
e5e190d
this does not work at all
purebluez Feb 13, 2026
c84360d
move to dynamic linked sync handler
jurrejelle Feb 14, 2026
31f9d0d
Move to GenericListSyncHandler
jurrejelle Feb 14, 2026
d973df3
Move to display widget
jurrejelle Feb 14, 2026
733954b
Port change to dynamic sync handler (c0f8757)
jurrejelle Feb 14, 2026
0eb1c0a
Apply read list sync handler fix, move to index based entry syncing
jurrejelle Feb 14, 2026
b4e8dc8
null guarding the description field for some reason? NPEs without it
jurrejelle Feb 14, 2026
d2f7ed8
Resolve sizing problems
jurrejelle Feb 14, 2026
9b22995
Sync colors
jurrejelle Feb 15, 2026
1e7a50b
Chagne fluid sync handler, add UUID syncer, add deleteDescription action
jurrejelle Feb 16, 2026
121f7fe
Apply Ghz's patch for fluid tanks
jurrejelle Feb 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/generated/resources/assets/gtceu/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -2056,6 +2056,8 @@
"cover.ender_fluid_link.tooltip.clear_button": "Clear channel description",
"cover.ender_fluid_link.tooltip.list_button": "Show channel list",
"cover.ender_item_link.title": "Ender Item Link",
"cover.ender_link.channel_description": "Channel description",
"cover.ender_link.channel_name": "Channel name",
"cover.ender_redstone_link.title": "Ender Redstone Link",
"cover.filter.blacklist.disabled": "Whitelist",
"cover.filter.blacklist.enabled": "Blacklist",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ public void setFluid(FluidStack fluid) {
@Override
public boolean equals(Object o) {
if (!(o instanceof VirtualTank other)) return false;
return this.fluidTank == other.fluidTank;

if (this.fluidTank.getCapacity() != other.fluidTank.getCapacity()) return false;
if (!this.fluidTank.getFluid().equals(other.fluidTank.getFluid())) return false;
return true;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public class DynamicLinkedSyncHandler<S extends ValueSyncHandler<?>> extends Syn
private IWidgetProvider<S> widgetProvider;
private Consumer<IWidget> onWidgetUpdate;

private boolean updateQueued;
private IWidget lastRejectedWidget;

private final S linkedValue;
Expand Down Expand Up @@ -45,10 +44,7 @@ public void readOnServer(int id, FriendlyByteBuf buf) {
@Override
public void init(String key, PanelSyncManager syncManager) {
super.init(key, syncManager);
if (this.updateQueued) {
notifyUpdate(true);
this.updateQueued = false;
}
notifyUpdate(false);
}

private IWidget parseWidget() {
Expand All @@ -61,7 +57,7 @@ private IWidget parseWidget() {
int unregistered = WidgetTree.countUnregisteredSyncHandlers(widget);
if (unregistered > 0) {
throw new IllegalStateException(
"Widgets created by DynamicSyncHandler can't have implicitly registered sync handlers. All" +
"Widgets created by DynamicSyncHandler can't have implicitly registered sync handlers. All " +
"sync handlers must be registered with a variant of 'PanelSyncManager#getOrCreateSyncHandler(...)'.");
}
return widget;
Expand All @@ -86,11 +82,7 @@ private void updateWidget(IWidget widget) {
* initialised is effective.
*/
private void notifyUpdate(boolean sync) {
if (!isValid()) {
// sync handler not yet initialised
this.updateQueued = true;
return;
}
if (!isValid()) return;
IWidget widget = parseWidget();
if (getSyncManager().isClient()) {
updateWidget(widget);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private IWidget parseWidget(FriendlyByteBuf buf) {
if (unregistered > 0) {
throw new IllegalStateException(
"Widgets created by DynamicSyncHandler can't have implicitly registered sync" +
" handlers. All sync handlers must be regisered witha variant of 'PanelSyncManager#getOrCreateSyncHandler(...)'.");
" handlers. All sync handlers must be registered with a variant of 'PanelSyncManager#getOrCreateSyncHandler(...)'.");
}
return widget;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public List<T> getValue() {
@Override
public void read(FriendlyByteBuf buffer) {
this.cache.clear();
for (int i = 0; i < buffer.readVarInt(); i++) {
int size = buffer.readVarInt();
for (int i = 0; i < size; i++) {
this.cache.add(deserializeValue(buffer));
}
onSetCache(getValue(), true, false);
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
import com.gregtechceu.gtceu.api.cover.filter.FilterHandler;
import com.gregtechceu.gtceu.api.cover.filter.FilterHandlers;
import com.gregtechceu.gtceu.api.cover.filter.FluidFilter;
import com.gregtechceu.gtceu.api.gui.GuiTextures;
import com.gregtechceu.gtceu.api.gui.widget.TankWidget;
import com.gregtechceu.gtceu.api.misc.virtualregistry.EntryTypes;
import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEnderRegistry;
import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEntry;
import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualTank;
import com.gregtechceu.gtceu.api.mui.base.widget.IWidget;
import com.gregtechceu.gtceu.api.mui.value.sync.FluidSlotSyncHandler;
import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager;
import com.gregtechceu.gtceu.api.mui.value.sync.SyncHandlers;
import com.gregtechceu.gtceu.api.mui.widget.ParentWidget;
import com.gregtechceu.gtceu.api.mui.widgets.slot.FluidSlot;
import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField;
import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient;
import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable;
Expand All @@ -21,6 +25,8 @@
import net.minecraft.core.Direction;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.IFluidHandler;

import lombok.Getter;
import org.jetbrains.annotations.NotNull;
Expand All @@ -35,7 +41,50 @@ public class EnderFluidLinkCover extends AbstractEnderLinkCover<VirtualTank> {

@SaveField
@SyncToClient
protected VirtualTank visualTank;
protected VirtualTank visualTank = new VirtualTank();

// todo make this a proper class
protected final IFluidTank tankSwitchShim = new IFluidTank() {

private IFluidTank getDelegate() {
return getEntry().getFluidTank();
}

@Override
public @NotNull FluidStack getFluid() {
return getDelegate().getFluid();
}

@Override
public int getFluidAmount() {
return getDelegate().getFluidAmount();
}

@Override
public int getCapacity() {
return getDelegate().getCapacity();
}

@Override
public boolean isFluidValid(FluidStack fluidStack) {
return getDelegate().isFluidValid(fluidStack);
}

@Override
public int fill(FluidStack fluidStack, IFluidHandler.FluidAction fluidAction) {
return getDelegate().fill(fluidStack, fluidAction);
}

@Override
public @NotNull FluidStack drain(int i, IFluidHandler.FluidAction fluidAction) {
return getDelegate().drain(i, fluidAction);
}

@Override
public @NotNull FluidStack drain(FluidStack fluidStack, IFluidHandler.FluidAction fluidAction) {
return getDelegate().drain(fluidStack, fluidAction);
}
};

@Getter
@SaveField
Expand All @@ -51,6 +100,13 @@ public EnderFluidLinkCover(CoverDefinition definition, ICoverable coverHolder, D
.getOrCreateEntry(getOwner(), EntryTypes.ENDER_FLUID, getChannelName()));
}

@Override
public void onLoad() {
super.onLoad();
if (!coverHolder.isRemote()) visualTank = VirtualEnderRegistry.getInstance()
.getOrCreateEntry(getOwner(), EntryTypes.ENDER_FLUID, getChannelName());
}

@Override
protected VirtualTank getEntry() {
return visualTank;
Expand Down Expand Up @@ -115,14 +171,23 @@ private int doTransferFluids(int platformTransferLimit) {
//////////////////////////////////////

@Override
protected Widget addVirtualEntryWidget(VirtualEntry entry, int x, int y, int width, int height, boolean canClick) {
return new TankWidget(((VirtualTank) entry).getFluidTank(), 0, x, y, width, height, canClick, canClick)
.setBackground(GuiTextures.FLUID_SLOT);
}

@NotNull
@Override
protected String getUITitle() {
return "cover.ender_fluid_link.title";
protected IWidget createVirtualEntryWidget(PanelSyncManager manager, VirtualEntry entry, int w, int h, int index) {
if (!(entry instanceof VirtualTank tank)) return new ParentWidget<>().size(w, h);

manager.getOrCreateSyncHandler("ender_link_cover_fluid_slot", index, FluidSlotSyncHandler.class,
() -> SyncHandlers.fluidSlot(index == -1 ? tankSwitchShim : tank.getFluidTank()));

return new FluidSlot()
.syncHandler("ender_link_cover_fluid_slot", index)
.marginLeft(3)
.size(w, h)
// return new FluidSlot()
// .syncHandler(manager.getOrCreateSyncHandler(
// ModularSyncManager.AUTO_SYNC_PREFIX + coverDefinition.getId().getPath(),
// FluidSlotSyncHandler.class,
// () -> new FluidSlotSyncHandler(((VirtualTank) entry).getFluidTank())))
// .marginLeft(3)
// .size(w, h)
;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
import com.gregtechceu.gtceu.api.cover.filter.FilterHandler;
import com.gregtechceu.gtceu.api.cover.filter.FilterHandlers;
import com.gregtechceu.gtceu.api.cover.filter.ItemFilter;
import com.gregtechceu.gtceu.api.gui.widget.SlotWidget;
import com.gregtechceu.gtceu.api.misc.virtualregistry.EntryTypes;
import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEnderRegistry;
import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEntry;
import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualItemStorage;
import com.gregtechceu.gtceu.api.mui.base.widget.IWidget;
import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager;
import com.gregtechceu.gtceu.api.mui.widget.ParentWidget;
import com.gregtechceu.gtceu.api.mui.widgets.slot.ItemSlot;
import com.gregtechceu.gtceu.api.mui.widgets.slot.ModularSlot;
import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder;
import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField;
import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient;
import com.gregtechceu.gtceu.utils.GTTransferUtils;

import com.lowdragmc.lowdraglib.gui.widget.Widget;
import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup;

import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
Expand Down Expand Up @@ -49,6 +50,13 @@ public EnderItemLinkCover(CoverDefinition definition, ICoverable coverHolder, Di
getChannelName()));
}

@Override
public void onLoad() {
super.onLoad();
if (!coverHolder.isRemote()) storage = VirtualEnderRegistry.getInstance().getOrCreateEntry(getOwner(),
EntryTypes.ENDER_ITEM, getChannelName());
}

@Override
public boolean canAttach() {
return true;
Expand Down Expand Up @@ -101,16 +109,13 @@ private int doTransferItems(int max) {
}

@Override
protected Widget addVirtualEntryWidget(VirtualEntry entry, int x, int y, int width, int height, boolean canClick) {
WidgetGroup group = new WidgetGroup(x, y, width, height);
for (int i = 0; i < ((VirtualItemStorage) entry).getHandler().getSlots(); i++) {
group.addWidget(new SlotWidget(((VirtualItemStorage) entry).getHandler(), i, 8 * i, 0, canClick, canClick));
}
return group;
}

@Override
protected String getUITitle() {
return "cover.ender_item_link.title";
protected IWidget createVirtualEntryWidget(PanelSyncManager manager, VirtualEntry entry, int w, int h, int index) {
if (!(entry instanceof VirtualItemStorage itemStorage)) return new ParentWidget<>().size(w, h);
manager.getOrCreateSlot("ender_item_link_cover_" + index, 0,
() -> new ModularSlot(itemStorage.getHandler(), 0));
return new ItemSlot()
.syncHandler("ender_item_link_cover_" + index)
.marginLeft(3)
.size(w, h);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import com.gregtechceu.gtceu.api.misc.virtualregistry.EntryTypes;
import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEntry;
import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualRedstone;
import com.gregtechceu.gtceu.api.mui.base.widget.IWidget;
import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager;
import com.gregtechceu.gtceu.api.mui.widget.ParentWidget;
import com.gregtechceu.gtceu.api.sync_system.SyncDataHolder;
import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField;
import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient;

import com.lowdragmc.lowdraglib.gui.widget.Widget;
import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup;

import net.minecraft.core.Direction;

import lombok.Getter;
Expand All @@ -32,7 +32,7 @@ public class EnderRedstoneLinkCover extends AbstractEnderLinkCover<VirtualRedsto

public EnderRedstoneLinkCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide) {
super(definition, coverHolder, attachedSide);
if (!isRemote()) {
if (!coverHolder.isRemote()) {
uuid = UUID.randomUUID();
setVirtualEntry();
} else uuid = null;
Expand Down Expand Up @@ -75,13 +75,8 @@ protected void transfer() {
}

@Override
protected Widget addVirtualEntryWidget(VirtualEntry entry, int x, int y, int width, int height, boolean canClick) {
return new WidgetGroup(x, y, width, height);
}

@Override
protected String getUITitle() {
return "cover.ender_redstone_link.title";
protected IWidget createVirtualEntryWidget(PanelSyncManager manager, VirtualEntry entry, int w, int h, int index) {
return new ParentWidget<>().size(w, h);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ public static class IDs {
public static final UITexture INDICATOR_NO_STEAM_STEEL = fullImage(
"textures/gui/base/indicator_no_steam_steel.png");
public static final UITexture TANK_ICON = fullImage("textures/gui/base/tank_icon.png");
public static final UITexture IO_BOTH = fullImage("textures/gui/icon/io_mode/both.png");
public static final UITexture IO_EXPORT = fullImage("textures/gui/icon/io_mode/export.png");
public static final UITexture IO_IMPORT = fullImage("textures/gui/icon/io_mode/import.png");
public static final UITexture IO_NONE = fullImage("textures/gui/icon/io_mode/none.png");
public static final UITexture MANUAL_IO_DISABLED = fullImage("textures/gui/icon/manual_io_mode/disabled.png");
public static final UITexture MANUAL_IO_FILTERED = fullImage("textures/gui/icon/manual_io_mode/filtered.png");
public static final UITexture MANUAL_IO_UNFILTERED = fullImage("textures/gui/icon/manual_io_mode/unfiltered.png");
public static final UITexture SEPERATOR_SIMPLE = UITexture.builder()
.location(GTCEu.MOD_ID, "textures/gui/icon/seperator/seperator_simple.png")
.imageSize(16, 5)
.adaptable(2)
.build();

// BACKGROUNDS
public static final UITexture BACKGROUND = UITexture.builder()
Expand Down Expand Up @@ -443,6 +455,8 @@ public static class IDs {
public static final UITexture BUTTON_REDSTONE_OFF = fullImage("textures/gui/widget/button_redstone_off.png");
public static final UITexture BUTTON_THROTTLE_PLUS = fullImage("textures/gui/widget/button_throttle_plus.png");
public static final UITexture BUTTON_THROTTLE_MINUS = fullImage("textures/gui/widget/button_throttle_minus.png");
public static final UITexture OVERLAY_LOCK_CLOSED = fullImage("textures/gui/overlay/lock_closed.png");
public static final UITexture OVERLAY_LOCK_OPEN = fullImage("textures/gui/overlay/lock_open.png");
public static final UITexture BUTTON_EU = fullImage("textures/gui/overlay/mode_eu.png");
public static final UITexture BUTTON_PERCENT = fullImage("textures/gui/overlay/mode_percent.png");
public static final UITexture BUTTON_MAINTENANCE = fullImage("textures/gui/widget/button_maintenance.png");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Objects;
import java.util.UUID;

public class ByteBufAdapters {

Expand Down Expand Up @@ -139,6 +140,31 @@ public boolean areEqual(@NotNull GTRecipe t1, @NotNull GTRecipe t2) {
}
};

public static final IByteBufAdapter<UUID> UUID = new IByteBufAdapter<>() {

@Override
public UUID deserialize(FriendlyByteBuf buffer) {
if (!buffer.readBoolean()) {
return null;
}
return buffer.readUUID();
}

@Override
public void serialize(FriendlyByteBuf buffer, UUID u) {
if (u == null) {
buffer.writeBoolean(false);
return;
}
buffer.writeUUID(u);
}

@Override
public boolean areEqual(@NotNull UUID t1, @NotNull UUID t2) {
return EqualityTest.wrapNullSafe(java.util.UUID::equals).areEqual(t1, t2);
}
};

public static <T> IByteBufAdapter<T> makeAdapter(@NotNull IByteBufDeserializer<T> deserializer,
@NotNull IByteBufSerializer<T> serializer,
@Nullable EqualityTest<T> tester) {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading