DataFixerUpper
DataFixerUpper copied to clipboard
Datafixers.Dynamic can't convert boolean values. always 'false'
Issue from https://bugs.mojang.com/browse/MC-135413
I found a problem with the class: com.mojang.datafixers.Dynamic
When I try to convert a boolean value from a JsonElement it always turns up as false.
Base a basic UnitTest to explain my scenario.
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.mojang.datafixers.Dynamic;
import com.mojang.datafixers.types.JsonOps;
import net.minecraft.server.v1_13_R1.DynamicOpsNBT;
import net.minecraft.server.v1_13_R1.NBTTagCompound;
import org.junit.Test;
import static org.junit.Assert.*;
public class DynamicTest {
@Test
public void convertTest() {
JsonObject element = new JsonObject();
element.addProperty("string", "hello world");
element.addProperty("boolean_true", true);
element.addProperty("boolean_false", false);
element.addProperty("byte_1", (byte) 1);
element.addProperty("byte_0", (byte) 0);
element.addProperty("double", 10.5);
element.addProperty("int", 11);
element.addProperty("long", 12L);
element.addProperty("float", 13.5F);
element.addProperty("short", (short) 100);
JsonObject properties = new JsonParser().parse(element.toString()).getAsJsonObject();
assertEquals("hello world", properties.get("string").getAsString());
assertEquals(true, properties.get("boolean_true").getAsBoolean());
assertEquals(false, properties.get("boolean_false").getAsBoolean());
assertEquals((byte) 1, properties.get("byte_1").getAsByte());
assertEquals((byte) 0, properties.get("byte_0").getAsByte());
assertEquals(10.5, properties.get("double").getAsDouble(), 10.5);
assertEquals(11, properties.get("int").getAsInt());
assertEquals(12L, properties.get("long").getAsLong());
assertEquals(13.5F, properties.get("float").getAsFloat(), 13.5F);
assertEquals((short) 100, properties.get("short").getAsShort());
NBTTagCompound dynamic = ((NBTTagCompound) Dynamic.convert(JsonOps.INSTANCE, DynamicOpsNBT.a, properties));
assertEquals("hello world", dynamic.getString("string"));
assertEquals(true, dynamic.getBoolean("boolean_true")); // Fails here?? Dynamic.class can't convert true to a boolean.
assertEquals(false, dynamic.getBoolean("boolean_false"));
assertEquals((byte) 1, dynamic.getByte("byte_1"));
assertEquals((byte) 0, dynamic.getByte("byte_0"));
assertEquals(10.5, dynamic.getDouble("double"), 10.5);
assertEquals(11, dynamic.getInt("int"));
assertEquals(12L, dynamic.getLong("long"));
assertEquals(13.5F, dynamic.getFloat("float"), 13.5F);
assertEquals((short) 100, dynamic.getShort("short"));
}
}
The result when we run the UnitTest is
java.lang.AssertionError:
Expected :true
Actual :false
<Click to see difference>
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.failNotEquals(Assert.java:647)
at org.junit.Assert.assertEquals(Assert.java:128)
at org.junit.Assert.assertEquals(Assert.java:147)
at DynamicTest.convertTest(DynamicTest.java:43) // The line is commented in the example above.
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Where will this bug be a problem?
When you set the generator-settings in the server.properties to a JSON object it will always turn up in the level.dat as:
useCaves: 0
useRavines: 0
When you set the generator-settings to {"useCaves":true,"useRavines":false}
Looking at this Unit Test I wrote in 2018, I can conclude the issue is not with DataFixerUpper but with the NBT logic in Minecraft, sadly :/
Waiting to close this issue to a maintainer can answer how to proceed from here?
Is it time for Mojang to open-source the internal NBT library?
As far as I can identify the problem is with NBTTagCompound, when calling getBoolean it looks for 1 or 0 as boolean, but the value is stored as a string "false" or "true".