Towdium / JustEnoughCalculation

A simple minecraft mod help you calculate the cost for recipes
Other
54 stars 41 forks source link

[1.16.5] Crash when hovering the GUI in Chroma Sky 2.0 #115

Closed Windorain closed 2 years ago

Windorain commented 2 years ago

the calculator have added the recipe of Kiln Brick and relative log is provided minecraft-exported-crash-info-2022-08-21T09-41-54.zip

Windorain commented 2 years ago

It comes when hovering the items added by Chroma Sky itself, such as compressed sand and so on

jie65535 commented 2 years ago

I encountered the same problem as you. It seems that the problem was fixed in the 1.18 branch, but this exception still exists in the 1.16 branch.

我遇到了和你一样的问题,该问题似乎在1.18的分支中修复了,但是在1.16的分支中任然存在这个异常。


1.16


    // MOD NAME
    @Nullable
    public static String getModName(Item item) {
        ResourceLocation tmp = item.getRegistryName();
        if (tmp == null) return null;
        String id = tmp.getNamespace();
        return id.equals("minecraft") ? "Minecraft" : getModName(id);
    }

    static String getModName(String id) {
        return ModList.get().getModContainerById(id)
                .orElseThrow(() -> new RuntimeException("Internal error"))
                .getModInfo().getDisplayName();
    }

    public static File config() {
        return new File(FMLPaths.CONFIGDIR.get().toFile(), JustEnoughCalculation.MODID);
    }

    public static String getModName(Fluid fluid) {
        FluidStack fs = new FluidStack(fluid, 1000);
        String name = fs.getDisplayName().getString(); //.getFormattedText();
        if (name.equals("lava") || name.equals("water")) return "Minecraft";
        ResourceLocation texture = fluid.getAttributes().getStillTexture(fs);
        if (texture == null) return "Unknown";
        else return getModName(texture.getNamespace());
    }

1.18

    // MOD NAME
    static <T> Optional<String> getModNameInternal(Registry<T> registry, T t) {
        return Optional.ofNullable(registry.getKey(t))
                .map(ResourceLocation::getNamespace)
                .map(s -> ResourceLocation.DEFAULT_NAMESPACE.equals(s) ? "Minecraft" : getModName(s));
    }

    static String getModName(String id) {
        return Platform.getOptionalMod(id)
                .map(Mod::getName)
                .orElseGet(() -> WordUtils.capitalize(id.replace("_", " ")));
    }

    public static String getModName(Item item) {
        return getModNameInternal(Registry.ITEM, item)
                .orElse("Unknown");
    }

    public static String getModName(Fluid fluid) {
        return getModNameInternal(Registry.FLUID, fluid)
                .orElseGet(() -> getModNameFromTexture(fluid));
    }

    static String getModNameFromTexture(Fluid fluid) {
        FluidStack fs = FluidStack.create(fluid, 1000);
        String name = fs.getName().getString(); //.getFormattedText();
        if (name.equals("lava") || name.equals("water")) return "Minecraft";
        TextureAtlasSprite texture = FluidStackHooks.getStillTexture(fluid);
        if (texture == null) return "Unknown";
        else return getModName(texture.getName().getNamespace());
    }
Windorain commented 2 years ago

看错误报告似乎是调用getModName函数出错了,但我还是不知道该怎么做,因为我并不了解Minecraft的底层机制,.

jie65535 commented 2 years ago

看错误报告似乎是调用getModName函数出错了,但我还是不知道该怎么做,因为我并不了解Minecraft的底层机制,. Looking at the error report, it seems that there is an error in calling the getmodname function, but I still don't know what to do, because I don't know the underlying mechanism of minecraft

他以前写的代码,遇到获取不到mod来源的直接抛异常,新的代码只会返回未知来源,我正在尝试克隆下来修复一下(就是把新代码搬到旧分支),届时我再回复你结果。 I am trying to move the new code to the old branch, and I will reply later.

Windorain commented 2 years ago
    static String getModName(String id) {
        return ModList.get().getModContainerById(id)
                .orElseThrow(() -> new RuntimeException("Internal error"))
                .getModInfo().getDisplayName();
    }

根据你的提示仔细,我看明白了. 如果这样的话简单地修改一下似乎很简单,直接新建一个分支统一以"Unknown Source"来替代就可以了. 只不过这样并没有解决本质问题, 即为什么会获取不到Mod名字

jie65535 commented 2 years ago

不知道,我猜因为那些物品是整合包作者用脚本加的,没有更多详细信息。 我不是很关心它根本问题怎么解决,我只想在这个套娃整合包正常使用合成计算器。

jie65535 commented 2 years ago
Index: src/main/java/me/towdium/jecalculation/utils/Utilities.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/me/towdium/jecalculation/utils/Utilities.java b/src/main/java/me/towdium/jecalculation/utils/Utilities.java
--- a/src/main/java/me/towdium/jecalculation/utils/Utilities.java   (revision f5dae9454e5eb7997be2ca577accf9a170ef680b)
+++ b/src/main/java/me/towdium/jecalculation/utils/Utilities.java   (revision 31a37ce4564a235452b8c2d00fd76f096209888f)
@@ -17,6 +17,7 @@
 import net.minecraft.util.ResourceLocation;
 import net.minecraftforge.client.MinecraftForgeClient;
 import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fml.ModContainer;
 import net.minecraftforge.fml.ModList;
 import net.minecraftforge.fml.loading.FMLPaths;
 import org.apache.commons.io.FileUtils;
@@ -90,9 +91,9 @@
     }

     static String getModName(String id) {
-        return ModList.get().getModContainerById(id)
-                .orElseThrow(() -> new RuntimeException("Internal error"))
-                .getModInfo().getDisplayName();
+        ModContainer mod = ModList.get().getModContainerById(id).orElse(null);
+        if (mod == null) return "Unknown";
+        else return mod.getModInfo().getDisplayName();
     }

     public static File config() {

Unknown Mod Name

@1652518008
JustEnoughCalculation-1.16.5-3.8.6-fixed.jar.zip

Windorain commented 2 years ago

Amazing! 确实已经修复了这个问题. 非常感谢你的帮助!

jie65535 commented 2 years ago

我不建议关闭这个issue,我只是修改代码并且临时编译了一个可用版本,并没有提交PR。仓库中仍然存在该问题。 I don't recommend closing this issue, I just modified the code and temporarily compiled a working version without submitting a PR. The issue still exists in the repository.

Windorain commented 2 years ago

你说的有道理,不过我似乎又崩溃了一次,还是计算器GUI划过的问题 然后我再重新启动HTML启动器, Win10判定有病毒.

jie65535 commented 2 years ago

崩溃报告发一下

Windorain commented 2 years ago

minecraft-exported-crash-info-2022-08-21T19-13-22.zip

jie65535 commented 2 years ago

你用的是 java 1.8 吗?如果是的话,应该是因为代码里用了 java 11 的方法有关。

Windorain commented 2 years ago

确实是,因为里面有个模组不支持java17,所以我退回了java1.8 我现在就下载中间的版本试一试

jie65535 commented 2 years ago
Index: src/main/java/me/towdium/jecalculation/data/label/ILabel.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/me/towdium/jecalculation/data/label/ILabel.java b/src/main/java/me/towdium/jecalculation/data/label/ILabel.java
--- a/src/main/java/me/towdium/jecalculation/data/label/ILabel.java (revision 31a37ce4564a235452b8c2d00fd76f096209888f)
+++ b/src/main/java/me/towdium/jecalculation/data/label/ILabel.java (revision 51827080f9e2c34657de100b9cba308176a9086d)
@@ -461,8 +461,8 @@
                     d = tmp;
                 }
                 if (a.isInstance(c) && b.isInstance(d) && p.test(c, d)) {
-                    long amountC = c.isPercent() ? c.getAmount() : Math.multiplyExact(c.getAmount(), 100);
-                    long amountD = d.isPercent() ? d.getAmount() : Math.multiplyExact(d.getAmount(), 100);
+                    long amountC = c.isPercent() ? c.getAmount() : c.getAmount() * 100;
+                    long amountD = d.isPercent() ? d.getAmount() : d.getAmount() * 100;
                     long amount = Math.addExact(amountC, amountD);
                     long amountI = (amount > 0 ? Math.addExact(amount, 99) : Math.subtractExact(amount, 99)) / 100;
                     if (amount == 0) return EMPTY;

JustEnoughCalculation-1.16.5-3.8.6-fixed.jar.zip

我修复了这个兼容问题,你可以再尝试一下 @1652518008

Windorain commented 2 years ago

目前来看一切正常,你的代码修改是有效的. 非常感谢你的帮助!

yzl210 commented 2 years ago

这个问题的根源是因为在没有获取到mod容器时会抛出异常,新版新增一个把namespace改成mod name的方法,而且现在在这些方法都没获取成功后,会返回Unknown,不会抛出异常

yzl210 commented 2 years ago

Fixed

yzl210 commented 2 years ago
    static String getModName(String id) {
        return ModList.get().getModContainerById(id)
                .orElseThrow(() -> new RuntimeException("Internal error"))
                .getModInfo().getDisplayName();
    }

根据你的提示仔细,我看明白了. 如果这样的话简单地修改一下似乎很简单,直接新建一个分支统一以"Unknown Source"来替代就可以了. 只不过这样并没有解决本质问题, 即为什么会获取不到Mod名字

这个问题应该也解决了

jie65535 commented 2 years ago

后面还有一个问题,Java 1.8 没有 Math.multiplyExact 这个方法,所以用 Java 1.8 运行,遇到的时候就会崩溃。我只是简单的修改成普通的乘法,你可以看看如何优化以使1.8兼容。

yzl210 commented 2 years ago

Java 8中是有multiplyExact方法的,只是没有multiplyExact(long, int)

yzl210 commented 2 years ago

正常编译的情况下都是会自动使用multiplyExact(long, long)的

jie65535 commented 2 years ago

噢,原来如此,我不是很了解Java,不好意思。没问题就行。