From 25d30ab435708aba1b5c53345662c632070f2736 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 08:35:47 +0200 Subject: [PATCH 01/52] port build environment to 26.1 --- build.gradle.kts | 2 +- gradle.properties | 20 ++++++++++---------- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7a5d310..f418c82 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("net.neoforged.moddev") version "2.0.141" - id("com.almostreliable.almostgradle") version "1.5.2" + id("com.almostreliable.almostgradle") version "2.3.2" } almostgradle.setup { diff --git a/gradle.properties b/gradle.properties index 0d92e3a..8205358 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,8 +3,8 @@ group = com.almostreliable modId = merequester modName = ME Requester modVersion = 1.4.3 -minecraftVersion = 1.21.1 -neoforgeVersion = 21.1.169 +minecraftVersion = 26.1.2 +neoforgeVersion = 26.1.2.81 # replacement properties modAuthor = Almost Reliable @@ -14,17 +14,17 @@ githubUser = AlmostReliable githubRepo = merequester # mod dependencies -aeVersion = 19.2.13 -wtlibVersion = 19.2.5 +aeVersion = 26.1.10-beta +wtlibVersion = 26.1.1-beta # settings -neoForge.parchment.minecraftVersion = 1.21.1 -neoForge.parchment.mappingsVersion = 2024.11.17 -almostgradle.buildconfig.name = ModConstants +#neoForge.parchment.minecraftVersion = 1.21.1 +#neoForge.parchment.mappingsVersion = 2024.11.17 +almostgradle.buildconfig = ModConstants almostgradle.launchArgs.autoWorldJoin = true -almostgradle.recipeViewers.emi.runConfig = true -almostgradle.recipeViewers.emi.version = 1.1.21 -almostgradle.recipeViewers.emi.minecraftVersion = 1.21.1 +almostgradle.recipeViewers.emi.runConfig = false +#almostgradle.recipeViewers.emi.version = 1.1.21 +#almostgradle.recipeViewers.emi.minecraftVersion = 1.21.1 # gradle org.gradle.vfs.watch = true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index accaf1a..626bad2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase = GRADLE_USER_HOME distributionPath = wrapper/dists -distributionUrl = https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip +distributionUrl = https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip networkTimeout = 10000 validateDistributionUrl = true zipStoreBase = GRADLE_USER_HOME From 512c4822ec829e65dc4822267987f520682c5514 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 09:18:03 +0200 Subject: [PATCH 02/52] NonnullDefault -> NullMarked --- .../merequester/client/abstraction/package-info.java | 4 ++-- .../com/almostreliable/merequester/client/package-info.java | 4 ++-- .../merequester/client/widgets/package-info.java | 4 ++-- .../almostreliable/merequester/compat/wtlib/package-info.java | 4 ++-- .../com/almostreliable/merequester/core/package-info.java | 4 ++-- .../merequester/mixin/accessors/package-info.java | 4 ++-- .../com/almostreliable/merequester/network/package-info.java | 4 ++-- .../java/com/almostreliable/merequester/package-info.java | 4 ++-- .../merequester/requester/abstraction/package-info.java | 4 ++-- .../almostreliable/merequester/requester/package-info.java | 4 ++-- .../merequester/requester/status/package-info.java | 4 ++-- .../com/almostreliable/merequester/terminal/package-info.java | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/package-info.java b/src/main/java/com/almostreliable/merequester/client/abstraction/package-info.java index e31a1e8..3f98e39 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/package-info.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.client.abstraction; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/client/package-info.java b/src/main/java/com/almostreliable/merequester/client/package-info.java index 6ff2fbb..3d51447 100644 --- a/src/main/java/com/almostreliable/merequester/client/package-info.java +++ b/src/main/java/com/almostreliable/merequester/client/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.client; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/package-info.java b/src/main/java/com/almostreliable/merequester/client/widgets/package-info.java index f23b522..253617f 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/package-info.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.client.widgets; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/compat/wtlib/package-info.java b/src/main/java/com/almostreliable/merequester/compat/wtlib/package-info.java index c17aa3b..0f1da05 100644 --- a/src/main/java/com/almostreliable/merequester/compat/wtlib/package-info.java +++ b/src/main/java/com/almostreliable/merequester/compat/wtlib/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.compat.wtlib; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/core/package-info.java b/src/main/java/com/almostreliable/merequester/core/package-info.java index d0e6f59..176f9a4 100644 --- a/src/main/java/com/almostreliable/merequester/core/package-info.java +++ b/src/main/java/com/almostreliable/merequester/core/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.core; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/mixin/accessors/package-info.java b/src/main/java/com/almostreliable/merequester/mixin/accessors/package-info.java index 9068dc5..6222eff 100644 --- a/src/main/java/com/almostreliable/merequester/mixin/accessors/package-info.java +++ b/src/main/java/com/almostreliable/merequester/mixin/accessors/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.mixin.accessors; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/network/package-info.java b/src/main/java/com/almostreliable/merequester/network/package-info.java index ed46cb6..d8b46cb 100644 --- a/src/main/java/com/almostreliable/merequester/network/package-info.java +++ b/src/main/java/com/almostreliable/merequester/network/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.network; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/package-info.java b/src/main/java/com/almostreliable/merequester/package-info.java index 2c6d2d3..3af68fd 100644 --- a/src/main/java/com/almostreliable/merequester/package-info.java +++ b/src/main/java/com/almostreliable/merequester/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/requester/abstraction/package-info.java b/src/main/java/com/almostreliable/merequester/requester/abstraction/package-info.java index 820dfb9..f5f939e 100644 --- a/src/main/java/com/almostreliable/merequester/requester/abstraction/package-info.java +++ b/src/main/java/com/almostreliable/merequester/requester/abstraction/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.requester.abstraction; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/requester/package-info.java b/src/main/java/com/almostreliable/merequester/requester/package-info.java index 565fbfd..dd57a74 100644 --- a/src/main/java/com/almostreliable/merequester/requester/package-info.java +++ b/src/main/java/com/almostreliable/merequester/requester/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.requester; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/requester/status/package-info.java b/src/main/java/com/almostreliable/merequester/requester/status/package-info.java index 866c82e..9e6c185 100644 --- a/src/main/java/com/almostreliable/merequester/requester/status/package-info.java +++ b/src/main/java/com/almostreliable/merequester/requester/status/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.requester.status; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/almostreliable/merequester/terminal/package-info.java b/src/main/java/com/almostreliable/merequester/terminal/package-info.java index e54711b..20a35bb 100644 --- a/src/main/java/com/almostreliable/merequester/terminal/package-info.java +++ b/src/main/java/com/almostreliable/merequester/terminal/package-info.java @@ -1,4 +1,4 @@ -@NonnullDefault +@NullMarked package com.almostreliable.merequester.terminal; -import org.lwjgl.system.NonnullDefault; +import org.jspecify.annotations.NullMarked; From 09596c4826ba762a0e89a94e1b13dafb113f762b Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 08:37:53 +0200 Subject: [PATCH 03/52] GuiGraphics -> GuiGraphicsExtractor --- .../client/abstraction/AbstractRequesterScreen.java | 8 ++++---- .../merequester/client/widgets/NumberField.java | 4 ++-- .../merequester/client/widgets/StateBox.java | 4 ++-- .../merequester/client/widgets/StatusDisplay.java | 4 ++-- .../merequester/client/widgets/SubmitButton.java | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index 2c15f4d..f10cf07 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -8,7 +8,7 @@ import com.almostreliable.merequester.requester.Request; import com.almostreliable.merequester.requester.abstraction.AbstractRequesterMenu; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.renderer.Rect2i; import net.minecraft.nbt.CompoundTag; @@ -165,7 +165,7 @@ protected EmptyingAction getEmptyingAction(Slot slot, ItemStack carried) { } @Override - public void drawFG(GuiGraphics guiGraphics, int pX, int pY, int mX, int mY) { + public void drawFG(GuiGraphicsExtractor guiGraphics, int pX, int pY, int mX, int mY) { menu.slots.removeIf(RequestSlot.class::isInstance); int textColor = style.getColor(PaletteColor.DEFAULT_TEXT_COLOR).toARGB(); @@ -262,7 +262,7 @@ protected void slotClicked(@Nullable Slot slot, int slotIndex, int mouseButton, } @Override - public void drawBG(GuiGraphics guiGraphics, int pX, int pY, int mX, int mY, float partial) { + public void drawBG(GuiGraphicsExtractor guiGraphics, int pX, int pY, int mX, int mY, float partial) { blit(guiGraphics, pX, pY, HEADER_BBOX); int scrollLevel = scrollbar.getCurrentScroll(); @@ -296,7 +296,7 @@ protected void resetScrollbar() { protected abstract RequesterReference getById(long requesterId, String name, long sortBy); - private void blit(GuiGraphics guiGraphics, int pX, int pY, Rect2i srcRect) { + private void blit(GuiGraphicsExtractor guiGraphics, int pX, int pY, Rect2i srcRect) { guiGraphics.blit(texture, pX, pY, srcRect.getX(), srcRect.getY(), srcRect.getWidth(), srcRect.getHeight()); } diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java index 46758af..a11da1d 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java @@ -5,7 +5,7 @@ import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.network.chat.Component; import appeng.api.stacks.AEFluidKey; @@ -75,7 +75,7 @@ public class NumberField extends ConfirmableTextField { } @Override - public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partial) { + public void renderWidget(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partial) { super.renderWidget(guiGraphics, mouseX, mouseY, partial); if (!isFluid) return; guiGraphics.drawString(Minecraft.getInstance().font, "B", getX() + WIDTH - PADDING, getY(), 0x54_5454, false); diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java b/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java index a3c4968..55e3b8e 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java @@ -2,7 +2,7 @@ import com.almostreliable.merequester.Utils; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; @@ -30,7 +30,7 @@ public class StateBox extends AECheckbox implements ITooltip { } @Override - public void renderWidget(GuiGraphics guiGraphics, int mX, int mY, float partial) { + public void renderWidget(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { Blitter icon; if (isMouseOver(mX, mY) && !isFocused()) { icon = isSelected() ? CHECKED_FOCUS : UNCHECKED_FOCUS; diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java b/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java index 97e6574..d784529 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java @@ -4,7 +4,7 @@ import com.almostreliable.merequester.requester.status.RequestStatus; import net.minecraft.ChatFormatting; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.screens.Screen; @@ -38,7 +38,7 @@ public void updateWidgetNarration(NarrationElementOutput narrationElementOutput) @SuppressWarnings("DataFlowIssue") @Override - public void renderWidget(GuiGraphics guiGraphics, int mX, int mY, float partialTick) { + public void renderWidget(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partialTick) { guiGraphics.fill(getX(), getY(), getX() + width, getY() + height, 0xFF << 3 * 8 | getStatusColor().getColor()); } diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java b/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java index 56e261f..6172163 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java @@ -2,7 +2,7 @@ import com.almostreliable.merequester.Utils; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; @@ -27,7 +27,7 @@ public class SubmitButton extends AECheckbox implements ITooltip { } @Override - public void renderWidget(GuiGraphics guiGraphics, int mX, int mY, float partial) { + public void renderWidget(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { Blitter icon = isFocused() || isMouseOver(mX, mY) ? FOCUSED : UNFOCUSED; if (!isMouseOver(mX, mY)) { setFocused(false); From d8741bcd7270eb26b85ac21e874f509581896cd7 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 08:52:20 +0200 Subject: [PATCH 04/52] drawString -> text --- .../client/abstraction/AbstractRequesterScreen.java | 4 ++-- .../merequester/client/widgets/NumberField.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index f10cf07..ef7b655 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -173,7 +173,7 @@ public void drawFG(GuiGraphicsExtractor guiGraphics, int pX, int pY, int mX, int if (lines.isEmpty()) { var text = Utils.translate("gui", "no_requesters").getString(); var textWidth = font.width(text); - guiGraphics.drawString( + guiGraphics.text( font, text, (int) ((GUI_WIDTH - textWidth) / 2f - 10), @@ -203,7 +203,7 @@ public void drawFG(GuiGraphicsExtractor guiGraphics, int pX, int pY, int mX, int if (rows > 1) text = String.format("%s (%s)", text, rows); text = font.plainSubstrByWidth(text, TEXT_MAX_WIDTH, true); - guiGraphics.drawString( + guiGraphics.text( font, text, GUI_PADDING_X + TEXT_MARGIN_X, diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java index a11da1d..df8c3a8 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java @@ -78,7 +78,7 @@ public class NumberField extends ConfirmableTextField { public void renderWidget(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partial) { super.renderWidget(guiGraphics, mouseX, mouseY, partial); if (!isFluid) return; - guiGraphics.drawString(Minecraft.getInstance().font, "B", getX() + WIDTH - PADDING, getY(), 0x54_5454, false); + guiGraphics.text(Minecraft.getInstance().font, "B", getX() + WIDTH - PADDING, getY(), 0x54_5454, false); } private void validate() { From c29d14849e7c8f0b18c9e20e0932b2a3e4f41e97 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 08:53:52 +0200 Subject: [PATCH 05/52] renderWidget -> extractWidgetRenderState --- .../merequester/client/widgets/NumberField.java | 4 ++-- .../almostreliable/merequester/client/widgets/StateBox.java | 2 +- .../merequester/client/widgets/StatusDisplay.java | 2 +- .../merequester/client/widgets/SubmitButton.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java index df8c3a8..915dacc 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java @@ -75,8 +75,8 @@ public class NumberField extends ConfirmableTextField { } @Override - public void renderWidget(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partial) { - super.renderWidget(guiGraphics, mouseX, mouseY, partial); + public void extractWidgetRenderState(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partial) { + super.extractWidgetRenderState(guiGraphics, mouseX, mouseY, partial); if (!isFluid) return; guiGraphics.text(Minecraft.getInstance().font, "B", getX() + WIDTH - PADDING, getY(), 0x54_5454, false); } diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java b/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java index 55e3b8e..9e4a610 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java @@ -30,7 +30,7 @@ public class StateBox extends AECheckbox implements ITooltip { } @Override - public void renderWidget(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { + public void extractWidgetRenderState(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { Blitter icon; if (isMouseOver(mX, mY) && !isFocused()) { icon = isSelected() ? CHECKED_FOCUS : UNCHECKED_FOCUS; diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java b/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java index d784529..9a8710b 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java @@ -38,7 +38,7 @@ public void updateWidgetNarration(NarrationElementOutput narrationElementOutput) @SuppressWarnings("DataFlowIssue") @Override - public void renderWidget(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partialTick) { + public void extractWidgetRenderState(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partialTick) { guiGraphics.fill(getX(), getY(), getX() + width, getY() + height, 0xFF << 3 * 8 | getStatusColor().getColor()); } diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java b/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java index 6172163..aaf11d4 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java @@ -27,7 +27,7 @@ public class SubmitButton extends AECheckbox implements ITooltip { } @Override - public void renderWidget(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { + public void extractWidgetRenderState(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { Blitter icon = isFocused() || isMouseOver(mX, mY) ? FOCUSED : UNFOCUSED; if (!isMouseOver(mX, mY)) { setFocused(false); From 6300eeadfc65b3967cb4a6004c35094a80ae4088 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 09:51:56 +0200 Subject: [PATCH 06/52] fixup extractWidgetRenderState -> extractContents --- .../com/almostreliable/merequester/client/widgets/StateBox.java | 2 +- .../almostreliable/merequester/client/widgets/SubmitButton.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java b/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java index 9e4a610..1023c08 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/StateBox.java @@ -30,7 +30,7 @@ public class StateBox extends AECheckbox implements ITooltip { } @Override - public void extractWidgetRenderState(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { + public void extractContents(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { Blitter icon; if (isMouseOver(mX, mY) && !isFocused()) { icon = isSelected() ? CHECKED_FOCUS : UNCHECKED_FOCUS; diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java b/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java index aaf11d4..61dd636 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/SubmitButton.java @@ -27,7 +27,7 @@ public class SubmitButton extends AECheckbox implements ITooltip { } @Override - public void extractWidgetRenderState(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { + public void extractContents(GuiGraphicsExtractor guiGraphics, int mX, int mY, float partial) { Blitter icon = isFocused() || isMouseOver(mX, mY) ? FOCUSED : UNFOCUSED; if (!isMouseOver(mX, mY)) { setFocused(false); From e8ff754656c9a98449e332d160eaf42fdcf55619 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 09:31:36 +0200 Subject: [PATCH 07/52] ClickType -> ContainerInput --- .../client/abstraction/AbstractRequesterScreen.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index ef7b655..e7a9191 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -15,7 +15,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.network.PacketDistributor; @@ -219,9 +219,9 @@ public void drawFG(GuiGraphicsExtractor guiGraphics, int pX, int pY, int mX, int } @Override - protected void slotClicked(@Nullable Slot slot, int slotIndex, int mouseButton, ClickType clickType) { + protected void slotClicked(@Nullable Slot slot, int slotIndex, int mouseButton, ContainerInput containerInput) { if (!(slot instanceof RequestSlot requestSlot)) { - super.slotClicked(slot, slotIndex, mouseButton, clickType); + super.slotClicked(slot, slotIndex, mouseButton, containerInput); return; } @@ -239,7 +239,7 @@ protected void slotClicked(@Nullable Slot slot, int slotIndex, int mouseButton, } InventoryAction action = null; - switch (clickType) { + switch (containerInput) { case PICKUP -> action = mouseButton == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN; case QUICK_MOVE -> action = mouseButton == 1 ? InventoryAction.PICKUP_SINGLE : InventoryAction.SHIFT_CLICK; case CLONE -> { From 2875d0ab3906a35ae35b5182b5c6f4972571feeb Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 09:42:31 +0200 Subject: [PATCH 08/52] ResourceLocation -> Identifier --- src/main/java/com/almostreliable/merequester/Utils.java | 6 +++--- .../almostreliable/merequester/client/RequesterScreen.java | 4 ++-- .../merequester/client/RequesterTerminalScreen.java | 4 ++-- .../client/abstraction/AbstractRequesterScreen.java | 6 +++--- .../com/almostreliable/merequester/core/Registration.java | 2 +- .../merequester/terminal/RequesterTerminalPart.java | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/Utils.java b/src/main/java/com/almostreliable/merequester/Utils.java index b29c54e..326f8ce 100644 --- a/src/main/java/com/almostreliable/merequester/Utils.java +++ b/src/main/java/com/almostreliable/merequester/Utils.java @@ -3,7 +3,7 @@ import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import com.mojang.blaze3d.platform.InputConstants; @@ -13,8 +13,8 @@ public final class Utils { private Utils() {} - public static ResourceLocation getRL(String path) { - return ResourceLocation.fromNamespaceAndPath(ModConstants.MOD_ID, path); + public static Identifier getRL(String path) { + return Identifier.fromNamespaceAndPath(ModConstants.MOD_ID, path); } public static MutableComponent translate(String type, String key, Object... args) { diff --git a/src/main/java/com/almostreliable/merequester/client/RequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/RequesterScreen.java index 28f9052..ba9a260 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/RequesterScreen.java @@ -9,7 +9,7 @@ import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Inventory; @@ -22,7 +22,7 @@ public class RequesterScreen extends AbstractRequesterScreen { - private static final ResourceLocation TEXTURE = Utils.getRL(String.format("textures/gui/%s.png", MERequester.REQUESTER_ID)); + private static final Identifier TEXTURE = Utils.getRL(String.format("textures/gui/%s.png", MERequester.REQUESTER_ID)); private static final Rect2i FOOTER_BBOX = new Rect2i(0, 114, GUI_WIDTH, GUI_FOOTER_HEIGHT + 2); private static final int MAX_ROW_COUNT = 10; diff --git a/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java b/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java index b3f0908..7e49d8c 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java @@ -10,7 +10,7 @@ import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.world.entity.player.Inventory; import appeng.api.config.Settings; @@ -36,7 +36,7 @@ public class RequesterTerminalScreen extends AbstractRequesterScreen { - private static final ResourceLocation TEXTURE = Utils.getRL(String.format("textures/gui/%s.png", MERequester.TERMINAL_ID)); + private static final Identifier TEXTURE = Utils.getRL(String.format("textures/gui/%s.png", MERequester.TERMINAL_ID)); private static final Rect2i FOOTER_BBOX = new Rect2i(0, 133, GUI_WIDTH, GUI_FOOTER_HEIGHT + 2); private final HashMap byId = new HashMap<>(); diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index e7a9191..d9c065a 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -13,7 +13,7 @@ import net.minecraft.client.renderer.Rect2i; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.inventory.Slot; @@ -65,7 +65,7 @@ public abstract class AbstractRequesterScreen e private static final Rect2i TEXT_BBOX = new Rect2i(0, 60, GUI_WIDTH, ROW_HEIGHT); private static final Rect2i REQUEST_BBOX = new Rect2i(0, 38, GUI_WIDTH, ROW_HEIGHT); - private final ResourceLocation texture; + private final Identifier texture; protected final ArrayList lines = new ArrayList<>(); private final Scrollbar scrollbar; @@ -76,7 +76,7 @@ public abstract class AbstractRequesterScreen e @SuppressWarnings("AssignmentToSuperclassField") protected AbstractRequesterScreen( - M menu, Inventory playerInventory, Component name, ScreenStyle style, ResourceLocation texture + M menu, Inventory playerInventory, Component name, ScreenStyle style, Identifier texture ) { super(menu, playerInventory, name, style); this.texture = texture; diff --git a/src/main/java/com/almostreliable/merequester/core/Registration.java b/src/main/java/com/almostreliable/merequester/core/Registration.java index a39f506..c9b7b6c 100644 --- a/src/main/java/com/almostreliable/merequester/core/Registration.java +++ b/src/main/java/com/almostreliable/merequester/core/Registration.java @@ -173,7 +173,7 @@ private static void initContents(BuildCreativeModeTabContentsEvent event) { } private static void registerTab(RegisterEvent registerEvent) { - registerEvent.register(Registries.CREATIVE_MODE_TAB, TAB_KEY.location(), () -> TAB); + registerEvent.register(Registries.CREATIVE_MODE_TAB, TAB_KEY.identifier(), () -> TAB); } } } diff --git a/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalPart.java b/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalPart.java index 207ffad..60a43d7 100644 --- a/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalPart.java +++ b/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalPart.java @@ -3,7 +3,7 @@ import com.almostreliable.merequester.MERequester; import com.almostreliable.merequester.Utils; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; @@ -22,9 +22,9 @@ public class RequesterTerminalPart extends AbstractDisplayPart implements RequesterTerminalHost { @PartModels - private static final ResourceLocation MODEL_OFF = Utils.getRL(String.format("part/%s_off", MERequester.TERMINAL_ID)); + private static final Identifier MODEL_OFF = Utils.getRL(String.format("part/%s_off", MERequester.TERMINAL_ID)); @PartModels - private static final ResourceLocation MODEL_ON = Utils.getRL(String.format("part/%s_on", MERequester.TERMINAL_ID)); + private static final Identifier MODEL_ON = Utils.getRL(String.format("part/%s_on", MERequester.TERMINAL_ID)); private static final IPartModel MODELS_OFF = new PartModel(MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF); private static final IPartModel MODELS_ON = new PartModel(MODEL_BASE, MODEL_ON, MODEL_STATUS_ON); From fe26102b74b3c16e3c32844bc39fe48b195de76e Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 09:59:45 +0200 Subject: [PATCH 09/52] replace InteractionResult.sidedSuccess --- .../almostreliable/merequester/requester/RequesterBlock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java index 927ea8a..a465e90 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java @@ -45,7 +45,7 @@ protected InteractionResult useWithoutItem(BlockState state, Level level, BlockP if (!level.isClientSide()) { MenuOpener.open(RequesterMenu.TYPE, player, MenuLocators.forBlockEntity(entity)); } - return InteractionResult.sidedSuccess(level.isClientSide()); + return level.isClientSide() ? InteractionResult.SUCCESS : InteractionResult.SUCCESS_SERVER; } @Override From 7be73b9b5f7eda7477230cabf8148b13decb667f Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 10:14:47 +0200 Subject: [PATCH 10/52] PacketDistributor.sendToServer -> ClientPacketDistributor.sendToServer --- .../com/almostreliable/merequester/client/RequestSlot.java | 4 ++-- .../client/abstraction/AbstractRequesterScreen.java | 6 +++--- .../merequester/client/widgets/RequestWidget.java | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/RequestSlot.java b/src/main/java/com/almostreliable/merequester/client/RequestSlot.java index f203a14..0f900f7 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequestSlot.java +++ b/src/main/java/com/almostreliable/merequester/client/RequestSlot.java @@ -9,7 +9,7 @@ import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; -import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.client.network.ClientPacketDistributor; import appeng.menu.slot.FakeSlot; @@ -82,6 +82,6 @@ public void setLocked(boolean locked) { @Override public void setFilterTo(ItemStack itemStack) { - PacketDistributor.sendToServer(new DragAndDropPacket(getRequesterReference().getRequesterId(), getSlot(), itemStack)); + ClientPacketDistributor.sendToServer(new DragAndDropPacket(getRequesterReference().getRequesterId(), getSlot(), itemStack)); } } diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index d9c065a..a5ba62a 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -18,7 +18,7 @@ import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.client.network.ClientPacketDistributor; import appeng.api.behaviors.ContainerItemStrategies; import appeng.api.behaviors.EmptyingAction; @@ -234,7 +234,7 @@ protected void slotClicked(@Nullable Slot slot, int slotIndex, int mouseButton, requestSlot.getSlot(), requestSlot.getRequesterReference().getRequesterId() ); - PacketDistributor.sendToServer(packet); + ClientPacketDistributor.sendToServer(packet); return; } @@ -257,7 +257,7 @@ protected void slotClicked(@Nullable Slot slot, int slotIndex, int mouseButton, requestSlot.getSlot(), requestSlot.getRequesterReference().getRequesterId() ); - PacketDistributor.sendToServer(packet); + ClientPacketDistributor.sendToServer(packet); } } diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java b/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java index bfb8e71..7ef7634 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java @@ -8,7 +8,7 @@ import net.minecraft.client.gui.components.AbstractWidget; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; -import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.client.network.ClientPacketDistributor; import appeng.client.gui.style.ScreenStyle; @@ -107,7 +107,7 @@ private void stateBoxChanged(@Nullable Request request) { var newState = stateBox.isSelected(); request.updateState(newState); // prevent jittery animation before server information is received var requesterId = ((RequesterReference) request.getRequesterReference()).getRequesterId(); - PacketDistributor.sendToServer(new RequestUpdatePacket(requesterId, request.getIndex(), newState)); + ClientPacketDistributor.sendToServer(new RequestUpdatePacket(requesterId, request.getIndex(), newState)); } private void amountFieldSubmitted(@Nullable Request request, long amount) { @@ -137,7 +137,7 @@ private void submitButtonClicked(@Nullable Request request) { long amount = amountField.getLongValue().orElse(0); long batch = batchField.getLongValue().orElse(1); var requesterId = ((RequesterReference) request.getRequesterReference()).getRequesterId(); - PacketDistributor.sendToServer(new RequestUpdatePacket(requesterId, request.getIndex(), amount, batch)); + ClientPacketDistributor.sendToServer(new RequestUpdatePacket(requesterId, request.getIndex(), amount, batch)); } private boolean isInactive(@Nullable Request request) { From 6047cdbb5b6d577dec141397b335a4de19c93d3f Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 10:24:11 +0200 Subject: [PATCH 11/52] isValidClickButton signature changed --- .../merequester/client/widgets/StatusDisplay.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java b/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java index 9a8710b..0c71a13 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java @@ -8,6 +8,7 @@ import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.MouseButtonInfo; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; @@ -43,7 +44,7 @@ public void extractWidgetRenderState(GuiGraphicsExtractor guiGraphics, int mX, i } @Override - protected boolean isValidClickButton(int button) { + protected boolean isValidClickButton(MouseButtonInfo buttonInfo) { return false; } From f5b2b00c4e98321c4dbfcce2c41cc6c05152eb3b Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 10:33:45 +0200 Subject: [PATCH 12/52] appeng.init.client.InitScreens moved --- .../java/com/almostreliable/merequester/MERequesterClient.java | 2 +- .../merequester/compat/wtlib/WirelessTerminalCompat.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/MERequesterClient.java b/src/main/java/com/almostreliable/merequester/MERequesterClient.java index 3e68ee3..c84f7ff 100644 --- a/src/main/java/com/almostreliable/merequester/MERequesterClient.java +++ b/src/main/java/com/almostreliable/merequester/MERequesterClient.java @@ -17,7 +17,7 @@ import appeng.api.util.AEColor; import appeng.client.render.StaticItemColor; -import appeng.init.client.InitScreens; +import appeng.client.InitScreens; @Mod(value = ModConstants.MOD_ID, dist = Dist.CLIENT) public final class MERequesterClient { diff --git a/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java b/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java index ef1e964..586e478 100644 --- a/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java +++ b/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java @@ -14,7 +14,7 @@ import net.neoforged.neoforge.registries.DeferredRegister; import appeng.api.features.GridLinkables; -import appeng.init.client.InitScreens; +import appeng.client.InitScreens; import appeng.items.tools.powered.WirelessTerminalItem; import appeng.items.tools.powered.powersink.PoweredItemCapabilities; import de.mari_023.ae2wtlib.api.gui.Icon; From 6664bdae6c04e22f1b6b999720c56269cbc83087 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 10:43:35 +0200 Subject: [PATCH 13/52] keyPressed signature changed --- .../merequester/compat/wtlib/ReqWirelessTerminalScreen.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalScreen.java b/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalScreen.java index 32a23cc..b158f41 100644 --- a/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalScreen.java +++ b/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalScreen.java @@ -2,6 +2,7 @@ import com.almostreliable.merequester.client.RequesterTerminalScreen; +import net.minecraft.client.input.KeyEvent; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; @@ -42,7 +43,7 @@ public WTMenuHost getHost() { public void storeState() {} @Override - public boolean keyPressed(int keyCode, int scanCode, int keyPressed) { - return super.keyPressed(keyCode, scanCode, keyPressed) || checkForTerminalKeys(keyCode, scanCode); + public boolean keyPressed(KeyEvent event) { + return super.keyPressed(event) || checkForTerminalKeys(event); } } \ No newline at end of file From 4a28ece4776f4d29cdc3e8a14e60160e29164de4 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 10:46:37 +0200 Subject: [PATCH 14/52] Screen.hasShiftDown -> Minecraft.getInstance().hasShiftDown() --- .../merequester/client/widgets/StatusDisplay.java | 4 ++-- .../almostreliable/merequester/requester/RequesterBlock.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java b/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java index 0c71a13..c670acc 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/StatusDisplay.java @@ -4,10 +4,10 @@ import com.almostreliable.merequester.requester.status.RequestStatus; import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.narration.NarrationElementOutput; -import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.input.MouseButtonInfo; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; @@ -63,7 +63,7 @@ private ChatFormatting getStatusColor(RequestStatus requestStatus) { public List getTooltipMessage() { List tooltip = new ArrayList<>(); tooltip.add(Utils.translate("tooltip", "status")); - if (Screen.hasShiftDown()) { + if (Minecraft.getInstance().hasShiftDown()) { tooltip.addAll(List.of( Component.literal(" "), Utils.translate("tooltip", RequestStatus.IDLE.toString().toLowerCase()).withStyle(getStatusColor(RequestStatus.IDLE)), diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java index a465e90..323a4f3 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java @@ -4,7 +4,7 @@ import com.almostreliable.merequester.Utils; import net.minecraft.ChatFormatting; -import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionResult; @@ -66,7 +66,7 @@ public IOrientationStrategy getOrientationStrategy() { @Override public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipFlag tooltipFlag) { - if (Screen.hasShiftDown()) { + if (Minecraft.getInstance().hasShiftDown()) { tooltip.add(Component.literal(" ")); tooltip.add(Utils.translate("tooltip", String.format("%s_desc", MERequester.REQUESTER_ID)).withStyle(ChatFormatting.AQUA)); } else { From db597c2ba4a44d755e94e1609d10826b75bf0c51 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 12:08:01 +0200 Subject: [PATCH 15/52] level.isClientSide -> level.isClientSide() --- .../merequester/requester/RequesterBlockEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java index 698a0ae..c799c3d 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java @@ -134,7 +134,7 @@ public TickingRequest getTickingRequest(IGridNode node) { @Override public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) { - if (level == null || level.isClientSide || !getMainNode().isActive()) return TickRateModulation.IDLE; + if (level == null || level.isClientSide() || !getMainNode().isActive()) return TickRateModulation.IDLE; if (handleRequests()) setChanged(); return currentTickRate; } From 3a7013aaa035e2e71da7713fff299599f8ed8314 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:47:52 +0200 Subject: [PATCH 16/52] move metalProps to match AE2 code --- .../com/almostreliable/merequester/core/Registration.java | 3 +-- .../almostreliable/merequester/requester/RequesterBlock.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/core/Registration.java b/src/main/java/com/almostreliable/merequester/core/Registration.java index c9b7b6c..696d3aa 100644 --- a/src/main/java/com/almostreliable/merequester/core/Registration.java +++ b/src/main/java/com/almostreliable/merequester/core/Registration.java @@ -62,8 +62,7 @@ public final class Registration { public static final DeferredBlock REQUESTER_BLOCK = BLOCKS.registerBlock( REQUESTER_ID, - RequesterBlock::new, - AEBaseBlock.metalProps() + RequesterBlock::new ); public static final DeferredItem REQUESTER_ITEM = ITEMS.registerSimpleBlockItem( REQUESTER_ID, diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java index 323a4f3..2107fc6 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java @@ -32,8 +32,8 @@ public class RequesterBlock extends AEBaseEntityBlock { private static final IOrientationStrategy ORIENTATION_STRATEGY = new FacingWithVerticalSpin(); private static final BooleanProperty ACTIVE = BooleanProperty.create("active"); - public RequesterBlock(Properties properties) { - super(properties); + public RequesterBlock(Properties p) { + super(metalProps(p)); registerDefaultState(defaultBlockState().setValue(ACTIVE, false)); } From 4c421effe66d82ebabe8b38ae292c5a6e5d6ed71 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 10:56:39 +0200 Subject: [PATCH 17/52] REVIEW NEEDED- charTyped signature changed --- .../merequester/client/RequesterTerminalScreen.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java b/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java index 7e49d8c..d9c8e0b 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java @@ -8,6 +8,7 @@ import com.almostreliable.merequester.requester.Request; import com.almostreliable.merequester.terminal.RequesterTerminalMenu; +import net.minecraft.client.input.CharacterEvent; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; @@ -71,8 +72,8 @@ public boolean mouseClicked(double mX, double mY, int button) { } @Override - public boolean charTyped(char character, int key) { - return character == ' ' && searchField.getValue().isEmpty() || super.charTyped(character, key); + public boolean charTyped(CharacterEvent event) { + return event.codepointAsString().equals(" ") && searchField.getValue().isEmpty() || super.charTyped(event); } @Override From 9d7c1242cee97172b7c7e660ba0678729c1b2e81 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 10:59:30 +0200 Subject: [PATCH 18/52] REVIEW NEEDED - mouseClicked signature changed --- .../merequester/client/RequesterTerminalScreen.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java b/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java index d9c8e0b..870b507 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java @@ -9,6 +9,7 @@ import com.almostreliable.merequester.terminal.RequesterTerminalMenu; import net.minecraft.client.input.CharacterEvent; +import net.minecraft.client.input.MouseButtonEvent; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; @@ -64,11 +65,11 @@ public RequesterTerminalScreen( } @Override - public boolean mouseClicked(double mX, double mY, int button) { - if (button == 1 && searchField.isMouseOver(mX, mY)) { + public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + if (event.button() == 1 && searchField.isMouseOver(event.x(), event.y())) { searchField.setValue(""); } - return super.mouseClicked(mX, mY, button); + return super.mouseClicked(event, doubleClick); } @Override From ceec9a563b929669280bdbd01ceb13a51fac1aa3 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Sat, 22 Aug 2026 20:43:44 +0200 Subject: [PATCH 19/52] REVIEW NEEDED - adapt recipes --- .../data/merequester/recipe/requester.json | 25 ++++++------------- .../recipe/requester_terminal.json | 12 +++------ .../recipe/wireless/combine_access.json | 8 ++---- .../recipe/wireless/combine_crafting.json | 8 ++---- .../recipe/wireless/combine_encoding.json | 8 ++---- .../recipe/wireless/upgrade_requester.json | 4 +-- .../wireless/wireless_requester_terminal.json | 13 +++------- 7 files changed, 21 insertions(+), 57 deletions(-) diff --git a/src/main/resources/data/merequester/recipe/requester.json b/src/main/resources/data/merequester/recipe/requester.json index 1849fd6..3186c3c 100644 --- a/src/main/resources/data/merequester/recipe/requester.json +++ b/src/main/resources/data/merequester/recipe/requester.json @@ -1,29 +1,18 @@ { "type": "minecraft:crafting_shaped", + "category": "misc", "pattern": [ "eie", "apa", "csc" ], "key": { - "e": { - "tag": "c:ingots/iron" - }, - "i": { - "tag": "ae2:interface" - }, - "a": { - "item": "ae2:crafting_accelerator" - }, - "p": { - "item": "ae2:engineering_processor" - }, - "c": { - "tag": "c:ingots/copper" - }, - "s": { - "item": "minecraft:amethyst_shard" - } + "e": "#c:ingots/iron", + "i": "#ae2:interface", + "a": "ae2:crafting_accelerator", + "p": "ae2:engineering_processor", + "c": "#c:ingots/copper", + "s": "minecraft:amethyst_shard" }, "result": { "id": "merequester:requester" diff --git a/src/main/resources/data/merequester/recipe/requester_terminal.json b/src/main/resources/data/merequester/recipe/requester_terminal.json index 414b1e5..c90fdb9 100644 --- a/src/main/resources/data/merequester/recipe/requester_terminal.json +++ b/src/main/resources/data/merequester/recipe/requester_terminal.json @@ -1,15 +1,9 @@ { "type": "minecraft:crafting_shapeless", "ingredients": [ - { - "tag": "ae2:illuminated_panel" - }, - { - "item": "ae2:logic_processor" - }, - { - "item": "merequester:requester" - } + "#ae2:illuminated_panel", + "ae2:logic_processor", + "merequester:requester" ], "result": { "id": "merequester:requester_terminal" diff --git a/src/main/resources/data/merequester/recipe/wireless/combine_access.json b/src/main/resources/data/merequester/recipe/wireless/combine_access.json index 4a70d44..ce9b4ea 100644 --- a/src/main/resources/data/merequester/recipe/wireless/combine_access.json +++ b/src/main/resources/data/merequester/recipe/wireless/combine_access.json @@ -6,12 +6,8 @@ } ], "type": "ae2wtlib:combine", - "terminalA": { - "item": "merequester:wireless_requester_terminal" - }, - "terminalB": { - "item": "ae2wtlib:wireless_pattern_access_terminal" - }, + "terminalA": "merequester:wireless_requester_terminal", + "terminalB": "ae2wtlib:wireless_pattern_access_terminal", "terminalAName": "requester", "terminalBName": "pattern_access" } \ No newline at end of file diff --git a/src/main/resources/data/merequester/recipe/wireless/combine_crafting.json b/src/main/resources/data/merequester/recipe/wireless/combine_crafting.json index e004086..80a4a5d 100644 --- a/src/main/resources/data/merequester/recipe/wireless/combine_crafting.json +++ b/src/main/resources/data/merequester/recipe/wireless/combine_crafting.json @@ -6,12 +6,8 @@ } ], "type": "ae2wtlib:combine", - "terminalA": { - "item": "merequester:wireless_requester_terminal" - }, - "terminalB": { - "item": "ae2:wireless_crafting_terminal" - }, + "terminalA": "merequester:wireless_requester_terminal", + "terminalB": "ae2:wireless_crafting_terminal", "terminalAName": "requester", "terminalBName": "crafting" } \ No newline at end of file diff --git a/src/main/resources/data/merequester/recipe/wireless/combine_encoding.json b/src/main/resources/data/merequester/recipe/wireless/combine_encoding.json index b4b3344..7637ab9 100644 --- a/src/main/resources/data/merequester/recipe/wireless/combine_encoding.json +++ b/src/main/resources/data/merequester/recipe/wireless/combine_encoding.json @@ -6,12 +6,8 @@ } ], "type": "ae2wtlib:combine", - "terminalA": { - "item": "merequester:wireless_requester_terminal" - }, - "terminalB": { - "item": "ae2wtlib:wireless_pattern_encoding_terminal" - }, + "terminalA": "merequester:wireless_requester_terminal", + "terminalB": "ae2wtlib:wireless_pattern_encoding_terminal", "terminalAName": "requester", "terminalBName": "pattern_encoding" } \ No newline at end of file diff --git a/src/main/resources/data/merequester/recipe/wireless/upgrade_requester.json b/src/main/resources/data/merequester/recipe/wireless/upgrade_requester.json index 66906bd..8cbead8 100644 --- a/src/main/resources/data/merequester/recipe/wireless/upgrade_requester.json +++ b/src/main/resources/data/merequester/recipe/wireless/upgrade_requester.json @@ -6,8 +6,6 @@ } ], "type": "ae2wtlib:upgrade", - "terminal": { - "item": "merequester:wireless_requester_terminal" - }, + "terminal": "merequester:wireless_requester_terminal", "terminalName": "requester" } \ No newline at end of file diff --git a/src/main/resources/data/merequester/recipe/wireless/wireless_requester_terminal.json b/src/main/resources/data/merequester/recipe/wireless/wireless_requester_terminal.json index 4b92915..08d2e8c 100644 --- a/src/main/resources/data/merequester/recipe/wireless/wireless_requester_terminal.json +++ b/src/main/resources/data/merequester/recipe/wireless/wireless_requester_terminal.json @@ -6,21 +6,16 @@ } ], "type": "minecraft:crafting_shaped", + "category": "misc", "pattern": [ "a", "b", "c" ], "key": { - "a": { - "item": "ae2:wireless_receiver" - }, - "b": { - "item": "merequester:requester_terminal" - }, - "c": { - "item": "ae2:dense_energy_cell" - } + "a": "ae2:wireless_receiver", + "b": "merequester:requester_terminal", + "c": "ae2:dense_energy_cell" }, "result": { "id": "merequester:wireless_requester_terminal" From e357ab68ed85c8cfe06e3fc358ec9a91dc6bb75c Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 16:44:40 +0200 Subject: [PATCH 20/52] REVIEW NEEDED - item models --- .../assets/merequester/items/requester.json | 6 ++++ .../merequester/items/requester_terminal.json | 32 +++++++++++++++++++ .../items/wireless_requester_terminal.json | 6 ++++ 3 files changed, 44 insertions(+) create mode 100644 src/main/resources/assets/merequester/items/requester.json create mode 100644 src/main/resources/assets/merequester/items/requester_terminal.json create mode 100644 src/main/resources/assets/merequester/items/wireless_requester_terminal.json diff --git a/src/main/resources/assets/merequester/items/requester.json b/src/main/resources/assets/merequester/items/requester.json new file mode 100644 index 0000000..07f21a0 --- /dev/null +++ b/src/main/resources/assets/merequester/items/requester.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "merequester:item/requester" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/merequester/items/requester_terminal.json b/src/main/resources/assets/merequester/items/requester_terminal.json new file mode 100644 index 0000000..77ef0e7 --- /dev/null +++ b/src/main/resources/assets/merequester/items/requester_terminal.json @@ -0,0 +1,32 @@ +{ + "model": { + "type": "minecraft:model", + "model": "merequester:item/requester_terminal", + "tints": [ + { + "type": "minecraft:constant", + "value": -1 + }, + { + "type": "ae2:color", + "color": "fluix", + "variant": "dark" + }, + { + "type": "ae2:color", + "color": "fluix", + "variant": "medium" + }, + { + "type": "ae2:color", + "color": "fluix", + "variant": "bright" + }, + { + "type": "ae2:color", + "color": "fluix", + "variant": "medium_bright" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/merequester/items/wireless_requester_terminal.json b/src/main/resources/assets/merequester/items/wireless_requester_terminal.json new file mode 100644 index 0000000..191cd27 --- /dev/null +++ b/src/main/resources/assets/merequester/items/wireless_requester_terminal.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "merequester:item/wireless_requester_terminal" + } +} \ No newline at end of file From fcf7566a53c4625f14aba6d0cda7f85ee80278d9 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 14:18:47 +0200 Subject: [PATCH 21/52] REVIEW NEEDED - OnlyIn no longer available --- .../merequester/client/abstraction/RequesterReference.java | 3 --- .../merequester/client/widgets/RequestWidget.java | 3 --- .../java/com/almostreliable/merequester/requester/Request.java | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/RequesterReference.java b/src/main/java/com/almostreliable/merequester/client/abstraction/RequesterReference.java index 6609012..2896885 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/RequesterReference.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/RequesterReference.java @@ -4,15 +4,12 @@ import com.almostreliable.merequester.requester.abstraction.RequestHost; import net.minecraft.network.chat.Component; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; /** * yoinked from AE2's legacy {@code PatternProviderRecord} *

* Note: this class has a natural ordering that is inconsistent with equals. */ -@OnlyIn(Dist.CLIENT) public class RequesterReference implements RequestHost, Comparable { private final long requesterId; diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java b/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java index 7ef7634..ad1f3c7 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java @@ -6,8 +6,6 @@ import com.almostreliable.merequester.requester.Request; import net.minecraft.client.gui.components.AbstractWidget; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.neoforge.client.network.ClientPacketDistributor; import appeng.client.gui.style.ScreenStyle; @@ -17,7 +15,6 @@ import java.util.HashMap; import java.util.Map; -@OnlyIn(Dist.CLIENT) public class RequestWidget { private final RequestDisplay host; diff --git a/src/main/java/com/almostreliable/merequester/requester/Request.java b/src/main/java/com/almostreliable/merequester/requester/Request.java index ebf4444..634214c 100644 --- a/src/main/java/com/almostreliable/merequester/requester/Request.java +++ b/src/main/java/com/almostreliable/merequester/requester/Request.java @@ -9,8 +9,6 @@ import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.util.Mth; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.neoforge.common.util.INBTSerializable; import appeng.api.stacks.AEKey; @@ -189,7 +187,6 @@ public long getBatch() { return batch; } - @OnlyIn(Dist.CLIENT) public RequestHost getRequesterReference() { assert host != null; return host; From 5fc1b6d71091a6499bf4d0a57eb6e6c5579468ac Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:58:47 +0200 Subject: [PATCH 22/52] TODO - part models are now JSON and there is no datagen --- .../merequester/core/Registration.java | 15 ++++++------ .../terminal/RequesterTerminalPart.java | 22 ------------------ .../ae2/parts/requester_terminal.json | 23 +++++++++++++++++++ 3 files changed, 30 insertions(+), 30 deletions(-) create mode 100644 src/main/resources/assets/merequester/ae2/parts/requester_terminal.json diff --git a/src/main/java/com/almostreliable/merequester/core/Registration.java b/src/main/java/com/almostreliable/merequester/core/Registration.java index 696d3aa..9e71754 100644 --- a/src/main/java/com/almostreliable/merequester/core/Registration.java +++ b/src/main/java/com/almostreliable/merequester/core/Registration.java @@ -21,6 +21,8 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; @@ -32,11 +34,9 @@ import net.neoforged.neoforge.registries.RegisterEvent; import appeng.api.AECapabilities; -import appeng.api.parts.PartModels; import appeng.block.AEBaseBlock; import appeng.blockentity.AEBaseBlockEntity; import appeng.items.parts.PartItem; -import appeng.items.parts.PartModelsHelper; import java.util.List; @@ -67,15 +67,16 @@ public final class Registration { public static final DeferredItem REQUESTER_ITEM = ITEMS.registerSimpleBlockItem( REQUESTER_ID, REQUESTER_BLOCK, - new Item.Properties() + () -> new Item.Properties() ); public static final DeferredHolder, BlockEntityType> REQUESTER_ENTITY = BLOCK_ENTITIES.register( REQUESTER_ID, () -> { // noinspection DataFlowIssue - var type = BlockEntityType.Builder - .of(RequesterBlockEntity::new, REQUESTER_BLOCK.get()) - .build(null); + var type = new BlockEntityType( + RequesterBlockEntity::new, + REQUESTER_BLOCK.get() + ); AEBaseBlockEntity.registerBlockEntityItem(type, REQUESTER_BLOCK.asItem()); REQUESTER_BLOCK.get().setBlockEntity(RequesterBlockEntity.class, type, null, null); return type; @@ -89,8 +90,6 @@ public final class Registration { public static final DeferredItem> REQUESTER_TERMINAL = ITEMS.registerItem( TERMINAL_ID, properties -> { - PartModels.registerModels(PartModelsHelper.createModels(RequesterTerminalPart.class)); - return new PartItem<>( properties, RequesterTerminalPart.class, diff --git a/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalPart.java b/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalPart.java index 60a43d7..1de4dd7 100644 --- a/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalPart.java +++ b/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalPart.java @@ -1,18 +1,11 @@ package com.almostreliable.merequester.terminal; -import com.almostreliable.merequester.MERequester; -import com.almostreliable.merequester.Utils; - -import net.minecraft.resources.Identifier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; import appeng.api.parts.IPartItem; -import appeng.api.parts.IPartModel; -import appeng.items.parts.PartModels; import appeng.menu.MenuOpener; import appeng.menu.locator.MenuLocators; -import appeng.parts.PartModel; import appeng.parts.reporting.AbstractDisplayPart; import appeng.parts.reporting.PatternAccessTerminalPart; @@ -20,16 +13,6 @@ * yoinked from {@link PatternAccessTerminalPart} */ public class RequesterTerminalPart extends AbstractDisplayPart implements RequesterTerminalHost { - - @PartModels - private static final Identifier MODEL_OFF = Utils.getRL(String.format("part/%s_off", MERequester.TERMINAL_ID)); - @PartModels - private static final Identifier MODEL_ON = Utils.getRL(String.format("part/%s_on", MERequester.TERMINAL_ID)); - - private static final IPartModel MODELS_OFF = new PartModel(MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF); - private static final IPartModel MODELS_ON = new PartModel(MODEL_BASE, MODEL_ON, MODEL_STATUS_ON); - private static final IPartModel MODELS_HAS_CHANNEL = new PartModel(MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL); - public RequesterTerminalPart(IPartItem partItem) { super(partItem, true); } @@ -41,9 +24,4 @@ public boolean onUseWithoutItem(Player player, Vec3 pos) { } return true; } - - @Override - public IPartModel getStaticModels() { - return selectModel(MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL); - } } diff --git a/src/main/resources/assets/merequester/ae2/parts/requester_terminal.json b/src/main/resources/assets/merequester/ae2/parts/requester_terminal.json new file mode 100644 index 0000000..295cead --- /dev/null +++ b/src/main/resources/assets/merequester/ae2/parts/requester_terminal.json @@ -0,0 +1,23 @@ +{ + "model": { + "type": "ae2:composite", + "models": [ + { + "type": "ae2:model", + "model": "ae2:part/display_base" + }, + { + "type": "ae2:status_indicator", + "active": "merequester:part/requester_terminal_on", + "powered": "merequester:part/requester_terminal_on", + "unpowered": "merequester:part/requester_terminal_off" + }, + { + "type": "ae2:status_indicator", + "active": "ae2:part/display_status_has_channel", + "powered": "ae2:part/display_status_on", + "unpowered": "ae2:part/display_status_off" + } + ] + } +} \ No newline at end of file From 492ab21afd67f3f71998ede38c52286207dfebd3 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:10:50 +0200 Subject: [PATCH 23/52] TODO - RequesterBlockEntity.java - why does this need the full path? --- .../merequester/requester/RequesterBlockEntity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java index c799c3d..188f59c 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java @@ -63,7 +63,7 @@ public class RequesterBlockEntity extends AENetworkedBlockEntity implements Requ private TickRateModulation currentTickRate = TickRateModulation.IDLE; public RequesterBlockEntity(BlockPos pos, BlockState blockState) { - this(Registration.REQUESTER_ENTITY.get(), pos, blockState); + this(com.almostreliable.merequester.core.Registration.REQUESTER_ENTITY.get(), pos, blockState); // TODO 26.1 somehow this did not work otherwise } public RequesterBlockEntity(BlockEntityType blockEntityType, BlockPos pos, BlockState blockState) { @@ -106,7 +106,7 @@ public void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { public void importSettings(SettingsFrom mode, DataComponentMap input, @Nullable Player player) { super.importSettings(mode, input, player); if (mode == SettingsFrom.MEMORY_CARD) { - var exportedRequests = input.get(Registration.EXPORTED_REQUESTS.get()); + var exportedRequests = input.get(com.almostreliable.merequester.core.Registration.EXPORTED_REQUESTS.get()); // TODO 26.1 somehow this did not work otherwise if (exportedRequests != null) { requestManager.fromComponent(exportedRequests); } @@ -117,7 +117,7 @@ public void importSettings(SettingsFrom mode, DataComponentMap input, @Nullable public void exportSettings(SettingsFrom mode, DataComponentMap.Builder builder, @Nullable Player player) { super.exportSettings(mode, builder, player); if (mode == SettingsFrom.MEMORY_CARD) { - builder.set(Registration.EXPORTED_REQUESTS.get(), requestManager.toComponent()); + builder.set(com.almostreliable.merequester.core.Registration.EXPORTED_REQUESTS.get(), requestManager.toComponent()); // TODO 26.1 somehow this did not work otherwise } } From 4a90885f539f9a3c7a394339728ac8467b43ff37 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:47:46 +0200 Subject: [PATCH 24/52] TODO - GUI fixes --- src/main/resources/META-INF/accesstransformer.cfg | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/main/resources/META-INF/accesstransformer.cfg diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 0000000..0fa0a72 --- /dev/null +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,3 @@ +# GUI rendering +protected-f net.minecraft.client.gui.screens.inventory.AbstractContainerScreen imageWidth +protected-f net.minecraft.client.gui.screens.inventory.AbstractContainerScreen imageHeight \ No newline at end of file From f867175f3ab210ab4616dc020afee0e73de1e901 Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:48:14 +0200 Subject: [PATCH 25/52] TODO - GUI hack for bg texture --- .../client/abstraction/AbstractRequesterScreen.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index a5ba62a..95e8dcd 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -297,7 +297,10 @@ protected void resetScrollbar() { protected abstract RequesterReference getById(long requesterId, String name, long sortBy); private void blit(GuiGraphicsExtractor guiGraphics, int pX, int pY, Rect2i srcRect) { - guiGraphics.blit(texture, pX, pY, srcRect.getX(), srcRect.getY(), srcRect.getWidth(), srcRect.getHeight()); + // TODO 26.1 this is hardcoded and thus fragile + float width = 256; + float height = 256; + guiGraphics.blit(texture, pX, pY, pX+srcRect.getWidth(), pY+srcRect.getHeight(), (float)srcRect.getX()/width, (float)(srcRect.getX() + srcRect.getWidth())/width, (float)srcRect.getY()/height, (float)(srcRect.getY() + srcRect.getHeight())/height); } private RequestSlot createSlot(int index, Request request) { From 79905869b4856fcfb7fd56acaf75f41f53ae1adc Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:00:52 +0200 Subject: [PATCH 26/52] TODO - RequestManager.java - TEMP added missing abstract overrides --- .../merequester/requester/RequestManager.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/main/java/com/almostreliable/merequester/requester/RequestManager.java b/src/main/java/com/almostreliable/merequester/requester/RequestManager.java index ccb1d14..e523b16 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequestManager.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequestManager.java @@ -9,6 +9,10 @@ import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.common.util.INBTSerializable; +import net.neoforged.neoforge.transfer.ResourceHandler; +import net.neoforged.neoforge.transfer.item.ItemResource; +import net.neoforged.neoforge.transfer.transaction.TransactionContext; + import appeng.api.behaviors.GenericInternalInventory; import appeng.api.config.Actionable; import appeng.api.inventories.InternalInventory; @@ -181,6 +185,49 @@ public Component getDescription() { return host.getTerminalName(); } + @Override + public void updateSnapshots(TransactionContext transaction) {} // TODO 26.1 + + @Override + public ResourceHandler toResourceHandler() { // TODO 26.1 + return new ResourceHandler() { + @Override + public int size() { + return 0; + } + + @Override + public ItemResource getResource(int index) { + return null; + } + + @Override + public long getAmountAsLong(int index) { + return 0; + } + + @Override + public long getCapacityAsLong(int index, ItemResource resource) { + return 0; + } + + @Override + public boolean isValid(int index, ItemResource resource) { + return false; + } + + @Override + public int insert(int index, ItemResource resource, int amount, TransactionContext transaction) { + return 0; + } + + @Override + public int extract(int index, ItemResource resource, int amount, TransactionContext transaction) { + return 0; + } + }; + } + // @Override public void beginBatch() {} From 8cc2502c69d4a3f237e7a3d98a18a07223d245ff Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:48:21 +0200 Subject: [PATCH 27/52] remove unused imports from Registration.java --- .../java/com/almostreliable/merequester/core/Registration.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/core/Registration.java b/src/main/java/com/almostreliable/merequester/core/Registration.java index 9e71754..c69604a 100644 --- a/src/main/java/com/almostreliable/merequester/core/Registration.java +++ b/src/main/java/com/almostreliable/merequester/core/Registration.java @@ -21,8 +21,6 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; @@ -34,7 +32,6 @@ import net.neoforged.neoforge.registries.RegisterEvent; import appeng.api.AECapabilities; -import appeng.block.AEBaseBlock; import appeng.blockentity.AEBaseBlockEntity; import appeng.items.parts.PartItem; From baf47aa2d0ee187c913ea04b421630770ce17aee Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 12:39:54 +0200 Subject: [PATCH 28/52] TODO - RequesterBlock.java - TEMP disable appendHoverText --- .../almostreliable/merequester/requester/RequesterBlock.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java index 2107fc6..d910ccf 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java @@ -64,6 +64,7 @@ public IOrientationStrategy getOrientationStrategy() { return ORIENTATION_STRATEGY; } + /* TODO 26.1 @Override public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipFlag tooltipFlag) { if (Minecraft.getInstance().hasShiftDown()) { @@ -73,4 +74,5 @@ public void appendHoverText(ItemStack stack, Item.TooltipContext context, List Date: Sat, 22 Aug 2026 20:48:36 +0200 Subject: [PATCH 29/52] TODO - color handling seems to be no longer needed --- .../merequester/MERequesterClient.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/MERequesterClient.java b/src/main/java/com/almostreliable/merequester/MERequesterClient.java index c84f7ff..9294bdd 100644 --- a/src/main/java/com/almostreliable/merequester/MERequesterClient.java +++ b/src/main/java/com/almostreliable/merequester/MERequesterClient.java @@ -3,20 +3,14 @@ import com.almostreliable.merequester.client.RequesterScreen; import com.almostreliable.merequester.client.RequesterTerminalScreen; import com.almostreliable.merequester.compat.wtlib.WirelessTerminalCompat; -import com.almostreliable.merequester.core.Registration; import com.almostreliable.merequester.requester.RequesterMenu; import com.almostreliable.merequester.terminal.RequesterTerminalMenu; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.util.FastColor; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; -import appeng.api.util.AEColor; -import appeng.client.render.StaticItemColor; import appeng.client.InitScreens; @Mod(value = ModConstants.MOD_ID, dist = Dist.CLIENT) @@ -24,7 +18,6 @@ public final class MERequesterClient { public MERequesterClient(IEventBus modEventBus) { modEventBus.addListener(this::registerScreens); - modEventBus.addListener(this::registerColors); } @SuppressWarnings("RedundantTypeArguments") @@ -39,11 +32,4 @@ InitScreens. FastColor.ARGB32.opaque(itemColor.getColor(stack, tintIndex)); - } } From 531f28a2c0d690038e2138696155f07a8be0b49c Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Thu, 20 Aug 2026 11:41:29 +0200 Subject: [PATCH 30/52] TODO - port ae2wtlib support - maybe needs improvement --- .../compat/wtlib/ReqWirelessTerminalItem.java | 3 +++ .../compat/wtlib/ReqWirelessTerminalScreen.java | 5 +---- .../compat/wtlib/WirelessTerminalCompat.java | 17 +++++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalItem.java b/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalItem.java index 3636c2a..89c1e8a 100644 --- a/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalItem.java +++ b/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalItem.java @@ -7,6 +7,9 @@ import de.mari_023.ae2wtlib.api.terminal.ItemWT; class ReqWirelessTerminalItem extends ItemWT { + public ReqWirelessTerminalItem(Properties p) { + super(p); + } @Override public MenuType getMenuType(ItemMenuHostLocator itemMenuHostLocator, Player player) { diff --git a/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalScreen.java b/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalScreen.java index b158f41..5322df4 100644 --- a/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalScreen.java +++ b/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalScreen.java @@ -19,7 +19,7 @@ class ReqWirelessTerminalScreen extends RequesterTerminalScreen collectItems() { } private boolean isLoaded() { - return LoadingModList.get().getModFileById("ae2wtlib") != null; + return ModList.get().getModFileById("ae2wtlib") != null; } private WirelessTerminalCompat() {} @@ -84,11 +88,12 @@ private static void init(DeferredRegister> menuRegistry) { } public static void registerWirelessTerminal(Registry registry) { - WIRELESS_REQUESTER_TERMINAL = new ReqWirelessTerminalItem(); + WIRELESS_REQUESTER_TERMINAL = new ReqWirelessTerminalItem(new Item.Properties().setId(ResourceKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath( + ModConstants.MOD_ID, TERMINAL_ID)))); // TODO this is probably not the correct way with the manual .setId Registry.register(registry, Utils.getRL(TERMINAL_ID), WIRELESS_REQUESTER_TERMINAL); AddTerminalEvent.register(event -> event.builder( "requester", ReqWirelessTerminalMenuHost::new, ReqWirelessTerminalMenu.TYPE, WIRELESS_REQUESTER_TERMINAL, - Icon.PATTERN_ACCESS + Icon.PATTERN_ACCESS // TODO 26.1 this looks like the wrong value ) .addTerminal()); } @@ -97,8 +102,8 @@ private static void registerCapabilities(RegisterCapabilitiesEvent event) { assert WIRELESS_REQUESTER_TERMINAL != null; GridLinkables.register(WIRELESS_REQUESTER_TERMINAL, WirelessTerminalItem.LINKABLE_HANDLER); event.registerItem( - Capabilities.EnergyStorage.ITEM, - (stack, context) -> new PoweredItemCapabilities(stack, WIRELESS_REQUESTER_TERMINAL), + Capabilities.Energy.ITEM, + (stack, context) -> new PoweredItemCapabilities(context, WIRELESS_REQUESTER_TERMINAL, WIRELESS_REQUESTER_TERMINAL), WIRELESS_REQUESTER_TERMINAL ); } From b953fdbef11a316c43d15b04a67f3560120e085a Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:41:39 +0200 Subject: [PATCH 31/52] TODO - rewrite data serialization --- .../abstraction/AbstractRequesterScreen.java | 16 ++++--- .../merequester/requester/Request.java | 40 +++++++++------- .../merequester/requester/RequestManager.java | 18 ++++--- .../requester/RequesterBlockEntity.java | 40 +++++++--------- .../merequester/requester/StorageManager.java | 47 ++++++++++--------- .../abstraction/AbstractRequesterMenu.java | 37 ++++++++------- 6 files changed, 101 insertions(+), 97 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index 95e8dcd..0f628a5 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -14,10 +14,13 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.ValueInput; import net.neoforged.neoforge.client.network.ClientPacketDistributor; import appeng.api.behaviors.ContainerItemStrategies; @@ -110,22 +113,21 @@ public List getEmptyingTooltip(RequestSlot slot, ItemStack carried) { return Tooltips.getEmptyingTooltip(ButtonToolTips.SetAction, carried, emptyingAction); } - public void updateFromMenu(boolean clearData, long requesterId, CompoundTag data) { + public void updateFromMenu(boolean clearData, long requesterId, CompoundTag tag) { if (clearData) { clear(); refreshList(); return; } - var name = data.getString(AbstractRequesterMenu.UNIQUE_NAME_ID); - var sortBy = data.getLong(AbstractRequesterMenu.SORT_BY_ID); + ValueInput data = TagValueInput.create(ProblemReporter.DISCARDING, getPlayer().registryAccess(), tag); + var name = data.getStringOr(AbstractRequesterMenu.UNIQUE_NAME_ID, ""); + var sortBy = data.getLongOr(AbstractRequesterMenu.SORT_BY_ID, 0); var requests = getById(requesterId, name, sortBy).getRequestManager(); for (var i = 0; i < requests.size(); i++) { - var requestIndex = String.valueOf(i); - if (data.contains(requestIndex)) { - requests.get(i).deserializeNBT(menu.getPlayer().registryAccess(), data.getCompound(requestIndex)); - } + var child = data.child(String.valueOf(i)); + if (child.isPresent()) requests.get(i).deserialize(child.orElseThrow()); } if (refreshList) refreshList(); diff --git a/src/main/java/com/almostreliable/merequester/requester/Request.java b/src/main/java/com/almostreliable/merequester/requester/Request.java index 634214c..f66ac98 100644 --- a/src/main/java/com/almostreliable/merequester/requester/Request.java +++ b/src/main/java/com/almostreliable/merequester/requester/Request.java @@ -3,13 +3,14 @@ import com.almostreliable.merequester.requester.abstraction.RequestHost; import com.almostreliable.merequester.requester.status.RequestStatus; -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.util.Mth; -import net.neoforged.neoforge.common.util.INBTSerializable; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; + +import net.neoforged.neoforge.common.util.ValueIOSerializable; import appeng.api.stacks.AEKey; import appeng.api.stacks.GenericStack; @@ -21,7 +22,7 @@ import java.util.Objects; import java.util.Optional; -public final class Request implements INBTSerializable { +public final class Request implements ValueIOSerializable { // serialization IDs private static final String STATE_ID = "state"; @@ -50,14 +51,13 @@ public final class Request implements INBTSerializable { } @Override - public CompoundTag serializeNBT(HolderLookup.Provider registries) { - var tag = new CompoundTag(); - tag.putBoolean(STATE_ID, state); - if (key != null) tag.put(KEY_ID, key.toTagGeneric(registries)); - tag.putLong(AMOUNT_ID, amount); - tag.putLong(BATCH_ID, batch); - tag.putInt(STATUS_ID, clientStatus.ordinal()); - return tag; + public void serialize(ValueOutput data) { + data.putBoolean(STATE_ID, state); + if (key != null) + key.toTagGeneric(data.child(KEY_ID)); + data.putLong(AMOUNT_ID, amount); + data.putLong(BATCH_ID, batch); + data.putInt(STATUS_ID, clientStatus.ordinal()); } public Component toComponent() { @@ -71,12 +71,16 @@ public Component toComponent() { } @Override - public void deserializeNBT(HolderLookup.Provider registries, CompoundTag tag) { - state = tag.getBoolean(STATE_ID); - key = tag.contains(KEY_ID) ? AEKey.fromTagGeneric(registries, tag.getCompound(KEY_ID)) : null; - amount = tag.getLong(AMOUNT_ID); - batch = tag.getLong(BATCH_ID); - clientStatus = RequestStatus.values()[tag.getInt(STATUS_ID)]; + public void deserialize(ValueInput data) { + state = data.getBooleanOr(STATE_ID, false); + var childKey = data.child(KEY_ID); + if (childKey.isPresent()) + key = AEKey.fromTagGeneric(childKey.orElseThrow()); + else + key = null; + amount = data.getLongOr(AMOUNT_ID, 0); + batch = data.getLongOr(BATCH_ID, 0); + clientStatus = RequestStatus.values()[data.getIntOr(STATUS_ID, 0)]; } public void fromComponent(Component request) { diff --git a/src/main/java/com/almostreliable/merequester/requester/RequestManager.java b/src/main/java/com/almostreliable/merequester/requester/RequestManager.java index e523b16..86c9d0e 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequestManager.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequestManager.java @@ -3,12 +3,12 @@ import com.almostreliable.merequester.core.Config; import com.almostreliable.merequester.requester.abstraction.RequestHost; -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; -import net.neoforged.neoforge.common.util.INBTSerializable; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; +import net.neoforged.neoforge.common.util.ValueIOSerializable; import net.neoforged.neoforge.transfer.ResourceHandler; import net.neoforged.neoforge.transfer.item.ItemResource; import net.neoforged.neoforge.transfer.transaction.TransactionContext; @@ -35,7 +35,7 @@ * Automatically provides a menu wrapper by implementing {@link InternalInventory}. */ @SuppressWarnings("UnstableApiUsage") -public class RequestManager implements MEStorage, GenericInternalInventory, InternalInventory, INBTSerializable { +public class RequestManager implements MEStorage, GenericInternalInventory, InternalInventory, ValueIOSerializable { // if null, the inventory is client-side and doesn't need saving @Nullable @@ -139,18 +139,16 @@ public void onChange() { } @Override - public CompoundTag serializeNBT(HolderLookup.Provider registries) { - var tag = new CompoundTag(); + public void serialize(ValueOutput data) { for (var i = 0; i < size(); i++) { - tag.put(String.valueOf(i), get(i).serializeNBT(registries)); + get(i).serialize(data.child(String.valueOf(i))); } - return tag; } @Override - public void deserializeNBT(HolderLookup.Provider registries, CompoundTag tag) { + public void deserialize(ValueInput data) { for (var i = 0; i < size(); i++) { - get(i).deserializeNBT(registries, tag.getCompound(String.valueOf(i))); + get(i).deserialize(data.childOrEmpty(String.valueOf(i))); } } diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java index 188f59c..c6f5a5b 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java @@ -20,6 +20,8 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; import appeng.api.config.Actionable; import appeng.api.networking.GridFlags; @@ -85,21 +87,19 @@ public RequesterBlockEntity(BlockEntityType blockEntityType, BlockPos pos, Bl } @Override - public void loadTag(CompoundTag tag, HolderLookup.Provider registries) { - super.loadTag(tag, registries); - if (tag.contains(REQUESTS_ID)) requestManager.deserializeNBT(registries, tag.getCompound(REQUESTS_ID)); - if (tag.contains(REQUEST_STATUS_ID)) deserializeStatus(tag.getCompound(REQUEST_STATUS_ID)); - if (tag.contains(STORAGE_MANAGER_ID)) { - storageManager.deserializeNBT(registries, tag.getCompound(STORAGE_MANAGER_ID)); - } + public void loadTag(ValueInput data) { + super.loadTag(data); + requestManager.deserialize(data.childOrEmpty(REQUESTS_ID)); + deserializeStatus(data.childOrEmpty(REQUEST_STATUS_ID)); + storageManager.deserialize(data.childOrEmpty(STORAGE_MANAGER_ID)); } @Override - public void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.saveAdditional(tag, registries); - tag.put(REQUESTS_ID, requestManager.serializeNBT(registries)); - tag.put(REQUEST_STATUS_ID, serializeStatus()); - tag.put(STORAGE_MANAGER_ID, storageManager.serializeNBT(registries)); + public void saveAdditional(ValueOutput data) { + super.saveAdditional(data); + requestManager.serialize(data.child(REQUESTS_ID)); + serializeStatus(data.child(REQUEST_STATUS_ID)); + storageManager.serialize(data.child(STORAGE_MANAGER_ID)); } @Override @@ -172,27 +172,23 @@ public void addAdditionalDrops(Level level, BlockPos pos, List drops) storageManager.addDrops(drops); } - private void deserializeStatus(CompoundTag tag) { + private void deserializeStatus(ValueInput data) { for (var i = 0; i < requestStatus.length; i++) { - if (tag.contains(String.valueOf(i))) { - var stateTag = tag.getCompound(String.valueOf(i)); - var link = StorageHelper.loadCraftingLink(stateTag, this); + var child = data.child(String.valueOf(i)); + if (child.isPresent()) { + var link = StorageHelper.loadCraftingLink(child.orElseThrow(), this); requestStatus[i] = new LinkState(link); } } } - private CompoundTag serializeStatus() { - var tag = new CompoundTag(); + private void serializeStatus(ValueOutput data) { for (var i = 0; i < requestStatus.length; i++) { var state = requestStatus[i]; if (state instanceof LinkState cls) { - var stateTag = new CompoundTag(); - cls.link().writeToNBT(stateTag); - tag.put(String.valueOf(i), stateTag); + cls.link().writeToNBT(data.child(String.valueOf(i))); } } - return tag; } private boolean handleRequests() { diff --git a/src/main/java/com/almostreliable/merequester/requester/StorageManager.java b/src/main/java/com/almostreliable/merequester/requester/StorageManager.java index 58b4414..d5c260a 100644 --- a/src/main/java/com/almostreliable/merequester/requester/StorageManager.java +++ b/src/main/java/com/almostreliable/merequester/requester/StorageManager.java @@ -2,10 +2,11 @@ import com.almostreliable.merequester.core.Config; -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; -import net.neoforged.neoforge.common.util.INBTSerializable; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; + +import net.neoforged.neoforge.common.util.ValueIOSerializable; import appeng.api.config.FuzzyMode; import appeng.api.networking.IStackWatcher; @@ -16,7 +17,7 @@ import java.util.List; -public class StorageManager implements IStorageWatcherNode, INBTSerializable { +public class StorageManager implements IStorageWatcherNode, ValueIOSerializable { private final RequesterBlockEntity host; private final Storage[] storages; @@ -66,18 +67,16 @@ public long computeAmountToCraft(int slot) { } @Override - public CompoundTag serializeNBT(HolderLookup.Provider registries) { - var tag = new CompoundTag(); + public void serialize(ValueOutput data) { for (var i = 0; i < storages.length; i++) { - tag.put(String.valueOf(i), get(i).serializeNBT(registries)); + get(i).serialize(data.child(String.valueOf(i))); } - return tag; } @Override - public void deserializeNBT(HolderLookup.Provider registries, CompoundTag tag) { + public void deserialize(ValueInput data) { for (var i = 0; i < storages.length; i++) { - get(i).deserializeNBT(registries, tag.getCompound(String.valueOf(i))); + get(i).deserialize(data.childOrEmpty(String.valueOf(i))); } } @@ -115,7 +114,7 @@ private void computeKnownAmount(int slot) { get(slot).knownAmount = host.getMainNodeGrid().getStorageService().getInventory().getAvailableStacks().get(key); } - public static class Storage implements INBTSerializable { + public static class Storage implements ValueIOSerializable { // serialization IDs private static final String KEY_ID = "key"; @@ -131,21 +130,23 @@ public static class Storage implements INBTSerializable { private long knownAmount = -1; // the known amount stored in the system @Override - public CompoundTag serializeNBT(HolderLookup.Provider registries) { - var tag = new CompoundTag(); - if (key != null) tag.put(KEY_ID, key.toTagGeneric(registries)); - tag.putLong(BUFFER_AMOUNT_ID, bufferAmount); - tag.putLong(PENDING_AMOUNT_ID, pendingAmount); - tag.putLong(KNOWN_AMOUNT_ID, knownAmount); - return tag; + public void serialize(ValueOutput data) { + if (key != null) key.toTagGeneric(data.child(KEY_ID)); + data.putLong(BUFFER_AMOUNT_ID, bufferAmount); + data.putLong(PENDING_AMOUNT_ID, pendingAmount); + data.putLong(KNOWN_AMOUNT_ID, knownAmount); } @Override - public void deserializeNBT(HolderLookup.Provider registries, CompoundTag tag) { - key = tag.contains(KEY_ID) ? AEKey.fromTagGeneric(registries, tag.getCompound(KEY_ID)) : null; - bufferAmount = tag.getLong(BUFFER_AMOUNT_ID); - pendingAmount = tag.getLong(PENDING_AMOUNT_ID); - knownAmount = tag.getLong(KNOWN_AMOUNT_ID); + public void deserialize(ValueInput data) { + var childKey = data.child(KEY_ID); + if (childKey.isPresent()) + key = AEKey.fromTagGeneric(childKey.orElseThrow()); + else + key = null; + bufferAmount = data.getLongOr(BUFFER_AMOUNT_ID, 0); + pendingAmount = data.getLongOr(PENDING_AMOUNT_ID, 0); + knownAmount = data.getLongOr(KNOWN_AMOUNT_ID, 0); } /** diff --git a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java index 95f36ae..4d765a2 100644 --- a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java +++ b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java @@ -4,11 +4,13 @@ import com.almostreliable.merequester.network.RequesterSyncPacket; import com.almostreliable.merequester.requester.RequesterBlockEntity; -import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.TagValueOutput; import net.neoforged.neoforge.network.PacketDistributor; import appeng.api.behaviors.ContainerItemStrategies; @@ -112,17 +114,18 @@ protected void syncRequestTrackerFull(RequestTracker requestTracker) { var client = requestTracker.getClient(); // get the requests from the server - var tag = server.serializeNBT(getPlayer().registryAccess()); + TagValueOutput data = TagValueOutput.createWithoutContext(ProblemReporter.DISCARDING); + server.serialize(data); // store the information in the client tracker to // check for differences on partial updates later // tag serialization is used to avoid references to the original data - client.deserializeNBT(getPlayer().registryAccess(), tag); + client.deserialize(TagValueInput.create(ProblemReporter.DISCARDING, getPlayer().registryAccess(), data.buildResult())); // send relevant data to the client - tag.putString(UNIQUE_NAME_ID, requestTracker.getName()); - tag.putLong(SORT_BY_ID, requestTracker.getSortBy()); + data.putString(UNIQUE_NAME_ID, requestTracker.getName()); + data.putLong(SORT_BY_ID, requestTracker.getSortBy()); if (getPlayer() instanceof ServerPlayer serverPlayer) { - PacketDistributor.sendToPlayer(serverPlayer, RequesterSyncPacket.createInventory(requestTracker.getId(), tag)); + PacketDistributor.sendToPlayer(serverPlayer, RequesterSyncPacket.createInventory(requestTracker.getId(), data.buildResult())); } } @@ -130,7 +133,7 @@ protected void syncRequestTrackerPartial(RequestTracker requestTracker) { var server = requestTracker.getServer(); var client = requestTracker.getClient(); - CompoundTag tag = null; + TagValueOutput data = null; // iterate through the server data and check for differences for (var i = 0; i < server.size(); i++) { var serverRequest = server.get(i); @@ -138,22 +141,22 @@ protected void syncRequestTrackerPartial(RequestTracker requestTracker) { if (serverRequest.isDifferent(clientRequest)) { // write initial data as soon as something is different - if (tag == null) { - tag = new CompoundTag(); - tag.putString(UNIQUE_NAME_ID, requestTracker.getName()); - tag.putLong(SORT_BY_ID, requestTracker.getSortBy()); + if (data == null) { + data = TagValueOutput.createWithoutContext(ProblemReporter.DISCARDING); + data.putString(UNIQUE_NAME_ID, requestTracker.getName()); + data.putLong(SORT_BY_ID, requestTracker.getSortBy()); } - var serverData = serverRequest.serializeNBT(getPlayer().registryAccess()); - tag.put(String.valueOf(i), serverData); - // update the client information for future difference checks - clientRequest.deserializeNBT(getPlayer().registryAccess(), serverData); + serverRequest.serialize(data.child(String.valueOf(i))); + var tmp = TagValueOutput.createWithoutContext(ProblemReporter.DISCARDING); + serverRequest.serialize(tmp); + clientRequest.deserialize(TagValueInput.create(ProblemReporter.DISCARDING, getPlayer().registryAccess(), tmp.buildResult())); } } // only send an update if something changed - if (tag != null && getPlayer() instanceof ServerPlayer serverPlayer) { - PacketDistributor.sendToPlayer(serverPlayer, RequesterSyncPacket.createInventory(requestTracker.getId(), tag)); + if (data != null && getPlayer() instanceof ServerPlayer serverPlayer) { + PacketDistributor.sendToPlayer(serverPlayer, RequesterSyncPacket.createInventory(requestTracker.getId(), data.buildResult())); } } From d4797159c506bf6ad1c61889303a4a19a194459a Mon Sep 17 00:00:00 2001 From: Mithi83 <28407460+Mithi83@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:57:22 +0200 Subject: [PATCH 32/52] fix number field colors --- .../merequester/client/widgets/NumberField.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java index 915dacc..7c15229 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java @@ -41,8 +41,9 @@ public class NumberField extends ConfirmableTextField { private static final int WIDTH = 52; private static final int HEIGHT = 12; - private static final int TEXT_COLOR = 0xFF_FFFF; - private static final int ERROR_COLOR = 0xFF_0000; + private static final int TEXT_COLOR = 0xFFFF_FFFF; + private static final int ERROR_COLOR = 0xFFFF_0000; + private static final int B_COLOR = 0xFF54_5454; private static final int MIN_VALUE = 0; @@ -78,7 +79,7 @@ public class NumberField extends ConfirmableTextField { public void extractWidgetRenderState(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partial) { super.extractWidgetRenderState(guiGraphics, mouseX, mouseY, partial); if (!isFluid) return; - guiGraphics.text(Minecraft.getInstance().font, "B", getX() + WIDTH - PADDING, getY(), 0x54_5454, false); + guiGraphics.text(Minecraft.getInstance().font, "B", getX() + WIDTH - PADDING, getY(), B_COLOR, false); } private void validate() { From d42515d3de28b0ddfb47c1d933a86f9d57f86b31 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:26:36 +0200 Subject: [PATCH 33/52] update Gradle --- gradle/wrapper/gradle-wrapper.jar | Bin 43583 -> 48966 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 11 ++++------- gradlew.bat | 3 +-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b9530d66f5e68d973ea569d8e19de379189..d997cfc60f4cff0e7451d19d49a82fa986695d07 100644 GIT binary patch delta 40682 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Ðt5p(LLtXn?pxm3OZHd|13r);5)1uCW40m{;j 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 A;{X5v delta 35496 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 626bad2..4d8a80c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase = GRADLE_USER_HOME distributionPath = wrapper/dists -distributionUrl = https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +distributionUrl = https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip networkTimeout = 10000 validateDistributionUrl = true zipStoreBase = GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f3b75f3..739907d 100644 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -205,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9d21a21..c4bdd3a 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell From 9a98b50b1503890a17fa15ec1ebb3e06576a4a98 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:26:53 +0200 Subject: [PATCH 34/52] remove unused parchment mappings --- gradle.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8205358..13caf10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,8 +18,6 @@ aeVersion = 26.1.10-beta wtlibVersion = 26.1.1-beta # settings -#neoForge.parchment.minecraftVersion = 1.21.1 -#neoForge.parchment.mappingsVersion = 2024.11.17 almostgradle.buildconfig = ModConstants almostgradle.launchArgs.autoWorldJoin = true almostgradle.recipeViewers.emi.runConfig = false From ac5944cfed9925e52fce8e053a5370fe548e6040 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:27:00 +0200 Subject: [PATCH 35/52] enable JEI run config --- gradle.properties | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 13caf10..120ebae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,9 +20,8 @@ wtlibVersion = 26.1.1-beta # settings almostgradle.buildconfig = ModConstants almostgradle.launchArgs.autoWorldJoin = true -almostgradle.recipeViewers.emi.runConfig = false -#almostgradle.recipeViewers.emi.version = 1.1.21 -#almostgradle.recipeViewers.emi.minecraftVersion = 1.21.1 +almostgradle.recipeViewers.jei.runConfig = true +almostgradle.recipeViewers.jei.version = 29.21.0.66 # gradle org.gradle.vfs.watch = true From 5f5cb75227662478089d6ad9ba7b08afdb08e325 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:27:19 +0200 Subject: [PATCH 36/52] update MDG and enable doc download --- build.gradle.kts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f418c82..0d81ab8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,18 +1,22 @@ plugins { - id("net.neoforged.moddev") version "2.0.141" + id("net.neoforged.moddev") version "2.0.143" id("com.almostreliable.almostgradle") version "2.3.2" } almostgradle.setup { withSourcesJar = false + downloadSources = true + downloadJavadoc = true } neoForge { runs { configureEach { - systemProperties = mapOf( - "guideme.ae2.guide.sources" to file("guidebook").absolutePath, - "guideme.ae2.guide.sourcesNamespace" to almostgradle.modId, + systemProperties.putAll( + mapOf( + "guideme.ae2.guide.sources" to file("guidebook").absolutePath, + "guideme.ae2.guide.sourcesNamespace" to almostgradle.modId, + ) ) } @@ -26,7 +30,6 @@ neoForge { repositories { mavenCentral() maven("https://modmaven.dev") - mavenLocal() } dependencies { From 073dc21cbbaaf1f915d398b0f66fc8bb34c7b7da Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:28:47 +0200 Subject: [PATCH 37/52] mark slot field accessors as mutable --- .../almostreliable/merequester/mixin/accessors/SlotMixin.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/almostreliable/merequester/mixin/accessors/SlotMixin.java b/src/main/java/com/almostreliable/merequester/mixin/accessors/SlotMixin.java index 9d26bfd..a719f89 100644 --- a/src/main/java/com/almostreliable/merequester/mixin/accessors/SlotMixin.java +++ b/src/main/java/com/almostreliable/merequester/mixin/accessors/SlotMixin.java @@ -2,15 +2,19 @@ import net.minecraft.world.inventory.Slot; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(Slot.class) public interface SlotMixin { @Accessor("x") + @Mutable void merequester$setX(int x); @Accessor("y") + @Mutable void merequester$setY(int y); } From d9f47f02144ee67536f16c0f5a0dfe171fa76cb0 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:35:11 +0200 Subject: [PATCH 38/52] provide registry context to requester menu syncing --- .../requester/abstraction/AbstractRequesterMenu.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java index 4d765a2..d312753 100644 --- a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java +++ b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java @@ -114,7 +114,7 @@ protected void syncRequestTrackerFull(RequestTracker requestTracker) { var client = requestTracker.getClient(); // get the requests from the server - TagValueOutput data = TagValueOutput.createWithoutContext(ProblemReporter.DISCARDING); + TagValueOutput data = TagValueOutput.createWithContext(ProblemReporter.DISCARDING, getPlayer().registryAccess()); server.serialize(data); // store the information in the client tracker to // check for differences on partial updates later @@ -142,13 +142,13 @@ protected void syncRequestTrackerPartial(RequestTracker requestTracker) { if (serverRequest.isDifferent(clientRequest)) { // write initial data as soon as something is different if (data == null) { - data = TagValueOutput.createWithoutContext(ProblemReporter.DISCARDING); + data = TagValueOutput.createWithContext(ProblemReporter.DISCARDING, getPlayer().registryAccess()); data.putString(UNIQUE_NAME_ID, requestTracker.getName()); data.putLong(SORT_BY_ID, requestTracker.getSortBy()); } serverRequest.serialize(data.child(String.valueOf(i))); - var tmp = TagValueOutput.createWithoutContext(ProblemReporter.DISCARDING); + var tmp = TagValueOutput.createWithContext(ProblemReporter.DISCARDING, getPlayer().registryAccess()); serverRequest.serialize(tmp); clientRequest.deserialize(TagValueInput.create(ProblemReporter.DISCARDING, getPlayer().registryAccess(), tmp.buildResult())); } From 03e7e88bbdf91ed0c4b0589e517d6abde9e878fc Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:37:19 +0200 Subject: [PATCH 39/52] update java mixin compatibility level to 25 --- src/main/resources/merequester.mixins.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/merequester.mixins.json b/src/main/resources/merequester.mixins.json index e3773d9..6c8e84f 100644 --- a/src/main/resources/merequester.mixins.json +++ b/src/main/resources/merequester.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8.5", "package": "com.almostreliable.merequester.mixin", - "compatibilityLevel": "JAVA_21", + "compatibilityLevel": "JAVA_25", "client": [ "accessors.EditBoxMixin", "accessors.SlotMixin", From db0a451e35f64ebeb20153e34a631588f19e2841 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:39:03 +0200 Subject: [PATCH 40/52] migrate to jspecify nullable annotations --- .../java/com/almostreliable/merequester/client/RequestSlot.java | 2 +- .../com/almostreliable/merequester/client/RequesterScreen.java | 2 +- .../merequester/client/RequesterTerminalScreen.java | 2 +- .../merequester/client/abstraction/AbstractRequesterScreen.java | 2 +- .../merequester/client/abstraction/RequestDisplay.java | 2 +- .../almostreliable/merequester/client/widgets/NumberField.java | 2 +- .../merequester/client/widgets/RequestWidget.java | 2 +- .../merequester/compat/wtlib/WirelessTerminalCompat.java | 2 +- .../java/com/almostreliable/merequester/requester/Request.java | 2 +- .../almostreliable/merequester/requester/RequestManager.java | 2 +- .../merequester/requester/RequesterBlockEntity.java | 2 +- .../com/almostreliable/merequester/requester/RequesterMenu.java | 2 +- .../almostreliable/merequester/requester/StorageManager.java | 2 +- .../requester/abstraction/AbstractRequesterMenu.java | 2 +- .../merequester/requester/status/BlockingState.java | 2 +- .../merequester/terminal/RequesterTerminalMenu.java | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/RequestSlot.java b/src/main/java/com/almostreliable/merequester/client/RequestSlot.java index 0f900f7..4ae2c54 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequestSlot.java +++ b/src/main/java/com/almostreliable/merequester/client/RequestSlot.java @@ -13,7 +13,7 @@ import appeng.menu.slot.FakeSlot; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.Collections; import java.util.List; diff --git a/src/main/java/com/almostreliable/merequester/client/RequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/RequesterScreen.java index ba9a260..4a8aee1 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/RequesterScreen.java @@ -15,7 +15,7 @@ import appeng.client.gui.style.ScreenStyle; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.Collections; import java.util.Set; diff --git a/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java b/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java index 870b507..9d58908 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/RequesterTerminalScreen.java @@ -25,7 +25,7 @@ import appeng.core.localization.GuiText; import com.google.common.collect.HashMultimap; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index 0f628a5..bf90c66 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -38,7 +38,7 @@ import com.mojang.blaze3d.platform.InputConstants; import org.jetbrains.annotations.MustBeInvokedByOverriders; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/RequestDisplay.java b/src/main/java/com/almostreliable/merequester/client/abstraction/RequestDisplay.java index de87cf8..a12464f 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/RequestDisplay.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/RequestDisplay.java @@ -7,7 +7,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.List; import java.util.Map; diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java index 7c15229..342c593 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/NumberField.java @@ -18,7 +18,7 @@ import appeng.core.localization.GuiText; import com.mojang.blaze3d.platform.InputConstants; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.math.BigDecimal; import java.math.MathContext; diff --git a/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java b/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java index ad1f3c7..789897b 100644 --- a/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java +++ b/src/main/java/com/almostreliable/merequester/client/widgets/RequestWidget.java @@ -10,7 +10,7 @@ import appeng.client.gui.style.ScreenStyle; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java b/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java index 09343f2..13272a0 100644 --- a/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java +++ b/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java @@ -24,7 +24,7 @@ import de.mari_023.ae2wtlib.api.gui.Icon; import de.mari_023.ae2wtlib.api.registration.AddTerminalEvent; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.List; diff --git a/src/main/java/com/almostreliable/merequester/requester/Request.java b/src/main/java/com/almostreliable/merequester/requester/Request.java index f66ac98..19ee659 100644 --- a/src/main/java/com/almostreliable/merequester/requester/Request.java +++ b/src/main/java/com/almostreliable/merequester/requester/Request.java @@ -17,7 +17,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.Objects; import java.util.Optional; diff --git a/src/main/java/com/almostreliable/merequester/requester/RequestManager.java b/src/main/java/com/almostreliable/merequester/requester/RequestManager.java index 86c9d0e..ce66e61 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequestManager.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequestManager.java @@ -24,7 +24,7 @@ import appeng.helpers.externalstorage.GenericStackInv; import com.google.common.primitives.Ints; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java index c6f5a5b..72b85b4 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java @@ -42,7 +42,7 @@ import appeng.util.SettingsFrom; import com.google.common.collect.ImmutableSet; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.Arrays; import java.util.EnumSet; diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterMenu.java b/src/main/java/com/almostreliable/merequester/requester/RequesterMenu.java index cd6e44e..656ffbf 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterMenu.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterMenu.java @@ -15,7 +15,7 @@ import appeng.api.networking.IGrid; import appeng.menu.implementations.MenuTypeBuilder; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; public final class RequesterMenu extends AbstractRequesterMenu { diff --git a/src/main/java/com/almostreliable/merequester/requester/StorageManager.java b/src/main/java/com/almostreliable/merequester/requester/StorageManager.java index d5c260a..e0ff347 100644 --- a/src/main/java/com/almostreliable/merequester/requester/StorageManager.java +++ b/src/main/java/com/almostreliable/merequester/requester/StorageManager.java @@ -13,7 +13,7 @@ import appeng.api.networking.storage.IStorageWatcherNode; import appeng.api.stacks.AEKey; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.List; diff --git a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java index d312753..db1b10c 100644 --- a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java +++ b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java @@ -19,7 +19,7 @@ import appeng.helpers.InventoryAction; import appeng.menu.AEBaseMenu; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; public abstract class AbstractRequesterMenu extends AEBaseMenu { diff --git a/src/main/java/com/almostreliable/merequester/requester/status/BlockingState.java b/src/main/java/com/almostreliable/merequester/requester/status/BlockingState.java index 2a9d05d..83bb9fd 100644 --- a/src/main/java/com/almostreliable/merequester/requester/status/BlockingState.java +++ b/src/main/java/com/almostreliable/merequester/requester/status/BlockingState.java @@ -4,7 +4,7 @@ import appeng.api.networking.ticking.TickRateModulation; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; public abstract class BlockingState implements StatusState { diff --git a/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalMenu.java b/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalMenu.java index 57a10a3..0e3cda9 100644 --- a/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalMenu.java +++ b/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalMenu.java @@ -20,7 +20,7 @@ import appeng.menu.implementations.PatternAccessTermMenu; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.Comparator; import java.util.IdentityHashMap; From 8ca33e2cdbbe5bb62f4af9dad80d18a1bbee9545 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:49:06 +0200 Subject: [PATCH 41/52] move requester tooltip to custom block item --- .../merequester/core/Registration.java | 8 ++-- .../merequester/requester/RequesterBlock.java | 23 ---------- .../requester/RequesterBlockItem.java | 42 +++++++++++++++++++ 3 files changed, 46 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/almostreliable/merequester/requester/RequesterBlockItem.java diff --git a/src/main/java/com/almostreliable/merequester/core/Registration.java b/src/main/java/com/almostreliable/merequester/core/Registration.java index c69604a..3c95c6c 100644 --- a/src/main/java/com/almostreliable/merequester/core/Registration.java +++ b/src/main/java/com/almostreliable/merequester/core/Registration.java @@ -6,6 +6,7 @@ import com.almostreliable.merequester.requester.Request; import com.almostreliable.merequester.requester.RequesterBlock; import com.almostreliable.merequester.requester.RequesterBlockEntity; +import com.almostreliable.merequester.requester.RequesterBlockItem; import com.almostreliable.merequester.requester.RequesterMenu; import com.almostreliable.merequester.terminal.RequesterTerminalMenu; import com.almostreliable.merequester.terminal.RequesterTerminalPart; @@ -16,7 +17,6 @@ import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.resources.ResourceKey; import net.minecraft.world.inventory.MenuType; -import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.level.ItemLike; @@ -61,10 +61,10 @@ public final class Registration { REQUESTER_ID, RequesterBlock::new ); - public static final DeferredItem REQUESTER_ITEM = ITEMS.registerSimpleBlockItem( + public static final DeferredItem REQUESTER_ITEM = ITEMS.registerItem( REQUESTER_ID, - REQUESTER_BLOCK, - () -> new Item.Properties() + properties -> new RequesterBlockItem(REQUESTER_BLOCK.get(), properties), + Item.Properties::useBlockDescriptionPrefix ); public static final DeferredHolder, BlockEntityType> REQUESTER_ENTITY = BLOCK_ENTITIES.register( diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java index d910ccf..f4d38f1 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlock.java @@ -1,17 +1,8 @@ package com.almostreliable.merequester.requester; -import com.almostreliable.merequester.MERequester; -import com.almostreliable.merequester.Utils; - -import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; @@ -25,8 +16,6 @@ import appeng.menu.locator.MenuLocators; import appeng.util.InteractionUtil; -import java.util.List; - public class RequesterBlock extends AEBaseEntityBlock { private static final IOrientationStrategy ORIENTATION_STRATEGY = new FacingWithVerticalSpin(); @@ -63,16 +52,4 @@ protected void createBlockStateDefinition(StateDefinition.Builder tooltip, TooltipFlag tooltipFlag) { - if (Minecraft.getInstance().hasShiftDown()) { - tooltip.add(Component.literal(" ")); - tooltip.add(Utils.translate("tooltip", String.format("%s_desc", MERequester.REQUESTER_ID)).withStyle(ChatFormatting.AQUA)); - } else { - Utils.addShiftInfoTooltip(tooltip); - } - } - */ } diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockItem.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockItem.java new file mode 100644 index 0000000..6d69e16 --- /dev/null +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockItem.java @@ -0,0 +1,42 @@ +package com.almostreliable.merequester.requester; + +import com.almostreliable.merequester.MERequester; +import com.almostreliable.merequester.Utils; + +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.level.block.Block; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public class RequesterBlockItem extends BlockItem { + + public RequesterBlockItem(Block block, Properties properties) { + super(block, properties); + } + + @SuppressWarnings("deprecation") + @Override + public void appendHoverText( + ItemStack stack, Item.TooltipContext context, TooltipDisplay display, Consumer builder, TooltipFlag tooltipFlag + ) { + super.appendHoverText(stack, context, display, builder, tooltipFlag); + + if (Minecraft.getInstance().hasShiftDown()) { + builder.accept(Component.literal(" ")); + builder.accept(Utils.translate("tooltip", String.format("%s_desc", MERequester.REQUESTER_ID)).withStyle(ChatFormatting.AQUA)); + } else { + List tooltip = new ArrayList<>(); + Utils.addShiftInfoTooltip(tooltip); + tooltip.forEach(builder); + } + } +} From e6df36e5af2bd5c10c738c27e707e170b043e4de Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:50:53 +0200 Subject: [PATCH 42/52] fix registration name clash and clean up file --- .../merequester/MERequester.java | 4 +-- ...Registration.java => ModRegistration.java} | 28 ++++++++----------- .../requester/RequesterBlockEntity.java | 10 +++---- 3 files changed, 17 insertions(+), 25 deletions(-) rename src/main/java/com/almostreliable/merequester/core/{Registration.java => ModRegistration.java} (90%) diff --git a/src/main/java/com/almostreliable/merequester/MERequester.java b/src/main/java/com/almostreliable/merequester/MERequester.java index d1aa378..e8a81db 100644 --- a/src/main/java/com/almostreliable/merequester/MERequester.java +++ b/src/main/java/com/almostreliable/merequester/MERequester.java @@ -1,7 +1,7 @@ package com.almostreliable.merequester; import com.almostreliable.merequester.core.Config; -import com.almostreliable.merequester.core.Registration; +import com.almostreliable.merequester.core.ModRegistration; import com.almostreliable.merequester.network.PacketHandler; import net.neoforged.bus.api.IEventBus; @@ -19,7 +19,7 @@ public final class MERequester { public static final String TERMINAL_ID = "requester_terminal"; public MERequester(IEventBus modEventBus, ModContainer modContainer) { - Registration.init(modEventBus); + ModRegistration.init(modEventBus); PacketHandler.init(modEventBus); Config.init(modContainer); } diff --git a/src/main/java/com/almostreliable/merequester/core/Registration.java b/src/main/java/com/almostreliable/merequester/core/ModRegistration.java similarity index 90% rename from src/main/java/com/almostreliable/merequester/core/Registration.java rename to src/main/java/com/almostreliable/merequester/core/ModRegistration.java index 3c95c6c..5e9e1f2 100644 --- a/src/main/java/com/almostreliable/merequester/core/Registration.java +++ b/src/main/java/com/almostreliable/merequester/core/ModRegistration.java @@ -40,7 +40,7 @@ import static com.almostreliable.merequester.MERequester.REQUESTER_ID; import static com.almostreliable.merequester.MERequester.TERMINAL_ID; -public final class Registration { +public final class ModRegistration { private static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(ModConstants.MOD_ID); private static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(ModConstants.MOD_ID); @@ -69,11 +69,7 @@ public final class Registration { public static final DeferredHolder, BlockEntityType> REQUESTER_ENTITY = BLOCK_ENTITIES.register( REQUESTER_ID, () -> { - // noinspection DataFlowIssue - var type = new BlockEntityType( - RequesterBlockEntity::new, - REQUESTER_BLOCK.get() - ); + var type = new BlockEntityType<>(RequesterBlockEntity::new, REQUESTER_BLOCK.get()); AEBaseBlockEntity.registerBlockEntityItem(type, REQUESTER_BLOCK.asItem()); REQUESTER_BLOCK.get().setBlockEntity(RequesterBlockEntity.class, type, null, null); return type; @@ -86,13 +82,11 @@ public final class Registration { public static final DeferredItem> REQUESTER_TERMINAL = ITEMS.registerItem( TERMINAL_ID, - properties -> { - return new PartItem<>( - properties, - RequesterTerminalPart.class, - RequesterTerminalPart::new - ); - } + properties -> new PartItem<>( + properties, + RequesterTerminalPart.class, + RequesterTerminalPart::new + ) ); public static final DeferredHolder, MenuType> REQUESTER_TERMINAL_MENU = MENUS.register( TERMINAL_ID, @@ -108,12 +102,12 @@ public final class Registration { .build() ); - private Registration() {} + private ModRegistration() {} public static void init(IEventBus modEventBus) { // High priority due to AE2WTLib closes it's registration in the registry event - modEventBus.addListener(EventPriority.HIGH, Registration::registerContents); - modEventBus.addListener(Registration::registerCapabilities); + modEventBus.addListener(EventPriority.HIGH, ModRegistration::registerContents); + modEventBus.addListener(ModRegistration::registerCapabilities); modEventBus.addListener(Tab::initContents); WirelessTerminalCompat.INSTANCE.init(MENUS); @@ -140,7 +134,7 @@ private static void registerCapabilities(RegisterCapabilitiesEvent event) { event.registerBlockEntity( AECapabilities.IN_WORLD_GRID_NODE_HOST, REQUESTER_ENTITY.get(), - (requester, ctx) -> requester + (requester, _) -> requester ); WirelessTerminalCompat.INSTANCE.registerCapabilities(event); diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java index 72b85b4..98c4178 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterBlockEntity.java @@ -3,7 +3,7 @@ import com.almostreliable.merequester.MERequester; import com.almostreliable.merequester.Utils; import com.almostreliable.merequester.core.Config; -import com.almostreliable.merequester.core.Registration; +import com.almostreliable.merequester.core.ModRegistration; import com.almostreliable.merequester.requester.abstraction.RequestHost; import com.almostreliable.merequester.requester.status.LinkState; import com.almostreliable.merequester.requester.status.RequestStatus; @@ -11,9 +11,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.core.HolderLookup; import net.minecraft.core.component.DataComponentMap; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -65,7 +63,7 @@ public class RequesterBlockEntity extends AENetworkedBlockEntity implements Requ private TickRateModulation currentTickRate = TickRateModulation.IDLE; public RequesterBlockEntity(BlockPos pos, BlockState blockState) { - this(com.almostreliable.merequester.core.Registration.REQUESTER_ENTITY.get(), pos, blockState); // TODO 26.1 somehow this did not work otherwise + this(ModRegistration.REQUESTER_ENTITY.get(), pos, blockState); } public RequesterBlockEntity(BlockEntityType blockEntityType, BlockPos pos, BlockState blockState) { @@ -106,7 +104,7 @@ public void saveAdditional(ValueOutput data) { public void importSettings(SettingsFrom mode, DataComponentMap input, @Nullable Player player) { super.importSettings(mode, input, player); if (mode == SettingsFrom.MEMORY_CARD) { - var exportedRequests = input.get(com.almostreliable.merequester.core.Registration.EXPORTED_REQUESTS.get()); // TODO 26.1 somehow this did not work otherwise + var exportedRequests = input.get(ModRegistration.EXPORTED_REQUESTS.get()); if (exportedRequests != null) { requestManager.fromComponent(exportedRequests); } @@ -117,7 +115,7 @@ public void importSettings(SettingsFrom mode, DataComponentMap input, @Nullable public void exportSettings(SettingsFrom mode, DataComponentMap.Builder builder, @Nullable Player player) { super.exportSettings(mode, builder, player); if (mode == SettingsFrom.MEMORY_CARD) { - builder.set(com.almostreliable.merequester.core.Registration.EXPORTED_REQUESTS.get(), requestManager.toComponent()); // TODO 26.1 somehow this did not work otherwise + builder.set(ModRegistration.EXPORTED_REQUESTS.get(), requestManager.toComponent()); } } From adbe312145eed4917ccbc90937f3870644e7f028 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:53:43 +0200 Subject: [PATCH 43/52] update loader minimum version --- src/main/resources/META-INF/neoforge.mods.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index 6cb6d07..066f372 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -1,5 +1,5 @@ modLoader = "javafml" -loaderVersion = "[2,)" +loaderVersion = "[11,)" issueTrackerURL = "https://github.com/${githubUser}/${githubRepo}/issues" license = "${license}" logoFile = "logo.png" From 3ed12a46370492b5fcc75c312c88c03e90cf93ad Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:58:19 +0200 Subject: [PATCH 44/52] fix ser/de not using proper defaults --- .../com/almostreliable/merequester/requester/Request.java | 8 ++++---- .../merequester/requester/StorageManager.java | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/requester/Request.java b/src/main/java/com/almostreliable/merequester/requester/Request.java index 19ee659..efc0772 100644 --- a/src/main/java/com/almostreliable/merequester/requester/Request.java +++ b/src/main/java/com/almostreliable/merequester/requester/Request.java @@ -72,15 +72,15 @@ public Component toComponent() { @Override public void deserialize(ValueInput data) { - state = data.getBooleanOr(STATE_ID, false); + state = data.getBooleanOr(STATE_ID, state); var childKey = data.child(KEY_ID); if (childKey.isPresent()) key = AEKey.fromTagGeneric(childKey.orElseThrow()); else key = null; - amount = data.getLongOr(AMOUNT_ID, 0); - batch = data.getLongOr(BATCH_ID, 0); - clientStatus = RequestStatus.values()[data.getIntOr(STATUS_ID, 0)]; + amount = data.getLongOr(AMOUNT_ID, amount); + batch = data.getLongOr(BATCH_ID, batch); + clientStatus = RequestStatus.values()[data.getIntOr(STATUS_ID, clientStatus.ordinal())]; } public void fromComponent(Component request) { diff --git a/src/main/java/com/almostreliable/merequester/requester/StorageManager.java b/src/main/java/com/almostreliable/merequester/requester/StorageManager.java index e0ff347..83f2d71 100644 --- a/src/main/java/com/almostreliable/merequester/requester/StorageManager.java +++ b/src/main/java/com/almostreliable/merequester/requester/StorageManager.java @@ -144,9 +144,9 @@ public void deserialize(ValueInput data) { key = AEKey.fromTagGeneric(childKey.orElseThrow()); else key = null; - bufferAmount = data.getLongOr(BUFFER_AMOUNT_ID, 0); - pendingAmount = data.getLongOr(PENDING_AMOUNT_ID, 0); - knownAmount = data.getLongOr(KNOWN_AMOUNT_ID, 0); + bufferAmount = data.getLongOr(BUFFER_AMOUNT_ID, bufferAmount); + pendingAmount = data.getLongOr(PENDING_AMOUNT_ID, pendingAmount); + knownAmount = data.getLongOr(KNOWN_AMOUNT_ID, knownAmount); } /** From 7723823eea2b444fee7cc43c9d7b6d3aaa327554 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 20:37:24 +0200 Subject: [PATCH 45/52] separate requests between manager and config inventory --- .../merequester/client/RequestSlot.java | 2 +- .../merequester/requester/Request.java | 5 - .../merequester/requester/RequestManager.java | 197 +----------------- .../requester/RequesterConfigInventory.java | 79 +++++++ .../merequester/requester/RequesterMenu.java | 2 +- .../abstraction/AbstractRequesterMenu.java | 2 +- .../terminal/RequesterTerminalMenu.java | 2 +- 7 files changed, 91 insertions(+), 198 deletions(-) create mode 100644 src/main/java/com/almostreliable/merequester/requester/RequesterConfigInventory.java diff --git a/src/main/java/com/almostreliable/merequester/client/RequestSlot.java b/src/main/java/com/almostreliable/merequester/client/RequestSlot.java index 4ae2c54..c422f82 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequestSlot.java +++ b/src/main/java/com/almostreliable/merequester/client/RequestSlot.java @@ -27,7 +27,7 @@ public class RequestSlot extends FakeSlot { private boolean isLocked; public RequestSlot(RequestDisplay host, RequesterReference requesterReference, int slot, int x, int y) { - super(requesterReference.getRequestManager(), slot); + super(requesterReference.getRequestManager().getConfigInventory(), slot); this.host = host; this.requesterReference = requesterReference; this.slot = slot; diff --git a/src/main/java/com/almostreliable/merequester/requester/Request.java b/src/main/java/com/almostreliable/merequester/requester/Request.java index efc0772..63c553e 100644 --- a/src/main/java/com/almostreliable/merequester/requester/Request.java +++ b/src/main/java/com/almostreliable/merequester/requester/Request.java @@ -153,11 +153,6 @@ void updateKey(@Nullable GenericStack stack) { keyChanged(); } - void setClientKey(AEKey key, long amount) { - this.key = key; - this.amount = amount; - } - private void keyChanged() { if (host != null) host.requestChanged(index); } diff --git a/src/main/java/com/almostreliable/merequester/requester/RequestManager.java b/src/main/java/com/almostreliable/merequester/requester/RequestManager.java index ce66e61..aa58959 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequestManager.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequestManager.java @@ -3,53 +3,33 @@ import com.almostreliable.merequester.core.Config; import com.almostreliable.merequester.requester.abstraction.RequestHost; -import net.minecraft.network.chat.Component; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.ValueOutput; import net.neoforged.neoforge.common.util.ValueIOSerializable; -import net.neoforged.neoforge.transfer.ResourceHandler; -import net.neoforged.neoforge.transfer.item.ItemResource; -import net.neoforged.neoforge.transfer.transaction.TransactionContext; -import appeng.api.behaviors.GenericInternalInventory; -import appeng.api.config.Actionable; import appeng.api.inventories.InternalInventory; -import appeng.api.stacks.AEItemKey; import appeng.api.stacks.AEKey; -import appeng.api.stacks.AEKeyType; import appeng.api.stacks.GenericStack; -import appeng.api.storage.MEStorage; -import appeng.helpers.externalstorage.GenericStackInv; -import com.google.common.primitives.Ints; import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.List; -/** - * Uses the same approach as {@link GenericStackInv} to track items and fluids. - *

- * Automatically provides a menu wrapper by implementing {@link InternalInventory}. - */ -@SuppressWarnings("UnstableApiUsage") -public class RequestManager implements MEStorage, GenericInternalInventory, InternalInventory, ValueIOSerializable { +public class RequestManager implements ValueIOSerializable { - // if null, the inventory is client-side and doesn't need saving - @Nullable - private final RequestHost host; private final Request[] requests; private final int size; + private final RequesterConfigInventory configInventory; public RequestManager(@Nullable RequestHost host) { - this.host = host; this.size = Config.COMMON.requests.get(); - requests = new Request[size]; + this.requests = new Request[size]; for (var i = 0; i < requests.length; i++) { requests[i] = new Request(host, i); } + this.configInventory = new RequesterConfigInventory(this); } public RequestManager() { @@ -60,82 +40,30 @@ public Request get(int index) { return requests[index]; } - @Override public int size() { return size; } @Nullable - @Override public GenericStack getStack(int index) { return get(index).toGenericStack(); } @Nullable - @Override public AEKey getKey(int index) { return get(index).getKey(); } - @Override public long getAmount(int index) { return get(index).getAmount(); } - @Override - public long getMaxAmount(AEKey key) { - return 1; - } - - @Override - public long getCapacity(AEKeyType keyType) { - return 1; - } - - @Override - public boolean canInsert() { - return true; - } - - @Override - public boolean canExtract() { - return false; - } - - @Override - public void setStack(int index, @Nullable GenericStack stack) { + void setStack(int index, @Nullable GenericStack stack) { get(index).updateKey(stack); } - @Override - public boolean isSupportedType(AEKeyType type) { - return true; - } - - @Override - public boolean isAllowedIn(int slot, AEKey what) { - return true; - } - - @Override - public long insert(int index, AEKey key, long amount, Actionable mode) { - if (mode == Actionable.SIMULATE) return amount; - if (host == null || host.isClientSide()) { - get(index).setClientKey(key, amount); - } else { - get(index).updateKey(new GenericStack(key, amount)); - } - return amount; - } - - @Override - public long extract(int index, AEKey key, long amount, Actionable mode) { - throw new UnsupportedOperationException(); - } - - @Override - public void onChange() { - if (host != null) host.saveChanges(); + public InternalInventory getConfigInventory() { + return configInventory; } @Override @@ -157,7 +85,7 @@ public void fromComponent(List exportedRequests) { if (i < exportedRequests.size()) { get(i).fromComponent(exportedRequests.get(i)); } else { - setItemDirect(i, ItemStack.EMPTY); + setStack(i, null); } } } @@ -176,113 +104,4 @@ public int firstAvailableIndex() { } return -1; } - - @Override - public Component getDescription() { - if (host == null) return net.minecraft.network.chat.Component.empty(); - return host.getTerminalName(); - } - - @Override - public void updateSnapshots(TransactionContext transaction) {} // TODO 26.1 - - @Override - public ResourceHandler toResourceHandler() { // TODO 26.1 - return new ResourceHandler() { - @Override - public int size() { - return 0; - } - - @Override - public ItemResource getResource(int index) { - return null; - } - - @Override - public long getAmountAsLong(int index) { - return 0; - } - - @Override - public long getCapacityAsLong(int index, ItemResource resource) { - return 0; - } - - @Override - public boolean isValid(int index, ItemResource resource) { - return false; - } - - @Override - public int insert(int index, ItemResource resource, int amount, TransactionContext transaction) { - return 0; - } - - @Override - public int extract(int index, ItemResource resource, int amount, TransactionContext transaction) { - return 0; - } - }; - } - - // - @Override - public void beginBatch() {} - - @Override - public void endBatch() {} - - @Override - public void endBatchSuppressed() {} - // - - // - @Override - public boolean isItemValid(int slot, ItemStack stack) { - return stack.isEmpty() || convertToSuitableStack(stack) != null; - } - - @Override - public int getSlotLimit(int slot) { - return 1; - } - - @Override - public ItemStack getStackInSlot(int slot) { - var genericStack = getStack(slot); - if (genericStack != null && genericStack.what() instanceof AEItemKey itemKey) { - return itemKey.toStack(); - } - return GenericStack.wrapInItemStack(genericStack); - } - - @Override - public void setItemDirect(int slot, ItemStack stack) { - if (stack.isEmpty()) { - setStack(slot, null); - } else { - var converted = convertToSuitableStack(stack); - if (converted != null) setStack(slot, converted); - } - } - - @Nullable - private GenericStack convertToSuitableStack(ItemStack stack) { - if (stack.isEmpty()) return null; - - var unwrappedStack = GenericStack.unwrapItemStack(stack); - ItemStack returnStack = stack; - if (unwrappedStack != null) { - if (unwrappedStack.what() instanceof AEItemKey itemKey) { - returnStack = itemKey.toStack(Math.max(1, Ints.saturatedCast(unwrappedStack.amount()))); - } else { - return unwrappedStack; - } - } - - var itemKey = AEItemKey.of(returnStack); - return itemKey != null ? new GenericStack(itemKey, returnStack.getCount()) : null; - } - // } diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterConfigInventory.java b/src/main/java/com/almostreliable/merequester/requester/RequesterConfigInventory.java new file mode 100644 index 0000000..df32d06 --- /dev/null +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterConfigInventory.java @@ -0,0 +1,79 @@ +package com.almostreliable.merequester.requester; + +import net.minecraft.world.item.ItemStack; + +import net.neoforged.neoforge.transfer.ResourceHandler; +import net.neoforged.neoforge.transfer.item.ItemResource; + +import appeng.api.inventories.InternalInventory; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.GenericStack; +import com.google.common.primitives.Ints; + +import org.jspecify.annotations.Nullable; + +final class RequesterConfigInventory implements InternalInventory { + + private final RequestManager manager; + + RequesterConfigInventory(RequestManager manager) { + this.manager = manager; + } + + @Override + public ResourceHandler toResourceHandler() { + throw new UnsupportedOperationException("requester config inventory is not resource storage"); + } + + @Override + public int size() { + return manager.size(); + } + + @Override + public boolean isItemValid(int slot, ItemStack stack) { + return stack.isEmpty() || convertToSuitableStack(stack) != null; + } + + @Override + public int getSlotLimit(int slot) { + return 1; + } + + @Override + public ItemStack getStackInSlot(int slot) { + var genericStack = manager.getStack(slot); + if (genericStack != null && genericStack.what() instanceof AEItemKey itemKey) { + return itemKey.toStack(); + } + return GenericStack.wrapInItemStack(genericStack); + } + + @Override + public void setItemDirect(int slot, ItemStack stack) { + if (stack.isEmpty()) { + manager.setStack(slot, null); + } else { + var converted = convertToSuitableStack(stack); + if (converted != null) manager.setStack(slot, converted); + } + } + + @Nullable + private GenericStack convertToSuitableStack(ItemStack stack) { + if (stack.isEmpty()) return null; + + var unwrappedStack = GenericStack.unwrapItemStack(stack); + ItemStack returnStack = stack; + if (unwrappedStack != null) { + if (unwrappedStack.what() instanceof AEItemKey itemKey) { + returnStack = itemKey.toStack(Math.max(1, Ints.saturatedCast(unwrappedStack.amount()))); + } else { + return unwrappedStack; + } + } + + var itemKey = AEItemKey.of(returnStack); + return itemKey != null ? new GenericStack(itemKey, returnStack.getCount()) : null; + } +} diff --git a/src/main/java/com/almostreliable/merequester/requester/RequesterMenu.java b/src/main/java/com/almostreliable/merequester/requester/RequesterMenu.java index 656ffbf..deb30cb 100644 --- a/src/main/java/com/almostreliable/merequester/requester/RequesterMenu.java +++ b/src/main/java/com/almostreliable/merequester/requester/RequesterMenu.java @@ -46,7 +46,7 @@ protected int transferStackToMenu(ItemStack stack) { assert requestTracker != null; var firstAvailable = requestTracker.getServer().firstAvailableIndex(); if (firstAvailable != -1) { - requestTracker.getServer().insertItem(firstAvailable, stack, false); + requestTracker.getServer().getConfigInventory().insertItem(firstAvailable, stack, false); } return 0; } diff --git a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java index db1b10c..5d61acc 100644 --- a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java +++ b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java @@ -45,7 +45,7 @@ public void doAction(ServerPlayer player, InventoryAction action, int slot, long return; } - var requestSlot = requestTracker.getServer().getSlotInv(slot); + var requestSlot = requestTracker.getServer().getConfigInventory().getSlotInv(slot); var requestStack = requestSlot.getStackInSlot(0); var carriedStack = getCarried(); diff --git a/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalMenu.java b/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalMenu.java index 0e3cda9..5ff8f02 100644 --- a/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalMenu.java +++ b/src/main/java/com/almostreliable/merequester/terminal/RequesterTerminalMenu.java @@ -67,7 +67,7 @@ protected int transferStackToMenu(ItemStack stack) { for (var requester : requesters) { var targetSlot = requester.getRequestManager().firstAvailableIndex(); if (targetSlot == -1) continue; - byRequester.get(requester).getServer().insertItem(targetSlot, stack, false); + byRequester.get(requester).getServer().getConfigInventory().insertItem(targetSlot, stack, false); break; } From 905d006c30517146bbc098c63994464064fcc52c Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 20:51:53 +0200 Subject: [PATCH 46/52] do not mark slots as drag and drop targets if locked --- .../com/almostreliable/merequester/client/RequestSlot.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/almostreliable/merequester/client/RequestSlot.java b/src/main/java/com/almostreliable/merequester/client/RequestSlot.java index c422f82..6589d3a 100644 --- a/src/main/java/com/almostreliable/merequester/client/RequestSlot.java +++ b/src/main/java/com/almostreliable/merequester/client/RequestSlot.java @@ -84,4 +84,9 @@ public void setLocked(boolean locked) { public void setFilterTo(ItemStack itemStack) { ClientPacketDistributor.sendToServer(new DragAndDropPacket(getRequesterReference().getRequesterId(), getSlot(), itemStack)); } + + @Override + public boolean canSetFilterTo(ItemStack stack) { + return !isLocked && super.canSetFilterTo(stack); + } } From 6f9ab9ad1322a92ad5fa07ee3a4bf9ade3ecdd4f Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 21:20:05 +0200 Subject: [PATCH 47/52] fix requester screen using wrong render pipeline for background --- .../abstraction/AbstractRequesterScreen.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index bf90c66..5085a81 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -11,6 +11,7 @@ import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.renderer.Rect2i; +import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; @@ -299,10 +300,18 @@ protected void resetScrollbar() { protected abstract RequesterReference getById(long requesterId, String name, long sortBy); private void blit(GuiGraphicsExtractor guiGraphics, int pX, int pY, Rect2i srcRect) { - // TODO 26.1 this is hardcoded and thus fragile - float width = 256; - float height = 256; - guiGraphics.blit(texture, pX, pY, pX+srcRect.getWidth(), pY+srcRect.getHeight(), (float)srcRect.getX()/width, (float)(srcRect.getX() + srcRect.getWidth())/width, (float)srcRect.getY()/height, (float)(srcRect.getY() + srcRect.getHeight())/height); + guiGraphics.blit( + RenderPipelines.GUI_TEXTURED, + texture, + pX, + pY, + srcRect.getX(), + srcRect.getY(), + srcRect.getWidth(), + srcRect.getHeight(), + 256, + 256 + ); } private RequestSlot createSlot(int index, Request request) { From 60dfbcd11cf87c2440d4194132cd28ef9c21fb49 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 21:20:16 +0200 Subject: [PATCH 48/52] add missing particle textures in terminal --- .../assets/merequester/models/part/requester_terminal_on.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/assets/merequester/models/part/requester_terminal_on.json b/src/main/resources/assets/merequester/models/part/requester_terminal_on.json index b5ad780..b4d4806 100644 --- a/src/main/resources/assets/merequester/models/part/requester_terminal_on.json +++ b/src/main/resources/assets/merequester/models/part/requester_terminal_on.json @@ -2,7 +2,8 @@ "textures": { "lightsBright": "merequester:part/requester_terminal_bright", "lightsMedium": "merequester:part/requester_terminal_medium", - "lightsDark": "merequester:part/requester_terminal_dark" + "lightsDark": "merequester:part/requester_terminal_dark", + "particle": "#lightsMedium" }, "elements": [ { From 2d9c0ab9e4593f8777d495509a540bd81a8a8808 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 21:38:37 +0200 Subject: [PATCH 49/52] clean up wtlib integration --- .../compat/wtlib/ReqWirelessTerminalItem.java | 5 ++- .../compat/wtlib/WirelessTerminalCompat.java | 39 +++++++++---------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalItem.java b/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalItem.java index 89c1e8a..b714507 100644 --- a/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalItem.java +++ b/src/main/java/com/almostreliable/merequester/compat/wtlib/ReqWirelessTerminalItem.java @@ -7,7 +7,8 @@ import de.mari_023.ae2wtlib.api.terminal.ItemWT; class ReqWirelessTerminalItem extends ItemWT { - public ReqWirelessTerminalItem(Properties p) { + + ReqWirelessTerminalItem(Properties p) { super(p); } @@ -15,4 +16,4 @@ public ReqWirelessTerminalItem(Properties p) { public MenuType getMenuType(ItemMenuHostLocator itemMenuHostLocator, Player player) { return ReqWirelessTerminalMenu.TYPE; } -} \ No newline at end of file +} diff --git a/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java b/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java index 13272a0..d784cc5 100644 --- a/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java +++ b/src/main/java/com/almostreliable/merequester/compat/wtlib/WirelessTerminalCompat.java @@ -1,11 +1,9 @@ package com.almostreliable.merequester.compat.wtlib; -import com.almostreliable.merequester.ModConstants; import com.almostreliable.merequester.Utils; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; -import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.Item; @@ -14,7 +12,6 @@ import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; -import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; import appeng.api.features.GridLinkables; @@ -23,7 +20,6 @@ import appeng.items.tools.powered.powersink.PoweredItemCapabilities; import de.mari_023.ae2wtlib.api.gui.Icon; import de.mari_023.ae2wtlib.api.registration.AddTerminalEvent; - import org.jspecify.annotations.Nullable; import java.util.List; @@ -73,37 +69,40 @@ private boolean isLoaded() { private WirelessTerminalCompat() {} @SuppressWarnings("StaticVariableUsedBeforeInitialization") - static final class Guard { + private static final class Guard { @Nullable - static ReqWirelessTerminalItem WIRELESS_REQUESTER_TERMINAL; - @Nullable - static DeferredHolder, MenuType> WIRELESS_REQUESTER_TERMINAL_MENU; + private static ReqWirelessTerminalItem WIRELESS_REQUESTER_TERMINAL; private static void init(DeferredRegister> menuRegistry) { - WIRELESS_REQUESTER_TERMINAL_MENU = menuRegistry.register( - TERMINAL_ID, - () -> ReqWirelessTerminalMenu.TYPE - ); + menuRegistry.register(TERMINAL_ID, () -> ReqWirelessTerminalMenu.TYPE); } - public static void registerWirelessTerminal(Registry registry) { - WIRELESS_REQUESTER_TERMINAL = new ReqWirelessTerminalItem(new Item.Properties().setId(ResourceKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath( - ModConstants.MOD_ID, TERMINAL_ID)))); // TODO this is probably not the correct way with the manual .setId - Registry.register(registry, Utils.getRL(TERMINAL_ID), WIRELESS_REQUESTER_TERMINAL); + private static void registerWirelessTerminal(Registry registry) { + var terminalId = Utils.getRL(TERMINAL_ID); + var terminalKey = ResourceKey.create(Registries.ITEM, terminalId); + var terminalItem = new ReqWirelessTerminalItem(new Item.Properties().setId(terminalKey)); + + Registry.register(registry, terminalId, terminalItem); AddTerminalEvent.register(event -> event.builder( - "requester", ReqWirelessTerminalMenuHost::new, ReqWirelessTerminalMenu.TYPE, WIRELESS_REQUESTER_TERMINAL, - Icon.PATTERN_ACCESS // TODO 26.1 this looks like the wrong value + "requester", + ReqWirelessTerminalMenuHost::new, + ReqWirelessTerminalMenu.TYPE, + terminalItem, + Icon.PATTERN_ACCESS // TODO: replace this with a custom icon ) .addTerminal()); + + WIRELESS_REQUESTER_TERMINAL = terminalItem; } private static void registerCapabilities(RegisterCapabilitiesEvent event) { assert WIRELESS_REQUESTER_TERMINAL != null; + GridLinkables.register(WIRELESS_REQUESTER_TERMINAL, WirelessTerminalItem.LINKABLE_HANDLER); event.registerItem( Capabilities.Energy.ITEM, - (stack, context) -> new PoweredItemCapabilities(context, WIRELESS_REQUESTER_TERMINAL, WIRELESS_REQUESTER_TERMINAL), + (_, context) -> new PoweredItemCapabilities(context, WIRELESS_REQUESTER_TERMINAL, WIRELESS_REQUESTER_TERMINAL), WIRELESS_REQUESTER_TERMINAL ); } @@ -112,8 +111,6 @@ private static Iterable collectItems() { assert WIRELESS_REQUESTER_TERMINAL != null; return List.of(WIRELESS_REQUESTER_TERMINAL); } - - private Guard() {} } private static final class GuardClient { From 3d69d68c61a28f7991a10e8ea65dd96f87425418 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 21:50:24 +0200 Subject: [PATCH 50/52] fix texture name for front in requester model --- .../merequester/models/block/requester.json | 20 +++++++++---------- .../models/block/requester_active.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/resources/assets/merequester/models/block/requester.json b/src/main/resources/assets/merequester/models/block/requester.json index 589e84d..81a1ed6 100644 --- a/src/main/resources/assets/merequester/models/block/requester.json +++ b/src/main/resources/assets/merequester/models/block/requester.json @@ -2,7 +2,7 @@ "credit": "Made with Blockbench by Almost Reliable", "parent": "block/orientable", "textures": { - "face": "merequester:block/requester", + "front": "merequester:block/requester", "top": "ae2:block/generics/top", "back": "ae2:block/generics/back", "bottom": "ae2:block/generics/bottom", @@ -26,39 +26,39 @@ "from": [0, 0, 0], "to": [16, 4, 1], "faces": { - "north": {"uv": [0, 12, 16, 16], "texture": "#face"}, - "up": {"uv": [16, 12, 0, 13], "texture": "#face"} + "north": {"uv": [0, 12, 16, 16], "texture": "#front"}, + "up": {"uv": [16, 12, 0, 13], "texture": "#front"} } }, { "from": [3, 3, 1], "to": [13, 13, 2], "faces": { - "north": {"uv": [3, 3, 13, 13], "texture": "#face"} + "north": {"uv": [3, 3, 13, 13], "texture": "#front"} } }, { "from": [0, 4, 0], "to": [4, 16, 1], "faces": { - "north": {"uv": [12, 0, 16, 12], "texture": "#face"}, - "east": {"uv": [12, 0, 13, 12], "texture": "#face"} + "north": {"uv": [12, 0, 16, 12], "texture": "#front"}, + "east": {"uv": [12, 0, 13, 12], "texture": "#front"} } }, { "from": [12, 4, 0], "to": [16, 16, 1], "faces": { - "north": {"uv": [0, 0, 4, 12], "texture": "#face"}, - "west": {"uv": [3, 0, 4, 12], "texture": "#face"} + "north": {"uv": [0, 0, 4, 12], "texture": "#front"}, + "west": {"uv": [3, 0, 4, 12], "texture": "#front"} } }, { "from": [4, 12, 0], "to": [12, 16, 1], "faces": { - "north": {"uv": [4, 0, 12, 4], "texture": "#face"}, - "down": {"uv": [12, 3, 4, 4], "texture": "#face"} + "north": {"uv": [4, 0, 12, 4], "texture": "#front"}, + "down": {"uv": [12, 3, 4, 4], "texture": "#front"} } } ], diff --git a/src/main/resources/assets/merequester/models/block/requester_active.json b/src/main/resources/assets/merequester/models/block/requester_active.json index 7c70b31..88c46cb 100644 --- a/src/main/resources/assets/merequester/models/block/requester_active.json +++ b/src/main/resources/assets/merequester/models/block/requester_active.json @@ -1,6 +1,6 @@ { "parent": "merequester:block/requester", "textures": { - "face": "merequester:block/requester_active" + "front": "merequester:block/requester_active" } } From ebb8810c41311bcd544d38af69a4daa1cabe398f Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 21:59:44 +0200 Subject: [PATCH 51/52] improve sync packet logic --- .../abstraction/AbstractRequesterScreen.java | 20 ++---- .../network/RequesterSyncPacket.java | 43 ++++++++---- .../merequester/requester/Request.java | 8 +-- .../abstraction/AbstractRequesterMenu.java | 65 +++++++++---------- 4 files changed, 74 insertions(+), 62 deletions(-) diff --git a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java index 5085a81..104a89c 100644 --- a/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java +++ b/src/main/java/com/almostreliable/merequester/client/abstraction/AbstractRequesterScreen.java @@ -5,6 +5,7 @@ import com.almostreliable.merequester.client.RequestSlot; import com.almostreliable.merequester.client.widgets.RequestWidget; import com.almostreliable.merequester.mixin.accessors.WidgetContainerMixin; +import com.almostreliable.merequester.network.RequesterSyncPacket; import com.almostreliable.merequester.requester.Request; import com.almostreliable.merequester.requester.abstraction.AbstractRequesterMenu; @@ -12,16 +13,12 @@ import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.renderer.Rect2i; import net.minecraft.client.renderer.RenderPipelines; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; -import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.storage.TagValueInput; -import net.minecraft.world.level.storage.ValueInput; import net.neoforged.neoforge.client.network.ClientPacketDistributor; import appeng.api.behaviors.ContainerItemStrategies; @@ -114,21 +111,18 @@ public List getEmptyingTooltip(RequestSlot slot, ItemStack carried) { return Tooltips.getEmptyingTooltip(ButtonToolTips.SetAction, carried, emptyingAction); } - public void updateFromMenu(boolean clearData, long requesterId, CompoundTag tag) { + public void updateFromMenu(boolean clearData, long requesterId, RequesterSyncPacket.Payload data) { if (clearData) { clear(); refreshList(); return; } - ValueInput data = TagValueInput.create(ProblemReporter.DISCARDING, getPlayer().registryAccess(), tag); - var name = data.getStringOr(AbstractRequesterMenu.UNIQUE_NAME_ID, ""); - var sortBy = data.getLongOr(AbstractRequesterMenu.SORT_BY_ID, 0); - var requests = getById(requesterId, name, sortBy).getRequestManager(); - - for (var i = 0; i < requests.size(); i++) { - var child = data.child(String.valueOf(i)); - if (child.isPresent()) requests.get(i).deserialize(child.orElseThrow()); + var requests = getById(requesterId, data.name(), data.sortBy()).getRequestManager(); + for (var update : data.updates()) { + var index = update.index(); + if (index < 0 || index >= requests.size()) continue; + requests.get(index).fromComponent(update.component()); } if (refreshList) refreshList(); diff --git a/src/main/java/com/almostreliable/merequester/network/RequesterSyncPacket.java b/src/main/java/com/almostreliable/merequester/network/RequesterSyncPacket.java index 89a71eb..1430ba6 100644 --- a/src/main/java/com/almostreliable/merequester/network/RequesterSyncPacket.java +++ b/src/main/java/com/almostreliable/merequester/network/RequesterSyncPacket.java @@ -2,36 +2,36 @@ import com.almostreliable.merequester.Utils; import com.almostreliable.merequester.client.abstraction.AbstractRequesterScreen; +import com.almostreliable.merequester.requester.Request; import net.minecraft.client.Minecraft; -import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.neoforged.neoforge.network.handling.IPayloadContext; -import io.netty.buffer.ByteBuf; +import java.util.List; -public record RequesterSyncPacket( - boolean clearData, long requesterId, - CompoundTag data -) implements CustomPacketPayload { +public record RequesterSyncPacket(boolean clearData, long requesterId, Payload data) implements CustomPacketPayload { + + private static final Payload EMPTY_PAYLOAD = new Payload("", 0L, List.of()); static final Type TYPE = new Type<>(Utils.getRL("requester_sync")); - static final StreamCodec STREAM_CODEC = StreamCodec.composite( + static final StreamCodec STREAM_CODEC = StreamCodec.composite( ByteBufCodecs.BOOL, RequesterSyncPacket::clearData, ByteBufCodecs.VAR_LONG, RequesterSyncPacket::requesterId, - ByteBufCodecs.COMPOUND_TAG, RequesterSyncPacket::data, + Payload.PAYLOAD_STREAM_CODEC, RequesterSyncPacket::data, RequesterSyncPacket::new ); public static RequesterSyncPacket createClearData() { - return new RequesterSyncPacket(true, -1, new CompoundTag()); + return new RequesterSyncPacket(true, -1, EMPTY_PAYLOAD); } - public static RequesterSyncPacket createInventory(long requesterId, CompoundTag data) { - return new RequesterSyncPacket(false, requesterId, data); + public static RequesterSyncPacket createInventory(long requesterId, String name, long sortBy, List updates) { + return new RequesterSyncPacket(false, requesterId, new Payload(name, sortBy, updates)); } @Override @@ -39,9 +39,28 @@ public Type type() { return TYPE; } - public static void handle(RequesterSyncPacket payload, IPayloadContext context) { + public static void handle(RequesterSyncPacket payload, IPayloadContext ignoredContext) { if (Minecraft.getInstance().screen instanceof AbstractRequesterScreen screen) { screen.updateFromMenu(payload.clearData, payload.requesterId, payload.data); } } + + public record Payload(String name, long sortBy, List updates) { + + private static final StreamCodec PAYLOAD_STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.STRING_UTF8, Payload::name, + ByteBufCodecs.VAR_LONG, Payload::sortBy, + IndexedRequest.REQUEST_STREAM_CODEC.apply(ByteBufCodecs.list()), Payload::updates, + Payload::new + ); + } + + public record IndexedRequest(int index, Request.Component component) { + + private static final StreamCodec REQUEST_STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, IndexedRequest::index, + Request.Component.STREAM_CODEC, IndexedRequest::component, + IndexedRequest::new + ); + } } diff --git a/src/main/java/com/almostreliable/merequester/requester/Request.java b/src/main/java/com/almostreliable/merequester/requester/Request.java index 63c553e..1dbb6d1 100644 --- a/src/main/java/com/almostreliable/merequester/requester/Request.java +++ b/src/main/java/com/almostreliable/merequester/requester/Request.java @@ -53,8 +53,7 @@ public final class Request implements ValueIOSerializable { @Override public void serialize(ValueOutput data) { data.putBoolean(STATE_ID, state); - if (key != null) - key.toTagGeneric(data.child(KEY_ID)); + if (key != null) key.toTagGeneric(data.child(KEY_ID)); data.putLong(AMOUNT_ID, amount); data.putLong(BATCH_ID, batch); data.putInt(STATUS_ID, clientStatus.ordinal()); @@ -74,10 +73,11 @@ public Component toComponent() { public void deserialize(ValueInput data) { state = data.getBooleanOr(STATE_ID, state); var childKey = data.child(KEY_ID); - if (childKey.isPresent()) + if (childKey.isPresent()) { key = AEKey.fromTagGeneric(childKey.orElseThrow()); - else + } else { key = null; + } amount = data.getLongOr(AMOUNT_ID, amount); batch = data.getLongOr(BATCH_ID, batch); clientStatus = RequestStatus.values()[data.getIntOr(STATUS_ID, clientStatus.ordinal())]; diff --git a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java index 5d61acc..39a65f9 100644 --- a/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java +++ b/src/main/java/com/almostreliable/merequester/requester/abstraction/AbstractRequesterMenu.java @@ -5,12 +5,9 @@ import com.almostreliable.merequester.requester.RequesterBlockEntity; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.storage.TagValueInput; -import net.minecraft.world.level.storage.TagValueOutput; import net.neoforged.neoforge.network.PacketDistributor; import appeng.api.behaviors.ContainerItemStrategies; @@ -21,10 +18,10 @@ import org.jspecify.annotations.Nullable; -public abstract class AbstractRequesterMenu extends AEBaseMenu { +import java.util.ArrayList; +import java.util.List; - public static final String SORT_BY_ID = "sort_by"; - public static final String UNIQUE_NAME_ID = "unique_name"; +public abstract class AbstractRequesterMenu extends AEBaseMenu { // used to give requesters unique IDs private long idSerial = Long.MIN_VALUE; @@ -113,50 +110,52 @@ protected void syncRequestTrackerFull(RequestTracker requestTracker) { var server = requestTracker.getServer(); var client = requestTracker.getClient(); - // get the requests from the server - TagValueOutput data = TagValueOutput.createWithContext(ProblemReporter.DISCARDING, getPlayer().registryAccess()); - server.serialize(data); - // store the information in the client tracker to - // check for differences on partial updates later - // tag serialization is used to avoid references to the original data - client.deserialize(TagValueInput.create(ProblemReporter.DISCARDING, getPlayer().registryAccess(), data.buildResult())); - - // send relevant data to the client - data.putString(UNIQUE_NAME_ID, requestTracker.getName()); - data.putLong(SORT_BY_ID, requestTracker.getSortBy()); - if (getPlayer() instanceof ServerPlayer serverPlayer) { - PacketDistributor.sendToPlayer(serverPlayer, RequesterSyncPacket.createInventory(requestTracker.getId(), data.buildResult())); + var updates = new ArrayList(server.size()); + for (var i = 0; i < server.size(); i++) { + var component = server.get(i).toComponent(); + client.get(i).fromComponent(component); + updates.add(new RequesterSyncPacket.IndexedRequest(i, component)); } + + sendInventorySync(requestTracker, updates); } protected void syncRequestTrackerPartial(RequestTracker requestTracker) { var server = requestTracker.getServer(); var client = requestTracker.getClient(); - TagValueOutput data = null; - // iterate through the server data and check for differences + List updates = null; for (var i = 0; i < server.size(); i++) { var serverRequest = server.get(i); var clientRequest = client.get(i); if (serverRequest.isDifferent(clientRequest)) { - // write initial data as soon as something is different - if (data == null) { - data = TagValueOutput.createWithContext(ProblemReporter.DISCARDING, getPlayer().registryAccess()); - data.putString(UNIQUE_NAME_ID, requestTracker.getName()); - data.putLong(SORT_BY_ID, requestTracker.getSortBy()); + if (updates == null) { + updates = new ArrayList<>(); } - serverRequest.serialize(data.child(String.valueOf(i))); - var tmp = TagValueOutput.createWithContext(ProblemReporter.DISCARDING, getPlayer().registryAccess()); - serverRequest.serialize(tmp); - clientRequest.deserialize(TagValueInput.create(ProblemReporter.DISCARDING, getPlayer().registryAccess(), tmp.buildResult())); + var component = serverRequest.toComponent(); + clientRequest.fromComponent(component); + updates.add(new RequesterSyncPacket.IndexedRequest(i, component)); } } - // only send an update if something changed - if (data != null && getPlayer() instanceof ServerPlayer serverPlayer) { - PacketDistributor.sendToPlayer(serverPlayer, RequesterSyncPacket.createInventory(requestTracker.getId(), data.buildResult())); + if (updates != null) { + sendInventorySync(requestTracker, updates); + } + } + + private void sendInventorySync(RequestTracker requestTracker, List updates) { + if (getPlayer() instanceof ServerPlayer serverPlayer) { + PacketDistributor.sendToPlayer( + serverPlayer, + RequesterSyncPacket.createInventory( + requestTracker.getId(), + requestTracker.getName(), + requestTracker.getSortBy(), + updates + ) + ); } } From bf90f3df10f33e4eb597573d34c3a20a0832a162 Mon Sep 17 00:00:00 2001 From: rlnt <16513358+rlnt@users.noreply.github.com> Date: Tue, 1 Sep 2026 22:03:53 +0200 Subject: [PATCH 52/52] update workflows --- .github/workflows/build.yml | 6 +++--- .github/workflows/release.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 87844da..aa8cae0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - "1.21.1" + - "26.1" tags-ignore: - "**" paths: @@ -15,7 +15,7 @@ on: - "**/build.yml" pull_request: branches: - - "1.21.1" + - "26.1" paths: - "gradle/**" - "**.java" @@ -32,4 +32,4 @@ jobs: uses: AlmostReliable/.github/.github/workflows/build.yml@main with: java-distribution: "microsoft" - java-version: "21" + java-version: "25" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 73bb299..00c7f2d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: secrets: inherit with: java-distribution: "microsoft" - java-version: "21" + java-version: "25" mod_name: "MERequester" curseforge_id: "688367" modrinth_id: "E6BFl96N"