aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authormiozune <miozune@gmail.com>2023-08-17 13:38:26 +0900
committerGitHub <noreply@github.com>2023-08-17 06:38:26 +0200
commit7d64f80c790d262b10eddae72042b09c4816d327 (patch)
tree15da9511f80db1acbe0bfe623221cb5013fba79e /src/main
parent740233c43667a9b27e25033cac4833db826007f2 (diff)
downloadGT5-Unofficial-7d64f80c790d262b10eddae72042b09c4816d327.tar.gz
GT5-Unofficial-7d64f80c790d262b10eddae72042b09c4816d327.tar.bz2
GT5-Unofficial-7d64f80c790d262b10eddae72042b09c4816d327.zip
Fix server crash with RecipeFilter (#2231)
* Fix server crash with RecipeFilter * Make client send filtered machines to server * Use mUniqueIdentifier
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java55
-rw-r--r--src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_RecipeFilter.java165
-rw-r--r--src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_TypeFilter.java20
3 files changed, 195 insertions, 45 deletions
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java
index cb293e51a9..1a71f17ec8 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_SpecialFilter.java
@@ -40,8 +40,6 @@ public abstract class GT_MetaTileEntity_SpecialFilter extends GT_MetaTileEntity_
super(aName, aTier, aInvSlotCount, aDescription, aTextures);
}
- public abstract void clickTypeIcon(boolean aRightClick, ItemStack aHandStack);
-
@Override
public void saveNBTData(NBTTagCompound aNBT) {
super.saveNBTData(aNBT);
@@ -88,29 +86,10 @@ public abstract class GT_MetaTileEntity_SpecialFilter extends GT_MetaTileEntity_
new DrawableWidget().setDrawable(GT_UITextures.PICTURE_ARROW_24_RED.apply(19, true))
.setPos(152, 19)
.setSize(19, 24))
- .widget(new SlotWidget(BaseSlot.phantom(inventoryHandler, 9)) {
-
- @Override
- protected void phantomClick(ClickData clickData, ItemStack cursorStack) {
- clickTypeIcon(clickData.mouseButton != 0, cursorStack);
- }
-
- @Override
- public void buildTooltip(List<Text> tooltip) {
- super.buildTooltip(tooltip);
- List<Text> emptySlotTooltip = getEmptySlotTooltip();
- if (emptySlotTooltip != null) {
- tooltip.addAll(emptySlotTooltip);
- }
- }
-
- @Override
- public Function<List<String>, List<String>> getOverwriteItemStackTooltip() {
- return getItemStackReplacementTooltip();
- }
- }.disableShiftInsert()
- .setPos(34, 22)
- .setBackground(GT_UITextures.BUTTON_STANDARD))
+ .widget(
+ createFilterIconSlot(BaseSlot.phantom(inventoryHandler, 9)).disableShiftInsert()
+ .setPos(34, 22)
+ .setBackground(GT_UITextures.BUTTON_STANDARD))
.widget(
SlotGroup.ofItemHandler(inventoryHandler, 3)
.endAtSlot(8)
@@ -126,4 +105,30 @@ public abstract class GT_MetaTileEntity_SpecialFilter extends GT_MetaTileEntity_
GT_UITextures.OVERLAY_BUTTON_NBT,
() -> mTooltipCache.getData(ALLOW_NBT_TOOLTIP)));
}
+
+ protected abstract SlotWidget createFilterIconSlot(BaseSlot slot);
+
+ protected abstract class FilterIconSlotWidget extends SlotWidget {
+
+ public FilterIconSlotWidget(BaseSlot slot) {
+ super(slot);
+ }
+
+ @Override
+ protected abstract void phantomClick(ClickData clickData, ItemStack cursorStack);
+
+ @Override
+ public void buildTooltip(List<Text> tooltip) {
+ super.buildTooltip(tooltip);
+ List<Text> emptySlotTooltip = getEmptySlotTooltip();
+ if (emptySlotTooltip != null) {
+ tooltip.addAll(emptySlotTooltip);
+ }
+ }
+
+ @Override
+ public Function<List<String>, List<String>> getOverwriteItemStackTooltip() {
+ return getItemStackReplacementTooltip();
+ }
+ }
}
diff --git a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_RecipeFilter.java b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_RecipeFilter.java
index 4df9ca55b7..58dd2d5550 100644
--- a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_RecipeFilter.java
+++ b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_RecipeFilter.java
@@ -3,6 +3,7 @@ package gregtech.common.tileentities.automation;
import static gregtech.api.enums.Textures.BlockIcons.AUTOMATION_RECIPEFILTER;
import static gregtech.api.enums.Textures.BlockIcons.AUTOMATION_RECIPEFILTER_GLOW;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -11,21 +12,28 @@ import java.util.stream.Collectors;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.network.PacketBuffer;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.Constants;
import org.jetbrains.annotations.NotNull;
import com.gtnewhorizons.modularui.api.drawable.Text;
import com.gtnewhorizons.modularui.api.screen.ModularWindow;
import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.common.internal.network.NetworkUtils;
+import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot;
import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
import codechicken.nei.recipe.RecipeCatalysts;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.interfaces.tileentity.IRecipeLockable;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicGenerator;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_SpecialFilter;
import gregtech.api.multitileentity.MultiTileEntityContainer;
@@ -42,7 +50,7 @@ public class GT_MetaTileEntity_RecipeFilter extends GT_MetaTileEntity_SpecialFil
private static final String REPRESENTATION_SLOT_TOOLTIP = "GT5U.recipe_filter.representation_slot.tooltip";
private static final String EMPTY_REPRESENTATION_SLOT_TOOLTIP = "GT5U.recipe_filter.empty_representation_slot.tooltip";
public GT_Recipe.GT_Recipe_Map mRecipeMap;
- private List<ItemStack> filteredMachines = Collections.emptyList();
+ private List<ItemStack> filteredMachines = new ArrayList<>();
public int mRotationIndex = 0;
public GT_MetaTileEntity_RecipeFilter(int aID, String aName, String aNameRegional, int aTier) {
@@ -64,18 +72,6 @@ public class GT_MetaTileEntity_RecipeFilter extends GT_MetaTileEntity_SpecialFil
super(aName, aTier, aInvSlotCount, aDescription, aTextures);
}
- @Override
- public void clickTypeIcon(boolean rightClick, ItemStack heldStack) {
- mRecipeMap = getItemStackMachineRecipeMap(heldStack);
- if (mRecipeMap != null) {
- filteredMachines = getFilteredMachines(mRecipeMap);
- } else {
- filteredMachines = Collections.emptyList();
- mInventory[FILTER_SLOT_INDEX] = null;
- }
- mRotationIndex = -1;
- }
-
private static GT_Recipe.GT_Recipe_Map getItemStackMachineRecipeMap(ItemStack stack) {
if (stack != null) {
IMetaTileEntity metaTileEntity = GT_Item_Machines.getMetaTileEntity(stack);
@@ -93,6 +89,8 @@ public class GT_MetaTileEntity_RecipeFilter extends GT_MetaTileEntity_SpecialFil
return machine.getRecipeList();
} else if (metaTileEntity instanceof IRecipeLockable recipeLockable) {
return recipeLockable.getRecipeMap();
+ } else if (metaTileEntity instanceof GT_MetaTileEntity_BasicGenerator generator) {
+ return generator.getRecipes();
}
return null;
}
@@ -118,12 +116,7 @@ public class GT_MetaTileEntity_RecipeFilter extends GT_MetaTileEntity_SpecialFil
super.onPreTick(aBaseMetaTileEntity, aTick);
if ((!getBaseMetaTileEntity().isServerSide()) || ((aTick % 8L != 0L) && mRotationIndex != -1)) return;
if (this.filteredMachines.isEmpty()) {
- if (mRecipeMap != null) {
- // This should succeed after a few ticks when NEI is fully loaded.
- filteredMachines = getFilteredMachines(mRecipeMap);
- } else {
- return;
- }
+ return;
}
this.mInventory[FILTER_SLOT_INDEX] = GT_Utility.copyAmount(
1L,
@@ -155,12 +148,25 @@ public class GT_MetaTileEntity_RecipeFilter extends GT_MetaTileEntity_SpecialFil
public void saveNBTData(NBTTagCompound aNBT) {
super.saveNBTData(aNBT);
if (mRecipeMap != null) aNBT.setString("mRecipeMap", this.mRecipeMap.mUniqueIdentifier);
+ NBTTagList tagList = new NBTTagList();
+ for (ItemStack filteredMachine : filteredMachines) {
+ tagList.appendTag(filteredMachine.writeToNBT(new NBTTagCompound()));
+ }
+ aNBT.setTag("filteredMachines", tagList);
}
@Override
public void loadNBTData(NBTTagCompound aNBT) {
super.loadNBTData(aNBT);
this.mRecipeMap = GT_Recipe.GT_Recipe_Map.sIndexedMappings.getOrDefault(aNBT.getString("mRecipeMap"), null);
+ filteredMachines.clear();
+ NBTTagList tagList = aNBT.getTagList("filteredMachines", Constants.NBT.TAG_COMPOUND);
+ for (int i = 0; i < tagList.tagCount(); i++) {
+ ItemStack readStack = ItemStack.loadItemStackFromNBT(tagList.getCompoundTagAt(i));
+ if (readStack != null) {
+ filteredMachines.add(readStack);
+ }
+ }
}
@Override
@@ -205,4 +211,125 @@ public class GT_MetaTileEntity_RecipeFilter extends GT_MetaTileEntity_SpecialFil
tooltip.addAll(mTooltipCache.getData(REPRESENTATION_SLOT_TOOLTIP).text);
return tooltip;
}
+
+ @Override
+ protected SlotWidget createFilterIconSlot(BaseSlot slot) {
+ return new RecipeFilterIconSlotWidget(slot);
+ }
+
+ private class RecipeFilterIconSlotWidget extends FilterIconSlotWidget {
+
+ private static final int SYNC_RECIPEMAP_C2S = 98;
+ private static final int REQUEST_FILTERED_MACHINES_S2C = 99;
+
+ public RecipeFilterIconSlotWidget(BaseSlot slot) {
+ super(slot);
+ }
+
+ @Override
+ protected void phantomClick(ClickData clickData, ItemStack cursorStack) {}
+
+ // region client
+
+ @Override
+ public ClickResult onClick(int buttonId, boolean doubleClick) {
+ updateAndSendRecipeMapToServer(
+ getContext().getCursor()
+ .getItemStack());
+ return ClickResult.SUCCESS;
+ }
+
+ @Override
+ public boolean handleDragAndDrop(ItemStack draggedStack, int button) {
+ updateAndSendRecipeMapToServer(draggedStack);
+ draggedStack.stackSize = 0;
+ return true;
+ }
+
+ private void updateAndSendRecipeMapToServer(ItemStack stack) {
+ mRecipeMap = getItemStackMachineRecipeMap(stack);
+ updateAndSendRecipeMapToServer(mRecipeMap);
+ }
+
+ private void updateAndSendRecipeMapToServer(GT_Recipe.GT_Recipe_Map recipeMap) {
+ if (recipeMap != null) {
+ filteredMachines = getFilteredMachines(recipeMap);
+ } else {
+ filteredMachines = new ArrayList<>();
+ mInventory[FILTER_SLOT_INDEX] = null;
+ }
+ mRotationIndex = -1;
+ syncToServer(SYNC_RECIPEMAP_C2S, buffer -> {
+ NetworkUtils.writeStringSafe(buffer, recipeMap != null ? recipeMap.mUniqueIdentifier : null);
+ buffer.writeVarIntToBuffer(filteredMachines.size());
+ for (ItemStack filteredMachine : filteredMachines) {
+ try {
+ buffer.writeItemStackToBuffer(filteredMachine);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void readOnClient(int id, PacketBuffer buf) {
+ if (id != REQUEST_FILTERED_MACHINES_S2C) {
+ super.readOnClient(id, buf);
+ return;
+ }
+
+ String recipeMapName = NetworkUtils.readStringSafe(buf);
+ mRecipeMap = recipeMapName != null
+ ? GT_Recipe.GT_Recipe_Map.sIndexedMappings.getOrDefault(recipeMapName, null)
+ : null;
+ if (mRecipeMap != null) {
+ updateAndSendRecipeMapToServer(mRecipeMap);
+ }
+ }
+
+ // endregion
+
+ // region server
+
+ @Override
+ public void readOnServer(int id, PacketBuffer buf) throws IOException {
+ if (id != SYNC_RECIPEMAP_C2S) {
+ super.readOnServer(id, buf);
+ return;
+ }
+
+ String recipeMapName = NetworkUtils.readStringSafe(buf);
+ mRecipeMap = recipeMapName != null
+ ? GT_Recipe.GT_Recipe_Map.sIndexedMappings.getOrDefault(recipeMapName, null)
+ : null;
+ mRotationIndex = -1;
+ mInventory[FILTER_SLOT_INDEX] = null;
+ filteredMachines.clear();
+
+ if (mRecipeMap != null) {
+ int filteredMachineSize = buf.readVarIntFromBuffer();
+ filteredMachineSize = Math.min(filteredMachineSize, 256); // Prevent storing too many items
+ for (int i = 0; i < filteredMachineSize; i++) {
+ ItemStack stack = buf.readItemStackFromBuffer();
+ if (stack != null) {
+ filteredMachines.add(stack);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void detectAndSendChanges(boolean init) {
+ super.detectAndSendChanges(init);
+ if (init && mRecipeMap != null && filteredMachines.isEmpty()) {
+ // backward compatibility: This machine used to store only mRecipeMap, not filteredMachines
+ syncToClient(
+ REQUEST_FILTERED_MACHINES_S2C,
+ buffer -> NetworkUtils.writeStringSafe(buffer, mRecipeMap.mUniqueIdentifier));
+ }
+ }
+
+ // endregion
+ }
}
diff --git a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_TypeFilter.java b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_TypeFilter.java
index 56ce5877ea..598abc80a2 100644
--- a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_TypeFilter.java
+++ b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_TypeFilter.java
@@ -14,7 +14,9 @@ import net.minecraft.nbt.NBTTagCompound;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.modularui.api.screen.ModularWindow;
import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot;
import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
import gregtech.api.enums.OrePrefixes;
import gregtech.api.interfaces.ITexture;
@@ -86,7 +88,6 @@ public class GT_MetaTileEntity_TypeFilter extends GT_MetaTileEntity_SpecialFilte
.build());
}
- @Override
public void clickTypeIcon(boolean aRightClick, ItemStack aHandStack) {
if (getBaseMetaTileEntity().isServerSide()) {
if (aHandStack != null) {
@@ -192,4 +193,21 @@ public class GT_MetaTileEntity_TypeFilter extends GT_MetaTileEntity_SpecialFilte
return replacementTooltip;
};
}
+
+ @Override
+ protected SlotWidget createFilterIconSlot(BaseSlot slot) {
+ return new TypeFilterIconSlotWidget(slot);
+ }
+
+ private class TypeFilterIconSlotWidget extends FilterIconSlotWidget {
+
+ public TypeFilterIconSlotWidget(BaseSlot slot) {
+ super(slot);
+ }
+
+ @Override
+ protected void phantomClick(ClickData clickData, ItemStack cursorStack) {
+ clickTypeIcon(clickData.mouseButton != 0, cursorStack);
+ }
+ }
}