diff --git a/build.properties b/build.properties index c2a66261..713cc925 100644 --- a/build.properties +++ b/build.properties @@ -2,4 +2,4 @@ mc_version=1.7.10 forge_version=10.13.4.1614-1.7.10 ccl_version=1.1.3.138 ccc_version=1.0.7.+ -mod_version=2.1.4-GTNH +mod_version=2.1.5-GTNH diff --git a/src/codechicken/nei/ItemPanel.java b/src/codechicken/nei/ItemPanel.java index 5a1273ef..5f6e5807 100644 --- a/src/codechicken/nei/ItemPanel.java +++ b/src/codechicken/nei/ItemPanel.java @@ -231,9 +231,13 @@ public class ItemPanel extends Widget { private boolean slotValid(GuiContainer gui, int i) { Rectangle4i rect = getSlotRect(i); - for (INEIGuiHandler handler : GuiInfo.guiHandlers) - if (handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h)) + try { + GuiInfo.readLock.lock(); + if(GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h))) return false; + } finally { + GuiInfo.readLock.unlock(); + } return true; } @@ -297,9 +301,13 @@ public class ItemPanel extends Widget { return true; if (NEIClientUtils.getHeldItem() != null) { - for (INEIGuiHandler handler : GuiInfo.guiHandlers) - if (handler.hideItemPanelSlot(NEIClientUtils.getGuiContainer(), mousex, mousey, 1, 1)) + try { + GuiInfo.readLock.lock(); + if (GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(NEIClientUtils.getGuiContainer(), mousex, mousey, 1, 1))) return false; + } finally { + GuiInfo.readLock.unlock(); + } if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item")) if (button == 1) @@ -337,15 +345,21 @@ public class ItemPanel extends Widget { GuiContainer gui = NEIClientUtils.getGuiContainer(); boolean handled = false; - for (INEIGuiHandler handler : GuiInfo.guiHandlers) - if (handler.handleDragNDrop(gui, mousex, mousey, draggedStack, button)) { - handled = true; - if (draggedStack.stackSize == 0) { - draggedStack = null; - return true; + try { + GuiInfo.readLock.lock(); + for (INEIGuiHandler handler : GuiInfo.guiHandlers) { + if (handler.handleDragNDrop(gui, mousex, mousey, draggedStack, button)) { + handled = true; + if (draggedStack.stackSize == 0) { + draggedStack = null; + return true; + } } } - + } finally { + GuiInfo.readLock.unlock(); + } + if (handled) return true; @@ -470,10 +484,13 @@ public class ItemPanel extends Widget { public boolean contains(int px, int py) { GuiContainer gui = NEIClientUtils.getGuiContainer(); Rectangle4i rect = new Rectangle4i(px, py, 1, 1); - for (INEIGuiHandler handler : GuiInfo.guiHandlers) - if (handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h)) + try { + GuiInfo.readLock.lock(); + if(GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h))) return false; - + } finally { + GuiInfo.readLock.unlock(); + } return super.contains(px, py); } } diff --git a/src/codechicken/nei/LayoutManager.java b/src/codechicken/nei/LayoutManager.java index e7b09b3a..969d9bf7 100644 --- a/src/codechicken/nei/LayoutManager.java +++ b/src/codechicken/nei/LayoutManager.java @@ -317,10 +317,13 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH if (gui.guiLeft - 4 < 76) visiblity.showWidgets = false; - - for (INEIGuiHandler handler : GuiInfo.guiHandlers) - handler.modifyVisiblity(gui, visiblity); - + try { + GuiInfo.readLock.lock(); + GuiInfo.guiHandlers.forEach(handler -> handler.modifyVisiblity(gui, visiblity)); + } finally { + GuiInfo.readLock.unlock(); + } + visiblity.translateDependancies(); getLayoutStyle().layout(gui, visiblity); diff --git a/src/codechicken/nei/NEIClientUtils.java b/src/codechicken/nei/NEIClientUtils.java index e672a21d..9553dd7b 100644 --- a/src/codechicken/nei/NEIClientUtils.java +++ b/src/codechicken/nei/NEIClientUtils.java @@ -27,6 +27,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; import static codechicken.nei.NEIClientConfig.canCheatItem; import static codechicken.nei.NEIClientConfig.canPerformAction; @@ -157,9 +158,13 @@ public class NEIClientUtils extends NEIServerUtils ItemStack typestack = copyStack(stack, 1); if (!infinite && !canItemFitInInventory(mc().thePlayer, stack) && (mc().currentScreen instanceof GuiContainer)) { GuiContainer gui = getGuiContainer(); - List> handlerSlots = new LinkedList<>(); - for(INEIGuiHandler handler : GuiInfo.guiHandlers) - handlerSlots.add(handler.getItemSpawnSlots(gui, typestack)); + final List> handlerSlots; + try { + GuiInfo.readLock.lock(); + handlerSlots = GuiInfo.guiHandlers.stream().map(handler -> handler.getItemSpawnSlots(gui, typestack)).collect(Collectors.toCollection(LinkedList::new)); + } finally { + GuiInfo.readLock.unlock(); + } int increment = typestack.getMaxStackSize(); int given = 0; diff --git a/src/codechicken/nei/api/API.java b/src/codechicken/nei/api/API.java index b5c324e1..dc4544c5 100644 --- a/src/codechicken/nei/api/API.java +++ b/src/codechicken/nei/api/API.java @@ -112,7 +112,12 @@ public class API } public static void registerNEIGuiHandler(INEIGuiHandler handler) { - GuiInfo.guiHandlers.add(handler); + try { + GuiInfo.writeLock.lock(); + GuiInfo.guiHandlers.add(handler); + } finally { + GuiInfo.writeLock.unlock(); + } } /** diff --git a/src/codechicken/nei/api/GuiInfo.java b/src/codechicken/nei/api/GuiInfo.java index 059d827d..45ee350e 100644 --- a/src/codechicken/nei/api/GuiInfo.java +++ b/src/codechicken/nei/api/GuiInfo.java @@ -9,11 +9,16 @@ import net.minecraft.client.gui.inventory.GuiContainerCreative; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; -public class GuiInfo -{ +public class GuiInfo { public static final LinkedList guiHandlers = new LinkedList<>(); public static final HashSet> customSlotGuis = new HashSet<>(); + public static ReentrantReadWriteLock guiHandlersLock = new ReentrantReadWriteLock(); + public static Lock writeLock = guiHandlersLock.writeLock(); + public static Lock readLock = guiHandlersLock.readLock(); + public static void load() { API.registerNEIGuiHandler(new NEICreativeGuiHandler()); @@ -23,9 +28,12 @@ public class GuiInfo } public static void clearGuiHandlers() { - for (Iterator iterator = guiHandlers.iterator(); iterator.hasNext(); ) - if (iterator.next() instanceof GuiContainer) - iterator.remove(); + try { + GuiInfo.writeLock.lock(); + guiHandlers.removeIf(ineiGuiHandler -> ineiGuiHandler instanceof GuiContainer); + } finally { + GuiInfo.writeLock.unlock(); + } } public static boolean hasCustomSlots(GuiContainer gui) { diff --git a/src/codechicken/nei/guihook/GuiContainerManager.java b/src/codechicken/nei/guihook/GuiContainerManager.java index 996e86c5..ff9f760b 100644 --- a/src/codechicken/nei/guihook/GuiContainerManager.java +++ b/src/codechicken/nei/guihook/GuiContainerManager.java @@ -19,6 +19,7 @@ import java.awt.Point; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -249,12 +250,12 @@ public class GuiContainerManager } private int clickHandled = 0; - private List instanceTooltipHandlers; + private final List instanceTooltipHandlers; public GuiContainerManager(GuiContainer screen) { window = screen; if (screen instanceof IContainerTooltipHandler) { - instanceTooltipHandlers = new LinkedList<>(); + instanceTooltipHandlers = Collections.synchronizedList(new LinkedList<>()); instanceTooltipHandlers.add((IContainerTooltipHandler) screen); instanceTooltipHandlers.addAll(tooltipHandlers); } else @@ -398,17 +399,21 @@ public class GuiContainerManager List tooltip = new LinkedList<>(); FontRenderer font = GuiDraw.fontRenderer; - for (IContainerTooltipHandler handler : instanceTooltipHandlers) - tooltip = handler.handleTooltip(window, mousex, mousey, tooltip); - + synchronized (instanceTooltipHandlers) { + for (IContainerTooltipHandler handler : instanceTooltipHandlers) + tooltip = handler.handleTooltip(window, mousex, mousey, tooltip); + } + if (tooltip.isEmpty() && shouldShowTooltip(window)) {//mouseover tip, not holding an item ItemStack stack = getStackMouseOver(window); font = getFontRenderer(stack); if (stack != null) tooltip = itemDisplayNameMultiline(stack, window, true); - for (IContainerTooltipHandler handler : instanceTooltipHandlers) - tooltip = handler.handleItemTooltip(window, stack, mousex, mousey, tooltip); + synchronized (instanceTooltipHandlers) { + for (IContainerTooltipHandler handler : instanceTooltipHandlers) + tooltip = handler.handleItemTooltip(window, stack, mousex, mousey, tooltip); + } } if (tooltip.size() > 0)