Datafixers.Dynamic can't convert boolean values. always 'false'
I found a problem with the class:
com.mojang.datafixers.Dynamic
When i try to convert a boolean value from a JsonElement it always turn 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 an 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}
Environment
Java information:
$ java -version Java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0_171-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
System information:
$ systeminfo
OS Name: Microsoft Windows 10 Pro
OS Version: 10.0.17134 N/A Build 17134
System Type: x64-based PC
Processor(s): 1 Processor(s) Installed.
[01]: Intel64 Family 6 Model 158 Stepping 9 GenuineIntel ~2808 Mhz
Total Physical Memory: 16,337 MB
Created Issue:
Datafixers.Dynamic can't convert boolean values. always 'false'
I found a problem with the class:
com.mojang.datafixers.DynamicWhen i try to convert a boolean value from a JsonElement it always turn 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 an json object it will always turn up in the level.dat as:
useCaves: 0 useRavines: 0When you set the generator-settings to
{"useCaves":true,"useRavines":false}Environment
Java information:
$ java -version Java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0_171-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)System information:
$ systeminfo OS Name: Microsoft Windows 10 Pro OS Version: 10.0.17134 N/A Build 17134 System Type: x64-based PC Processor(s): 1 Processor(s) Installed. [01]: Intel64 Family 6 Model 158 Stepping 9 GenuineIntel ~2808 Mhz Total Physical Memory: 16,337 MB
Does this still apply to 1.15.2?
@miwob Yup just tested it again, the same problem in 1.15.2
DataFixerUpper has been open-sourced, so you might also want to post this at https://github.com/mojang/datafixerupper/issues (or submit a pull request if you know how to fix it).
@pokechu22 Was just about to fork it to try to resolve the issue. 😀 Will create the issue now 😁
@pokechu22 As I commented on https://github.com/Mojang/DataFixerUpper/issues/44 the issue is internal with the NBT library. Maybe it's correct to let it be open here too.
I have suggested open-sourcing the NBT library for Minecraft, it's also a really requested library as almost all game-related storing of data is NBT.
Is this still an issue in 1.19.3?