Jump to content

How to use NBT


SamTebbs33

Recommended Posts

Hi, I've made a block which allows you to set a combination code (specific to the block's location), the code needs to be stored somewhere so that I can then be retrieved and checked later on.

 

At first I used config (.properties extension) files for this, but they proved to be less than reliable (at least with my set-up) so I turned to NBT. I looked up the tutorial on the wiki, but it was less than helpful. It did give some code, but it failed to explain how it worked and what the parameters of the given methods needed to be. I understand that you have to use something called a tag compound, but using these in the method parameters gave an invalid data type error.

 

I would like to be able to create a file called (codes.dat) on mod load and then set values to the given code with the block's world name an coordinates as its key.

 

This is how I did it with the properties extension.

 

Getting and setting a code:

public static String getCode(String world, int x, int y, int z, String path, String filename) throws IOException{
        	
        	Config config = new Config();
        	
        	String code = config.getStringKey(world+"-"+x+","+y+","+z, path, filename);
        	
        	return code;
        	
        }
        
        public static void setCode(String world2, int x, int y, int z, String value, String path, String filename) throws IOException{
        	
        	Config config = new Config();
        	
        	config.setStringKey(world2+"-"+x+","+y+","+z, value, path, filename);
        	        	
        }

 

The setStringKey and getStringKey methods, as referenced to above:

public void setStringKey(String par1key, String par2value, String par3path, String par4filename) throws IOException{

	try{
	Properties prop = new Properties();
	FileInputStream in = new FileInputStream(par3path+par4filename);
	FileOutputStream out = new FileOutputStream(par3path+par4filename);
	prop.load(in);
	prop.setProperty(par1key, par2value);
	prop.store(out, null);
	in.close();

	}catch(IOException e){

		e.printStackTrace();

	}

}

public String getStringKey(String par1key, String par2path, String par3filename) throws IOException{

	try{

	Properties properties = new Properties();
	FileInputStream in = new FileInputStream(par2path+par3filename);
	FileOutputStream out = new FileOutputStream(par2path+par3filename);
	properties.load(new FileInputStream(par2path+par3filename));
	String value = properties.getProperty(par1key);
	properties.store(out, null);
	in.close();
	return value;

	}catch(IOException e){

	e.printStackTrace();
	return "error";

}

 

Using this way only allowed for there to be one entry in the codes.properties file, it was always overridden when setting another blocks code, even if it had different coordinates.

 

How would I be able to solve this, either with NBT or .properties?

 

Thanks in advance!

"Thinking that coding is the nerdy IT guy at work rebooting your computer is like thinking that music is what happens when the piano tuner comes round." - Ed Rex

Link to comment
Share on other sites

If you're using a TileEntity, there's a read/write NBTCompound function.  Just use that.  It's pretty strait forward, actually.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Thanks for the reply.

 

I found those, I just have no idea what to put in the method parameters as the NBTTagCompound.

 

Any ideas?

"Thinking that coding is the nerdy IT guy at work rebooting your computer is like thinking that music is what happens when the piano tuner comes round." - Ed Rex

Link to comment
Share on other sites

Generally you tell the NTB to save/load the same datatype as the object you wish to save.

 

eg, to save an int

nbt.setInteger("myInt", myInt);

to get it back

myInt = nbt.getInteger("myInt");

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Can't you make your own NBT files anyway? Just wondering that is...

I am Mew. The Legendary Psychic. I behave oddly and am always playing practical jokes.

 

I have also found that I really love making extremely long and extremely but sometimes not so descriptive variables. Sort of like what I just did there xD

Link to comment
Share on other sites

Can't you make your own NBT files anyway? Just wondering that is...

 

Yes, but I'm not sure how.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

That is me also. I would like to know.. Knowledge is everything

I am Mew. The Legendary Psychic. I behave oddly and am always playing practical jokes.

 

I have also found that I really love making extremely long and extremely but sometimes not so descriptive variables. Sort of like what I just did there xD

Link to comment
Share on other sites

I've been blindly poking at WorldSaveData, which I think creates nbts, but I'm honestly not sure.

*Checks the save of the one mod that's using that*

Well I'll be.  That's the one, alright!

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

WorldSaveData is where the world data is saved yes :P

 

And there is an interface that adds world data, its like IExtendedEntityProperties except for World data instead xD

I am Mew. The Legendary Psychic. I behave oddly and am always playing practical jokes.

 

I have also found that I really love making extremely long and extremely but sometimes not so descriptive variables. Sort of like what I just did there xD

Link to comment
Share on other sites

Thats a very, VERY horrible way of doing it. It ends up with your data being editable, no matter what extension. Therefore it does not work. What the NBT does is store the variables pretty much only in code. And yes I know there is the .dat file, but not many people bother with editing it, and if they do, they will have to edit it for mod specific data, otherwise they erase that data.

I am Mew. The Legendary Psychic. I behave oddly and am always playing practical jokes.

 

I have also found that I really love making extremely long and extremely but sometimes not so descriptive variables. Sort of like what I just did there xD

Link to comment
Share on other sites

Thanks for the help and replies everyone, I just have one last question.

 

Do you have any idea why the following method always returns false, even if the given NBT key is set and has a value?

 

codeIsSet method

public static boolean codeIsSet(NBTTagCompound nbt, String world, int x, int y, int z){
        	
        	String codeIf = getNBTCode(nbt, world, x, y, z);
        	
        	if(codeIf == null || codeIf == ""){
        		
        		return false;
        		
        	}else if(codeIf != null){
        		
        		return true;
        		
        	}else{
        		
        		return false;
        		
        	}
        	
        }

 

getNBTCode method

public static String getNBTCode(NBTTagCompound nbt, String world, int x, int y, int z)
        {
            String code = nbt.getString(world+"-"+x+","+y+","+z);
            return code;
            
        }

 

If the key is set, the value can be fetched, as shown by the below method in another class

String codeSet = Interlock.getNBTCode(nbt, world, x, y, z);
System.out.println("Set code is: "+codeSet);

 

(The print output is the correct code)

"Thinking that coding is the nerdy IT guy at work rebooting your computer is like thinking that music is what happens when the piano tuner comes round." - Ed Rex

Link to comment
Share on other sites

Are you ever calling nbt.setString(...)?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Yep, using this method

 

public static void setNBTCode(NBTTagCompound nbt, String world, int x, int y, int z, String value)
        {
        	
            nbt.setString(world+"-"+x+","+y+","+z, value);
            
        }

 

I can confirm that the code is being set by using getNBTCode after setting it, I print the returned value and it's correct.

 

I just don't get why my codeIsSet method always returns false, even if the key has a value and is set (as confirmed vie the getNBTCode method and printing the returned value).

"Thinking that coding is the nerdy IT guy at work rebooting your computer is like thinking that music is what happens when the piano tuner comes round." - Ed Rex

Link to comment
Share on other sites

Next question:

 

Where is the nbtcompound tag coming from?

If you're instanciating it yourself, it's not going to save.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Ah, that's the problem then, I'm just setting nbt to an object of the NBTTagCompound class.

 

To what do I set nbt to?

 

Thanks a lot for the help so far.

"Thinking that coding is the nerdy IT guy at work rebooting your computer is like thinking that music is what happens when the piano tuner comes round." - Ed Rex

Link to comment
Share on other sites

Ah, that's the problem then, I'm just setting nbt to an object of the NBTTagCompound class.

 

To what do I set nbt to?

 

Thanks a lot for the help so far.

 

Basically you have to let it get passed from a vanilla class, or get it from an existing entity (server side only).

 

Or you can use IExtendedProperties (basically getting data from an existing entity, but more complicated and not depreciated) or extend WordSaveData

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Ah, that's the problem then, I'm just setting nbt to an object of the NBTTagCompound class.

 

To what do I set nbt to?

 

Thanks a lot for the help so far.

 

Basically you have to let it get passed from a vanilla class, or get it from an existing entity (server side only).

 

Or you can use IExtendedProperties (basically getting data from an existing entity, but more complicated and not depreciated) or extend WordSaveData

 

Its actually IExtendedEntityProperties incase there is a mix up xD IExtendedEntityProperties isn't that hard to mess around with, its actually quite good.

I am Mew. The Legendary Psychic. I behave oddly and am always playing practical jokes.

 

I have also found that I really love making extremely long and extremely but sometimes not so descriptive variables. Sort of like what I just did there xD

Link to comment
Share on other sites

Its actually IExtendedEntityProperties incase there is a mix up xD IExtendedEntityProperties isn't that hard to mess around with, its actually quite good.

 

I got a little lost with it, so I said "fuck it" and went back to getEntityData

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Its actually IExtendedEntityProperties incase there is a mix up xD IExtendedEntityProperties isn't that hard to mess around with, its actually quite good.

 

I got a little lost with it, so I said "fuck it" and went back to getEntityData

 

Thanks to diesieben07 I now get how to use it xD SO if you need help with it I can help xD

I am Mew. The Legendary Psychic. I behave oddly and am always playing practical jokes.

 

I have also found that I really love making extremely long and extremely but sometimes not so descriptive variables. Sort of like what I just did there xD

Link to comment
Share on other sites

Its actually IExtendedEntityProperties incase there is a mix up xD IExtendedEntityProperties isn't that hard to mess around with, its actually quite good.

 

I got a little lost with it, so I said "fuck it" and went back to getEntityData

 

Thanks to diesieben07 I now get how to use it xD SO if you need help with it I can help xD

 

Not my primary focus right now, but thanks. :)

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

How would I get the appropriate NBTTag?

 

I looked through some of the vanilla classes and found a method called getNBTTagCompound which returned a tag for the player, how would I do this for a tile entity so that I can pass it into the writeToNBT methods?

 

I'm really lost when it comes to what an NBT tag is et.c :P

"Thinking that coding is the nerdy IT guy at work rebooting your computer is like thinking that music is what happens when the piano tuner comes round." - Ed Rex

Link to comment
Share on other sites

God, this is confusing :P

 

Anyway, I've re-done some of my code, so that the readFromNBT and writeFromNBT methods are in my tile entity class (I saw this in the TileEntityFurnace class). When the method is calles, they should set the block's code to the code variable in the TileEntityNumpad class.

When are the readFromNBT and writeToNBT methods called? I'm wondering this as I would like them to be called when the player sets the block's code via its GUI.

 

My TileEntityNumpadBlock class

package vivadaylight3.interlock.tileentities.numpadblock;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;

public class TileEntityNumpadBlock extends TileEntity {

public static String code;
public static String codeSet;

public void writeToNBT(NBTTagCompound nbt){

	super.writeToNBT(nbt);
	nbt.setString("Code", code);

}

public void readFromNBT(NBTTagCompound nbt){

	super.readFromNBT(nbt);
	codeSet = nbt.getString("Code");

}

public static String getCode(){

	return codeSet;

}

}

 

Changed codeIsSet method

public static boolean codeIsSet(NBTTagCompound nbt, String world, int x, int y, int z){
        	
        	String codeIf = TileEntityNumpadBlock.getCode();
        	
        	if(codeIf == null || codeIf == ""){
        		
        		return false;
        		
        	}else if(codeIf != null){
        		
        		return true;
        		
        	}else{
        		
        		return false;
        		
        	}
        	
        }

 

Code which sets the code variable in the tile entity class

if(codeSize == 4){
            		
            		// I'm setting the TileEntityNumpadBlock code variable here, so it can be written to NBT.
				TileEntityNumpadBlock numpad = new TileEntityNumpadBlock();
				numpad.code = code; // Code holds the user-entered code, numpad.code is the code to be written to NBT.
    			code = null;
            	codeSize = 0;
            	mc.displayGuiScreen((GuiScreen)null);
            		
            	}else{
            		
            		System.out.println("Code size is not 4");
            		
            	}

 

Code that checks if the user-entered code is the one that has been written to NBT

TileEntityNumpadBlock numpad = new TileEntityNumpadBlock();
            		
            		String codeSet = numpad.getCode();
            		
            		if(codeSet==code){
            			
            			// Open door code here.
            			
            		}

 

I'm sorry if I'm not being clear, it's just that this is all very confusing. I'd really appreciate a quick summary of how NBT works and how one reads, creates .dat files and writes to it.

 

Anyway, what I really need to know is how I can set it so that each code is specific to each placed numpad and when the readFromNBT and writeToNBT methods are called.

"Thinking that coding is the nerdy IT guy at work rebooting your computer is like thinking that music is what happens when the piano tuner comes round." - Ed Rex

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.