Jump to content

[1.12.2] serializeNBT() throws "Null string not allowed"


AuraXP

Recommended Posts

Hello there,

I want to test the save/write function from the nbt feature of a player simplyfied with this:

 

	@SubscribeEvent
	public void onPlayerLoggedInEvent(PlayerLoggedInEvent event) {
                //load stuff with deserializeNBT()
                //print original nbt
                //change nbt to something different

		event.player.serializeNBT(); //<-- exception here

                //deserializeNBT stuff again
                //read changes and print
	}

But I'll get a NullPointerException:

java.lang.NullPointerException: Null string not allowed
	at java.util.Objects.requireNonNull(Unknown Source)
	at net.minecraft.nbt.NBTTagString.<init>(NBTTagString.java:20)
	at net.minecraft.nbt.NBTTagCompound.setString(NBTTagCompound.java:172)
	at net.minecraft.entity.Entity.serializeNBT(Entity.java:3574)
...

I attached the capability normally to the player with the AttachCapabilitiesEvent.

The provider also looks quite normal to me:

	private final ITeleportCapability cap;
	private static final DefaultTeleportStorage<ITeleportCapability> STORAGE 
                   = new DefaultTeleportStorage<>();
	
	@Override
	public NBTBase serializeNBT() {
		return STORAGE.writeNBT(CAPABILITY_TELEPORT, cap, null);
	}

 The writeNBT method from DefaultTeleportStorage looks like this:

	@Override
	public NBTBase writeNBT(Capability<T> capability, T instance, EnumFacing side) {
		if((instance instanceof ITeleportCapability) == false) {
			throw new RuntimeException(instance.getClass().getName() 
                         + "does not implement ITeleportCapability");
		}
		
		NBTTagCompound nbt = new NBTTagCompound();
		ITeleportCapability cap = (ITeleportCapability) instance;
		nbt.setTag("integerPartition", new NBTTagInt(instance.getFlags()));
		
		return nbt;
	}

It fells like it isn't like a problem on the setup of the capability but more of how I use it.
Does somebody know what I am doing wrong?

Thank you in advantage!

Link to comment
Share on other sites

25 minutes ago, diesieben07 said:

Players don't have an entity-type ID, so serializeNBT does not work for them.

What are you trying to achieve?

I attached a capability to the player entity and I want to mantain them beyond runtime.
I read that the INBTSerializable interface is meant to do exactly that.
You said that players don't have entity-type ID, so what if I simply cast the player to entity type? <= [EDIT]: doesn't work

[EDIT 2]:
The cast may not work because of the ID will not be autofilled I guess.
Maybe something like this would work:

EntityList.createEntityByIDFromName(resource, world)


But I don't know how to fille the resource to refer to the player entity.
For a sheep it would look like this:

EntityList.createEntityByIDFromName(new ResourceLocation("minecraft", "sheep"), world)

 

But changing "sheep" with "player" doesn't seem like the right thing to do.

Edited by AuraXP
Link to comment
Share on other sites

52 minutes ago, diesieben07 said:

As long as the ICapabilityProvider you attach implements INBTSerializable, you do not need to do anything else. Your capability will be automatically serialized when the attached entity is saved to disk.

Ok, but deserializing has to be done on the other hand?
Because the capability will not load the values from my example from the previous runtime by simply calling getCapability just yet.

Link to comment
Share on other sites

14 minutes ago, diesieben07 said:

INBTSerializable has two methods, one for reading and one for writing.

You have to implement both properly on your ICapabilityProvider.

I thought I did that the right way.
In total the provider implements the interface like this:

	public static class TeleportBreakCapabilityProvider implements ICapabilityProvider, INBTSerializable<NBTBase> {

		private final ITeleportCapability cap;
		private static final DefaultTeleportStorage<ITeleportCapability> STORAGE = new DefaultTeleportStorage<>();
		
		public TeleportBreakCapabilityProvider() {
			this.cap = new TeleportCapability();
		}
		
		@Override
		public NBTBase serializeNBT() {
			return STORAGE.writeNBT(CAPABILITY_TELEPORT, cap, null);
		}

		@Override
		public void deserializeNBT(NBTBase nbt) {
			STORAGE.readNBT(CAPABILITY_TELEPORT, cap, null, nbt);
		}
      	...
    }

I am storing only one integer called "teleportBreak" in the nbt in DefaultTeleportStorage.
This class has been implemented like this:
 

public class DefaultTeleportStorage <T extends ITeleportCapability> implements Capability.IStorage<T>{

	@Override
	public NBTBase writeNBT(Capability<T> capability, T instance, EnumFacing side) {
		NBTTagCompound nbt = new NBTTagCompound();
		ITeleportCapability cap = (ITeleportCapability) instance;
		nbt.setInteger("teleportBreak", cap.getFlags());
		
		return nbt;
	}

	@Override
	public void readNBT(Capability<T> capability, T instance, EnumFacing side, NBTBase nbt) {
		NBTTagCompound tags = new NBTTagCompound();
		ITeleportCapability cap = capability.cast(instance);
		cap.setFlags(tags.getInteger("teleportBreak"));
	}
}

It looks pretty normal to me, so I don't know what's the matter with it not working properly.

Link to comment
Share on other sites

32 minutes ago, diesieben07 said:

In readNBT you completely ignore the data that you're told to read from and instead create a new, empty tag compound and restore your data from that.

Oh, I am sorry I did not see that.


This fixed the problem.

Thank you for being the one who helped me out, I really appreciate it. :)


This topic is solved.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.