diff options
author | miozune <miozune@gmail.com> | 2023-08-17 13:38:26 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-17 06:38:26 +0200 |
commit | 7d64f80c790d262b10eddae72042b09c4816d327 (patch) | |
tree | 15da9511f80db1acbe0bfe623221cb5013fba79e /src/main | |
parent | 740233c43667a9b27e25033cac4833db826007f2 (diff) | |
download | GT5-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')
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); + } + } } |