From 6501bef0b61b9b67d1ccf000297ebda4ffbb2c50 Mon Sep 17 00:00:00 2001 From: mezz Date: Sun, 30 Oct 2016 19:06:44 -0700 Subject: [PATCH] Fix #553 Improve stability of tooltip gathering at startup. --- .../ingredients/ItemStackRenderer.java | 24 +++++- .../java/mezz/jei/util/FakeClientPlayer.java | 31 +++++++ .../java/mezz/jei/util/FakeClientWorld.java | 81 +++++++++++++++++++ .../mezz/jei/util/IngredientListElement.java | 10 +-- 4 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 src/main/java/mezz/jei/util/FakeClientPlayer.java create mode 100644 src/main/java/mezz/jei/util/FakeClientWorld.java diff --git a/src/main/java/mezz/jei/plugins/vanilla/ingredients/ItemStackRenderer.java b/src/main/java/mezz/jei/plugins/vanilla/ingredients/ItemStackRenderer.java index 523931c26..009f1638a 100644 --- a/src/main/java/mezz/jei/plugins/vanilla/ingredients/ItemStackRenderer.java +++ b/src/main/java/mezz/jei/plugins/vanilla/ingredients/ItemStackRenderer.java @@ -1,13 +1,18 @@ package mezz.jei.plugins.vanilla.ingredients; import javax.annotation.Nullable; +import java.util.Collections; import java.util.List; import mezz.jei.api.ingredients.IIngredientRenderer; +import mezz.jei.util.ErrorUtil; +import mezz.jei.util.FakeClientPlayer; +import mezz.jei.util.Log; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.text.TextFormatting; @@ -26,7 +31,24 @@ public void render(Minecraft minecraft, int xPosition, int yPosition, @Nullable @Override public List getTooltip(Minecraft minecraft, ItemStack ingredient) { - List list = ingredient.getTooltip(minecraft.thePlayer, minecraft.gameSettings.advancedItemTooltips); + EntityPlayer player = minecraft.thePlayer; + if (player == null) { + player = FakeClientPlayer.getInstance(); + } + + List list; + try { + list = ingredient.getTooltip(player, minecraft.gameSettings.advancedItemTooltips); + } catch (RuntimeException e) { + String itemStackInfo = ErrorUtil.getItemStackInfo(ingredient); + Log.error("Failed to get tooltip: {}", itemStackInfo, e); + return Collections.emptyList(); + } catch (LinkageError e) { + String itemStackInfo = ErrorUtil.getItemStackInfo(ingredient); + Log.error("Failed to get tooltip: {}", itemStackInfo, e); + return Collections.emptyList(); + } + for (int k = 0; k < list.size(); ++k) { if (k == 0) { list.set(k, ingredient.getRarity().rarityColor + list.get(k)); diff --git a/src/main/java/mezz/jei/util/FakeClientPlayer.java b/src/main/java/mezz/jei/util/FakeClientPlayer.java new file mode 100644 index 000000000..ffe38bbd3 --- /dev/null +++ b/src/main/java/mezz/jei/util/FakeClientPlayer.java @@ -0,0 +1,31 @@ +package mezz.jei.util; + +import java.util.UUID; + +import com.mojang.authlib.GameProfile; +import net.minecraft.entity.player.EntityPlayer; + +public class FakeClientPlayer extends EntityPlayer { + public static FakeClientPlayer INSTANCE; + + public static FakeClientPlayer getInstance() { + if (INSTANCE == null) { + INSTANCE = new FakeClientPlayer(); + } + return INSTANCE; + } + + private FakeClientPlayer() { + super(FakeClientWorld.getInstance(), new GameProfile(new UUID(0, 0), "JEI_Fake")); + } + + @Override + public boolean isSpectator() { + return false; + } + + @Override + public boolean isCreative() { + return false; + } +} diff --git a/src/main/java/mezz/jei/util/FakeClientWorld.java b/src/main/java/mezz/jei/util/FakeClientWorld.java new file mode 100644 index 000000000..9b1179904 --- /dev/null +++ b/src/main/java/mezz/jei/util/FakeClientWorld.java @@ -0,0 +1,81 @@ +package mezz.jei.util; + +import javax.annotation.Nullable; + +import net.minecraft.profiler.Profiler; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.DimensionType; +import net.minecraft.world.GameType; +import net.minecraft.world.World; +import net.minecraft.world.WorldProvider; +import net.minecraft.world.WorldSettings; +import net.minecraft.world.WorldType; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.EmptyChunk; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.storage.ISaveHandler; +import net.minecraft.world.storage.SaveDataMemoryStorage; +import net.minecraft.world.storage.SaveHandlerMP; +import net.minecraft.world.storage.WorldInfo; + +public class FakeClientWorld extends World { + private static final WorldSettings worldSettings = new WorldSettings(0, GameType.SURVIVAL, false, false, WorldType.DEFAULT); + private static final WorldInfo worldInfo = new WorldInfo(worldSettings, "jei_fake"); + private static final ISaveHandler saveHandler = new SaveHandlerMP(); + private static final WorldProvider worldProvider = new WorldProvider() { + @Override + public DimensionType getDimensionType() { + return DimensionType.OVERWORLD; + } + }; + private static FakeClientWorld INSTANCE; + + public static FakeClientWorld getInstance() { + if (INSTANCE == null) { + INSTANCE = new FakeClientWorld(); + } + return INSTANCE; + } + + private FakeClientWorld() { + super(saveHandler, worldInfo, worldProvider, new Profiler(), true); + this.provider.registerWorld(this); + this.mapStorage = new SaveDataMemoryStorage(); + } + + @Override + public BlockPos getSpawnPoint() { + return new BlockPos(0, 0, 0); + } + + @Override + protected IChunkProvider createChunkProvider() { + return new IChunkProvider() { + @Nullable + @Override + public Chunk getLoadedChunk(int x, int z) { + return new EmptyChunk(FakeClientWorld.this, x, z); + } + + @Override + public Chunk provideChunk(int x, int z) { + return new EmptyChunk(FakeClientWorld.this, x, z); + } + + @Override + public boolean unloadQueuedChunks() { + return false; + } + + @Override + public String makeString() { + return ""; + } + }; + } + + @Override + protected boolean isChunkLoaded(int x, int z, boolean allowEmpty) { + return false; + } +} diff --git a/src/main/java/mezz/jei/util/IngredientListElement.java b/src/main/java/mezz/jei/util/IngredientListElement.java index 1e7077feb..e2a5638ce 100644 --- a/src/main/java/mezz/jei/util/IngredientListElement.java +++ b/src/main/java/mezz/jei/util/IngredientListElement.java @@ -120,15 +120,7 @@ protected IngredientListElement(V ingredient, IIngredientHelper ingredientHel } private static String getTooltipString(T ingredient, IIngredientRenderer ingredientRenderer, String modId, String modName, String displayName) { - List tooltip; - try { - tooltip = ingredientRenderer.getTooltip(Minecraft.getMinecraft(), ingredient); - } catch (RuntimeException ignored) { - return ""; - } catch (LinkageError ignored) { - return ""; - } - + List tooltip = ingredientRenderer.getTooltip(Minecraft.getMinecraft(), ingredient); String tooltipString = Joiner.on(' ').join(tooltip).toLowerCase(); tooltipString = removeChatFormatting(tooltipString); tooltipString = tooltipString.replace(modId, "");