From 928de6a991a5a83f73bdb576a55b025ce9da5978 Mon Sep 17 00:00:00 2001 From: Nightenom <17338378+Nightenom@users.noreply.github.com> Date: Thu, 2 Nov 2023 19:53:55 +0100 Subject: [PATCH] Do not crash if missing texture file when in production (#63) Still crashes when in dev --- .../java/com/ldtteam/blockui/BOScreen.java | 9 ++- .../com/ldtteam/blockui/UiRenderMacros.java | 12 ---- .../com/ldtteam/blockui/controls/Image.java | 25 ++++++- .../blockui/mod/ClientEventSubscriber.java | 12 ++-- .../ldtteam/blockui/util/cursor/Cursor.java | 37 ++++++++--- .../blockui/util/cursor/CursorUtils.java | 44 +++++++++++-- .../util/resloc/OutOfJarResourceLocation.java | 5 +- .../blockui/util/texture/CursorTexture.java | 4 +- .../util/texture/MissingCursorTexture.java | 40 +++++++++++ .../blockui/util/texture/OutOfJarTexture.java | 62 ++++++++++++++---- .../blockui/util/texture/SpriteTexture.java | 8 ++- .../resources/assets/blockui/gui/test.xml | 5 +- src/test/resources/button.png | Bin 0 -> 18770 bytes 13 files changed, 203 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/ldtteam/blockui/util/texture/MissingCursorTexture.java create mode 100644 src/test/resources/button.png diff --git a/src/main/java/com/ldtteam/blockui/BOScreen.java b/src/main/java/com/ldtteam/blockui/BOScreen.java index 4e14f6d2..b5ada11f 100644 --- a/src/main/java/com/ldtteam/blockui/BOScreen.java +++ b/src/main/java/com/ldtteam/blockui/BOScreen.java @@ -15,6 +15,8 @@ import net.minecraftforge.client.ForgeRenderTypes; import org.lwjgl.glfw.GLFW; +import java.util.Objects; + /** * Wraps MineCrafts GuiScreen for BlockOut's Window. */ @@ -102,7 +104,10 @@ public void render(final PoseStack ms, final int mx, final int my, final float f try { window.draw(newMs, calcRelativeX(mx), calcRelativeY(my)); - applyCursor(); + if (ms.minecraft.screen == this) + { + applyCursor(); + } window.drawLast(newMs, calcRelativeX(mx), calcRelativeY(my)); } catch (final Exception e) @@ -188,7 +193,7 @@ else if (keyCode == GLFW.GLFW_MOUSE_BUTTON_RIGHT) { final CrashReport crashReport = CrashReport.forThrowable(e, "MousePressed event for BO screen"); final CrashReportCategory category = crashReport.addCategory("BO screen mouse event details"); - category.setDetail("XML res loc", () -> window.getXmlResourceLocation().toString()); + category.setDetail("XML res loc", () -> Objects.toString(window.getXmlResourceLocation())); category.setDetail("GLFW mouse key value", () -> Integer.toString(keyCode)); throw new ReportedException(crashReport); } diff --git a/src/main/java/com/ldtteam/blockui/UiRenderMacros.java b/src/main/java/com/ldtteam/blockui/UiRenderMacros.java index 7756fd72..b92dfb95 100644 --- a/src/main/java/com/ldtteam/blockui/UiRenderMacros.java +++ b/src/main/java/com/ldtteam/blockui/UiRenderMacros.java @@ -1,7 +1,5 @@ package com.ldtteam.blockui; -import com.ldtteam.blockui.util.resloc.OutOfJarResourceLocation; -import com.ldtteam.blockui.util.texture.OutOfJarTexture; import com.mojang.blaze3d.platform.Lighting; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; @@ -428,7 +426,6 @@ public static void blit(final PoseStack ps, final float uMax, final float vMax) { - checkOutOfJarResLoc(rl); Minecraft.getInstance().getTextureManager().bindForSetup(rl); RenderSystem.setShaderTexture(0, rl); RenderSystem.setShader(GameRenderer::getPositionTexShader); @@ -443,14 +440,6 @@ public static void blit(final PoseStack ps, Tesselator.getInstance().end(); } - private static void checkOutOfJarResLoc(final ResourceLocation rl) - { - if (rl instanceof final OutOfJarResourceLocation outOfJarResLoc) - { - OutOfJarTexture.assertLoaded(outOfJarResLoc, Minecraft.getInstance().getTextureManager()); - } - } - /** * Draws texture without scaling so one texel is one pixel, using repeatable texture center. * TODO: Nightenom - rework to better algoritm from pgr, also texture extensions? @@ -552,7 +541,6 @@ protected static void blitRepeatable(final PoseStack ps, // bot left corner populateBlitTriangles(buffer, mat, xEnd, xEnd + uLeft, yEnd, yEnd + vLeft, restMinU, restMaxU, restMinV, restMaxV); - checkOutOfJarResLoc(rl); Minecraft.getInstance().getTextureManager().bindForSetup(rl); RenderSystem.setShaderTexture(0, rl); RenderSystem.setShader(GameRenderer::getPositionTexShader); diff --git a/src/main/java/com/ldtteam/blockui/controls/Image.java b/src/main/java/com/ldtteam/blockui/controls/Image.java index a29df9ce..f0fde26f 100644 --- a/src/main/java/com/ldtteam/blockui/controls/Image.java +++ b/src/main/java/com/ldtteam/blockui/controls/Image.java @@ -6,6 +6,7 @@ import com.ldtteam.blockui.mod.Log; import com.ldtteam.blockui.util.records.SizeI; import com.ldtteam.blockui.util.resloc.OutOfJarResourceLocation; +import com.ldtteam.blockui.util.texture.OutOfJarTexture; import com.ldtteam.blockui.util.texture.SpriteTexture; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; @@ -13,10 +14,14 @@ import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Tuple; +import net.minecraftforge.fml.loading.FMLEnvironment; +import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.file.NoSuchFileException; import java.util.Iterator; import java.util.Objects; @@ -65,8 +70,7 @@ public Image(final PaneParams params) private void loadMapDimensions(final ResourceLocation rl) { - final SpriteTexture sprite = SpriteTexture.checkLoaded(rl, Minecraft.getInstance().getTextureManager(), Minecraft.getInstance().getResourceManager()); - if (sprite != null) + if (OutOfJarTexture.assertLoadedDefaultManagers(rl) instanceof final SpriteTexture sprite) { mapWidth = sprite.width(); mapHeight = sprite.height(); @@ -119,6 +123,9 @@ public void setMapDimensions(final int height, final int width) */ public static SizeI getImageDimensions(final ResourceLocation resourceLocation) { + // this is called by most of image classes -> parse our textures + OutOfJarTexture.assertLoadedDefaultManagers(resourceLocation); + final int pos = resourceLocation.getPath().lastIndexOf("."); if (pos == -1) @@ -139,6 +146,10 @@ public static SizeI getImageDimensions(final ResourceLocation resourceLocation) return new SizeI(reader.getWidth(reader.getMinIndex()), reader.getHeight(reader.getMinIndex())); } + catch (final NoSuchFileException | FileNotFoundException e) + { + // dont log these, texture manager logs it anyway + } catch (final IOException e) { Log.getLogger().warn(e); @@ -208,7 +219,15 @@ public void setImage(final ResourceLocation rl, final boolean keepUv) @Override public void drawSelf(final PoseStack ms, final double mx, final double my) { - Objects.requireNonNull(resourceLocation, () -> id + " | " + window.getXmlResourceLocation()); + if (!FMLEnvironment.production) + { + Objects.requireNonNull(resourceLocation, () -> id + " | " + window.getXmlResourceLocation()); + } + else if (resourceLocation == null) + { + resourceLocation = MissingTextureAtlasSprite.getLocation(); + } + RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); diff --git a/src/main/java/com/ldtteam/blockui/mod/ClientEventSubscriber.java b/src/main/java/com/ldtteam/blockui/mod/ClientEventSubscriber.java index 4ac39834..16224fb9 100644 --- a/src/main/java/com/ldtteam/blockui/mod/ClientEventSubscriber.java +++ b/src/main/java/com/ldtteam/blockui/mod/ClientEventSubscriber.java @@ -3,14 +3,12 @@ import com.ldtteam.blockui.BOScreen; import com.ldtteam.blockui.controls.Button; import com.ldtteam.blockui.controls.ButtonVanilla; -import com.ldtteam.blockui.Pane; -import com.ldtteam.blockui.controls.Text; +import com.ldtteam.blockui.controls.Image; import com.ldtteam.blockui.hooks.HookManager; import com.ldtteam.blockui.hooks.HookRegistries; import com.ldtteam.blockui.mod.container.ContainerHook; -import com.ldtteam.blockui.util.records.SizeI; +import com.ldtteam.blockui.util.resloc.OutOfJarResourceLocation; import com.ldtteam.blockui.views.BOWindow; -import com.ldtteam.blockui.views.ScrollingList; import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; @@ -29,7 +27,6 @@ import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; import java.util.function.Consumer; @@ -67,7 +64,10 @@ public static void onClientTickEvent(final ClientTickEvent event) if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_X)) { final BOWindow window = new BOWindow(); - window.addChild(createTestGuiButton(0, "General All-in-one", new ResourceLocation(BlockUI.MOD_ID, "gui/test.xml"))); + window.addChild(createTestGuiButton(0, "General All-in-one", new ResourceLocation(BlockUI.MOD_ID, "gui/test.xml"), parent -> { + parent.findPaneOfTypeByID("missing_out_of_jar", Image.class).setImage(OutOfJarResourceLocation.ofMinecraftFolder(BlockUI.MOD_ID, "missing_out_of_jar.png"), false); + parent.findPaneOfTypeByID("working_out_of_jar", Image.class).setImage(OutOfJarResourceLocation.ofMinecraftFolder(BlockUI.MOD_ID, "../../src/test/resources/button.png"), false); + })); window.addChild(createTestGuiButton(1, "Tooltip Positioning", new ResourceLocation(BlockUI.MOD_ID, "gui/test2.xml"))); window.addChild(createTestGuiButton(2, "ItemIcon To BlockState", new ResourceLocation(BlockUI.MOD_ID, "gui/test3.xml"), BlockStateTestGui::setup)); window.addChild(createTestGuiButton(3, "Dynamic ScrollingLists", new ResourceLocation(BlockUI.MOD_ID, "gui/test4.xml"), DynamicScrollingListGui::setup)); diff --git a/src/main/java/com/ldtteam/blockui/util/cursor/Cursor.java b/src/main/java/com/ldtteam/blockui/util/cursor/Cursor.java index a7bd11f2..d2f1e2cf 100644 --- a/src/main/java/com/ldtteam/blockui/util/cursor/Cursor.java +++ b/src/main/java/com/ldtteam/blockui/util/cursor/Cursor.java @@ -10,22 +10,41 @@ public interface Cursor { /** Probably arrow, but OS dependend */ - public static final Cursor DEFAULT = () -> CursorUtils.setStandardCursor(StandardCursor.DEFAULT); - public static final Cursor ARROW = () -> CursorUtils.setStandardCursor(StandardCursor.ARROW); - public static final Cursor TEXT_CURSOR = () -> CursorUtils.setStandardCursor(StandardCursor.TEXT_CURSOR); - public static final Cursor CROSSHAIR = () -> CursorUtils.setStandardCursor(StandardCursor.CROSSHAIR); - public static final Cursor HAND = () -> CursorUtils.setStandardCursor(StandardCursor.HAND); - public static final Cursor HORIZONTAL_RESIZE = () -> CursorUtils.setStandardCursor(StandardCursor.HORIZONTAL_RESIZE); - public static final Cursor VERTICAL_RESIZE = () -> CursorUtils.setStandardCursor(StandardCursor.VERTICAL_RESIZE); - public static final Cursor RESIZE = () -> CursorUtils.setStandardCursor(StandardCursor.RESIZE); + public static final Cursor DEFAULT = named(() -> CursorUtils.setStandardCursor(StandardCursor.DEFAULT), StandardCursor.DEFAULT); + public static final Cursor ARROW = named(() -> CursorUtils.setStandardCursor(StandardCursor.ARROW), StandardCursor.ARROW); + public static final Cursor TEXT_CURSOR = named(() -> CursorUtils.setStandardCursor(StandardCursor.TEXT_CURSOR), StandardCursor.TEXT_CURSOR); + public static final Cursor CROSSHAIR = named(() -> CursorUtils.setStandardCursor(StandardCursor.CROSSHAIR), StandardCursor.CROSSHAIR); + public static final Cursor HAND = named(() -> CursorUtils.setStandardCursor(StandardCursor.HAND), StandardCursor.HAND); + public static final Cursor HORIZONTAL_RESIZE = named(() -> CursorUtils.setStandardCursor(StandardCursor.HORIZONTAL_RESIZE), StandardCursor.HORIZONTAL_RESIZE); + public static final Cursor VERTICAL_RESIZE = named(() -> CursorUtils.setStandardCursor(StandardCursor.VERTICAL_RESIZE), StandardCursor.VERTICAL_RESIZE); + public static final Cursor RESIZE = named(() -> CursorUtils.setStandardCursor(StandardCursor.RESIZE), StandardCursor.RESIZE); public static Cursor of(final ResourceLocation resLoc) { - return () -> CursorUtils.setCursorImage(resLoc); + CursorUtils.loadCursorTexture(resLoc); + return named(() -> CursorUtils.setCursorImage(resLoc), resLoc); } /** * Apply cursor to main window */ void apply(); + + static Cursor named(final Runnable applier, final Object name) + { + return new Cursor() + { + @Override + public void apply() + { + applier.run(); + } + + @Override + public String toString() + { + return "Cursor: " + name; + } + }; + } } diff --git a/src/main/java/com/ldtteam/blockui/util/cursor/CursorUtils.java b/src/main/java/com/ldtteam/blockui/util/cursor/CursorUtils.java index 5e207aa2..86da71e6 100644 --- a/src/main/java/com/ldtteam/blockui/util/cursor/CursorUtils.java +++ b/src/main/java/com/ldtteam/blockui/util/cursor/CursorUtils.java @@ -1,11 +1,16 @@ package com.ldtteam.blockui.util.cursor; +import com.ldtteam.blockui.mod.BlockUI; import com.ldtteam.blockui.util.texture.CursorTexture; import com.ldtteam.blockui.util.texture.IsOurTexture; +import com.ldtteam.blockui.util.texture.MissingCursorTexture; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.AbstractTexture; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.fml.loading.FMLEnvironment; import org.lwjgl.glfw.GLFW; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,27 +26,52 @@ public class CursorUtils /** * Sets cursor image using given resource location. + * Do not forget to load given resLoc as CursorTexture first * * @param rl image resource location * @return cursor texture reference + * @see #loadCursorTexture(ResourceLocation) */ public static CursorTexture setCursorImage(final ResourceLocation rl) { AbstractTexture texture = Minecraft.getInstance().getTextureManager().getTexture(rl); + if (texture == MissingTextureAtlasSprite.getTexture()) + { + texture = MissingCursorTexture.INSTANCE; + } + + if (!(texture instanceof final CursorTexture cursorTexture)) + { + throw new IllegalArgumentException("Did you forget to load CursorTexture for: " + rl); + } + + cursorTexture.setCursor(); + return cursorTexture; + } + + /** + * Makes sure client global texture manager has CursorTexture assigned to given resLoc + * + * @param resLoc cursor file location + */ + public static void loadCursorTexture(final ResourceLocation resLoc) + { + final TextureManager texManager = Minecraft.getInstance().getTextureManager(); + final AbstractTexture texture = texManager.getTexture(resLoc, null); if (!(texture instanceof CursorTexture)) { if (IsOurTexture.isOur(texture)) { - LOGGER.warn("Trying to use special BlockUI texture as cursor? Things may not work well: " + rl.toString()); + LOGGER.warn("Trying to use special BlockUI texture as cursor? Things may not work well: " + resLoc.toString()); } - texture = new CursorTexture(rl); - Minecraft.getInstance().getTextureManager().register(rl, texture); - } + texManager.register(resLoc, new CursorTexture(resLoc)); - final CursorTexture cursorTexture = (CursorTexture) texture; - cursorTexture.setCursor(); - return cursorTexture; + if (!FMLEnvironment.production && texManager.getTexture(resLoc) == MissingTextureAtlasSprite.getTexture() && !resLoc.getNamespace().equals(BlockUI.MOD_ID)) + { + throw new IllegalArgumentException("Missing texture: " + resLoc); + } + } } /** diff --git a/src/main/java/com/ldtteam/blockui/util/resloc/OutOfJarResourceLocation.java b/src/main/java/com/ldtteam/blockui/util/resloc/OutOfJarResourceLocation.java index 8bdffa51..ad1d0894 100644 --- a/src/main/java/com/ldtteam/blockui/util/resloc/OutOfJarResourceLocation.java +++ b/src/main/java/com/ldtteam/blockui/util/resloc/OutOfJarResourceLocation.java @@ -8,6 +8,7 @@ import net.minecraft.server.packs.resources.ResourceMetadata; import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; @@ -54,7 +55,7 @@ public static boolean fileExists(final ResourceLocation resLoc, final ResourceMa return fallbackManager.getResource(resLoc).isPresent(); } - public static Resource getResourceHandle(final ResourceLocation resLoc, final ResourceManager fallbackManager) + public static Resource getResourceHandle(final ResourceLocation resLoc, final ResourceManager fallbackManager) throws IOException { if (resLoc instanceof final OutOfJarResourceLocation nioResLoc) { @@ -63,7 +64,7 @@ public static Resource getResourceHandle(final ResourceLocation resLoc, final Re new OutOfJarResource(nioResLoc, parseMetadata(mcmeta)) : new OutOfJarResource(nioResLoc); } - return fallbackManager.getResource(resLoc).orElseThrow(() -> new RuntimeException("File not found: " + resLoc)); + return fallbackManager.getResource(resLoc).orElseThrow(() -> new FileNotFoundException("File not found: " + resLoc)); } private static IoSupplier parseMetadata(final OutOfJarResourceLocation path) diff --git a/src/main/java/com/ldtteam/blockui/util/texture/CursorTexture.java b/src/main/java/com/ldtteam/blockui/util/texture/CursorTexture.java index 32eeb537..84932799 100644 --- a/src/main/java/com/ldtteam/blockui/util/texture/CursorTexture.java +++ b/src/main/java/com/ldtteam/blockui/util/texture/CursorTexture.java @@ -36,7 +36,7 @@ public class CursorTexture extends AbstractTexture private int hotspotY = 0; private long glfwCursorAddress = 0; @Nullable - private NativeImage nativeImage = null; + protected NativeImage nativeImage = null; public CursorTexture(final ResourceLocation resLoc) { @@ -87,7 +87,7 @@ private void onDataChange() } } - private void destroyCursorHandle() + protected void destroyCursorHandle() { if (glfwCursorAddress != 0) { diff --git a/src/main/java/com/ldtteam/blockui/util/texture/MissingCursorTexture.java b/src/main/java/com/ldtteam/blockui/util/texture/MissingCursorTexture.java new file mode 100644 index 00000000..22441937 --- /dev/null +++ b/src/main/java/com/ldtteam/blockui/util/texture/MissingCursorTexture.java @@ -0,0 +1,40 @@ +package com.ldtteam.blockui.util.texture; + +import com.ldtteam.blockui.mod.BlockUI; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; + +import java.io.IOException; + +/** + * Backed by missing vanilla texture. + */ +public final class MissingCursorTexture extends CursorTexture +{ + public static final MissingCursorTexture INSTANCE = new MissingCursorTexture(); + + private MissingCursorTexture() + { + super(new ResourceLocation(BlockUI.MOD_ID, "missing_cursor_texture")); + super.nativeImage = MissingTextureAtlasSprite.getTexture().getPixels(); + } + + @Override + public void close() + { + // Noop + } + + @Override + protected void destroyCursorHandle() + { + // Noop + } + + @Override + public void load(final ResourceManager resourceManager) throws IOException + { + // Noop + } +} diff --git a/src/main/java/com/ldtteam/blockui/util/texture/OutOfJarTexture.java b/src/main/java/com/ldtteam/blockui/util/texture/OutOfJarTexture.java index 046d52fe..399e7787 100644 --- a/src/main/java/com/ldtteam/blockui/util/texture/OutOfJarTexture.java +++ b/src/main/java/com/ldtteam/blockui/util/texture/OutOfJarTexture.java @@ -1,17 +1,22 @@ package com.ldtteam.blockui.util.texture; +import com.ldtteam.blockui.mod.BlockUI; import com.ldtteam.blockui.util.resloc.OutOfJarResourceLocation; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.platform.TextureUtil; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.AbstractTexture; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.client.renderer.texture.SimpleTexture; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.resources.metadata.animation.AnimationMetadataSection; import net.minecraft.client.resources.metadata.texture.TextureMetadataSection; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraftforge.fml.loading.FMLEnvironment; +import org.jetbrains.annotations.Nullable; -import java.io.FileNotFoundException; import java.io.IOException; /** @@ -30,11 +35,6 @@ public OutOfJarTexture(final OutOfJarResourceLocation resourceLocation) @Override public void load(final ResourceManager resourceManager) throws IOException { - if (!OutOfJarResourceLocation.fileExists(resourceLocation, resourceManager)) - { - throw new FileNotFoundException(resourceLocation.toString()); - } - final Resource resource = OutOfJarResourceLocation.getResourceHandle(resourceLocation, resourceManager); // redirect to sprite @@ -74,18 +74,54 @@ public void load(final ResourceManager resourceManager) throws IOException } } - public static void assertLoaded(final OutOfJarResourceLocation resourceLocation, final TextureManager textureManager) + public static AbstractTexture assertLoadedDefaultManagers(final ResourceLocation resLoc) + { + return assertLoaded(resLoc, Minecraft.getInstance().getTextureManager(), Minecraft.getInstance().getResourceManager()); + } + + /** + * Checks whether given resLoc should be loaded into given textureManager as outOfJar or sprite texture + * + * @return valid texture instance (including missing texture) + */ + public static AbstractTexture assertLoaded(final ResourceLocation resLoc, final TextureManager textureManager, final ResourceManager resourceManager) { - final AbstractTexture current = textureManager.getTexture(resourceLocation, null); - if (!IsOurTexture.isOur(current)) + final AbstractTexture current = textureManager.getTexture(resLoc, null); + if (!(resLoc instanceof final OutOfJarResourceLocation outOfJarResLoc)) { - final OutOfJarTexture outOfJarTexture = new OutOfJarTexture(resourceLocation); - textureManager.register(resourceLocation, outOfJarTexture); + // it it's outOfJar then bottom of this method will redirect to sprite if needed + @Nullable + final SpriteTexture sprite = SpriteTexture.checkLoaded(resLoc, textureManager, resourceManager); + return sprite == null ? current : sprite; + } + + if (IsOurTexture.isOur(current)) + { + return current; + } - if (outOfJarTexture.redirectToSprite) + if (current == MissingTextureAtlasSprite.getTexture()) + { + if (!FMLEnvironment.production && !resLoc.getNamespace().equals(BlockUI.MOD_ID)) { - textureManager.register(resourceLocation, new SpriteTexture(resourceLocation)); + throw new IllegalArgumentException("Missing texture: " + resLoc); } + + return current; + } + + final OutOfJarTexture outOfJarTexture = new OutOfJarTexture(outOfJarResLoc); + textureManager.register(outOfJarResLoc, outOfJarTexture); // this causes texture to load + + if (!outOfJarTexture.redirectToSprite) + { + return outOfJarTexture; + } + else + { + final SpriteTexture spriteTexture = new SpriteTexture(outOfJarResLoc); + textureManager.register(outOfJarResLoc, spriteTexture); + return spriteTexture; } } } diff --git a/src/main/java/com/ldtteam/blockui/util/texture/SpriteTexture.java b/src/main/java/com/ldtteam/blockui/util/texture/SpriteTexture.java index a2030ab1..1095db5d 100644 --- a/src/main/java/com/ldtteam/blockui/util/texture/SpriteTexture.java +++ b/src/main/java/com/ldtteam/blockui/util/texture/SpriteTexture.java @@ -13,6 +13,8 @@ import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceMetadata; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.FileNotFoundException; import java.io.IOException; @@ -21,6 +23,7 @@ */ public class SpriteTexture extends AbstractTexture implements Tickable { + private static final Logger LOGGER = LoggerFactory.getLogger(SpriteTexture.class); private final ResourceLocation resourceLocation; private Sprite sprite; @@ -97,15 +100,14 @@ public static SpriteTexture checkLoaded(final ResourceLocation resourceLocation, } // parse mcmeta (or exit) - final Resource resource = OutOfJarResourceLocation.getResourceHandle(resourceLocation, resourceManager); final ResourceMetadata metadata; try { - metadata = resource.metadata(); + metadata = OutOfJarResourceLocation.getResourceHandle(resourceLocation, resourceManager).metadata(); } catch (final IOException e) { - // want to log this, but this is called from frame rendering => log spam + LOGGER.error("Parsing sprite metadata", e); return null; } diff --git a/src/main/resources/assets/blockui/gui/test.xml b/src/main/resources/assets/blockui/gui/test.xml index 16afd8f5..b2f8293e 100644 --- a/src/main/resources/assets/blockui/gui/test.xml +++ b/src/main/resources/assets/blockui/gui/test.xml @@ -7,8 +7,11 @@ + + + -