Closed CJenkins93 closed 5 years ago
That's the XP Drain's issue - they're giving us an invalid FluidStack
, seems it's missing a Fluid
name or they're giving a Fluid
that's not the chosen one from the registry
Hi, OpenMods dev here. This is probably caused by some other mod making stupid things with fluid registry, but something caught my attention: how could one even create FluidStack
that references non-chosen fluid? FluidStack
s points to delegate, which is supposed to always resolve (by name) to primary ones. AFAIK the main idea is to create FluidStack
with your instance on Fluid
and let Forge resolve it.
I agree it seems to be caused by some other mod doing stupid things with the fluid registry, though I am not sure there is a good way for us to handle it given what we are calling that is causing the crash to happen.
Based on the stack trace the code that is causing a crash (some parts are stripped out to better portray where the crash is happening)
void addFluidStack(FluidStack stack) {
if (stack != null) {
stack.writeToNBT(new NBTTagCompound()); //This call causes the null pointer
}
}
I believe this is our call that "causes" the crash. The line in FluidStack#writeToNBT
that the crash is happening in is:
nbt.setString("FluidName", FluidRegistry.getFluidName(getFluid()));
//And then the getFluidName which is what returns null causing the null pointer
public static String getFluidName(Fluid fluid) {
return fluids.inverse().get(fluid);
}
My best idea why this may cause a crash (though this is mainly just speculation):
A relatively quick way we probably could test if this is indeed the case is that after you register your liquid xp you then store in your cached Fluid object FluidRegistery.getFluid("xpjuice")
instead of your own object. If it stops crashing then my theory is probably right about what is happening.
If not I am at a loss as calling FluidStack#writeToNBT
on a non null fluidstack should not be causing a crash.
This analysis is not taking into account delegates: when fluid stack is created, Forge lookups delegate for given fluid (which is assigned on registration). When proper set of fluids is chosen, delegates are updated to point to selected instance, based on fluid id. So FluidStack.getFluid
does not return instance that is passed in constructor, but one that is selected based on fluid name - in theory name lookup should always succeed.
Now, I already know there is other mod in that crash report that registers same fluid id, but I never was able to reproduce that crash, no matter which instance was selected.
Considering access restriction on most parts of this flow, it can be only broken by irresponsible use of reflection/coremods, some weird level.dat
corruption that causes delegate rebind
to update value to null
and/or something causing delegate rebind
to not run.
EDIT: There is probably no need (or even sane way) to protect against this crash, as registry is already in invalid state.
Ya I haven't done much with the fluid registry personally so I had not realized FluidStack creation already ensures it is using the correct Fluid object.
Fluid delegates help in a lot of cases, though I'm fairly sure I've seen edge cases for it failing. Just can't remember off the top of my head. Could be just with instance comparisons to the non-default fluid though.
As for getting it to trigger yours not being default, you need to have the other mod installed without yours, create/load the world, then save, add your mod, and reopen - then the other is used as the default.
Please use the search functionality before reporting an issue. Also take a look at the closed issues!
Issue description:
Basic fluid tank crashes server upon standing on an open blocks 'xp drain' placed on top.
Steps to reproduce:
Version (make sure you are on the latest version before reporting):
Forge: 1.12.2-14.23.5.2836-universal Mekanism: 1.12.2-9.7.4.375 Mekanism Generators: 1.12.2-9.7.4.375
If a (crash)log is relevant for this issue, link it here: (It's almost always relevant)
https://pastebin.com/6Vdt81DF