Jump to content

[1.7.10][semi-solved] Constructing a list of subItems on the server


wesserboy

Recommended Posts

Hello everyone, I am having yet another problem with packets, but since this problem isn't like my previous ones i decided to make a new topic.

 

In my mod, the first time any client joins a new server, I need to send quite a lot of data from the server to that client and from that client back to the server.

If you want to know why I am doing this you can read the old topic here:

http://www.minecraftforge.net/forum/index.php/topic,32902.0.html

 

The thing diesieben07 had warned me for in the previous topic has happened, the payload of the packet I am sending to the server is too high.

To resolve this issue I want to pre-calculate the payload of my packet, and if it is too high i will send an early packet and start constructing a new one (if that makes any sense, but i feel like i'm failing at explaining what i mean here)

 

I am currently using the following code to calculate the payload:

public int getPayload(List<ItemStack> itemStacks){
	int payload = 1;

	if(itemStacks.size() <= Byte.MAX_VALUE){
		payload += 1;
	}else if(itemStacks.size() <= Short.MAX_VALUE){
		payload += 2;
	}else{
		payload += 4;
	}

	payload += itemStacks.size() * 5;

	for(int i = 0; i < itemStacks.size(); i++){
		if (itemStacks.get(i).getItem().isDamageable() || itemStacks.get(i).getItem().getShareTag()){
			payload += 3;
                NBTTagCompound compound = itemStacks.get(i).stackTagCompound;
                if(compound != null){
                	payload += compound.func_150296_c().size() * 6;
                }
            }
	}

	return payload;
}

 

from what i've seen i figure that the payload of a packet is equal to the amount of bytes in the byteBuffer.

keeping this in mind i calculated the values to use in the calculations, but if i am wrong somewhere please correct me, I am not very familiar with packets and bytebuffers.

 

In my packet I am first sending a byte, this is why i start with payload = 1.

Then, depending on the size of the value, i am sending a byte, a short or an integer. This is what the if statement is for.

After that is done i am sending an array of itemStacks, i found that two shorts and a byte are used to write an itemStack, and this is why i am using *5.

 

For some itemStacks NBTTagCompounds are written, the if statement i am using in the for-loop is the same one vanilla uses to determine if the compound should be written or not.

However, i feel like my calculations for the payload size of a compound are not right. I wrote that code yesterday before i went to bed, and i really don't know anymore where i got the +3 and the *6 from...

 

I am using 23767 as the max payload value, i found this value in the C17PacketCustomPayload class, but if this is wrong be sure to correct me  ;)

 

I assume my calculations are right up until the point of the NBTTagCompound, so my question is if someone knows how i can properly calculate the payload of an NBTTagCompound, or if there is a better way to go about splitting up my packets.

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

Sorry but I read your other thread this can be done with more simple payloads. The server already knows all the items, and yes you're right that it is easier to pick sub-type on the client. But you can still get a list on the server by going through the item list once and querying a client to get info on the subtypes.

 

The only code you should have following logic:

1) server goes through the item registry and sends packet to client indicating which item (the payload can simply be the integer ID from the registry)

3) client checks whether the item has subtypes and if it does it does the getSubItems() and finds the size of sub-type list.

4) client sends packet to server indicating the number of subtypes.

5) server updates a mapping of items and number of subtypes.

 

So two very small packets are required.

 

Now if you really want to continue in the way you were, I'm surprised that the packet is large. You only need to have the client send a list of item ids that have subtypes and how many there are. Server can assume that remaining items don't have subtypes. So it should only be several dozen bytes long I think -- for example all 16 dyes would just be represented by three bytes (two for id and one for number of subtypes).

 

In either case you get the best situation -- server gets complete list and therefore prevents hacking and can control the probability of selection to ensure all items have equal chance (or some other distribution if you want).

 

By the way, to answer your specific question about large payloads: for the logic in creating large payloads, the protocols are usually simple -- in the first bytes of the payload you simply send a boolean to indicate whether this packet is the last packet or not. If not, the receiver will continue to concatenate incoming packets. You don't need to send anything about the actual size, just whether you're finished or more is coming.

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

The only code you should have following logic:

1) server goes through the item registry and sends packet to client indicating which item (the payload can simply be the integer ID from the registry)

3) client checks whether the item has subtypes and if it does it does the getSubItems() and finds the size of sub-type list.

4) client sends packet to server indicating the number of subtypes.

5) server updates a mapping of items and number of subtypes.

 

You're system would indeed be way more efficient, but it doesn't fully cover my needs. There are however some key-components which i might be able to integrate into my system to make it more efficient.

 

The biggest problem is a check that i am using which can only be done on the clientSide, i check if getCreativeTab() != null to exclude placeholder blocks/items (such as water_still, commandBlocks, monster spawners, etc...) from the list, since these are usually not obtainable anyway. But the getCreativeTab() method is clientSide only, and this makes it so that i am currently sending almost every item in the game to the client which of course is a bad thing.

 

I am currently using Itemregistry.getNameForObject(item) to identify the items and i am sending these Strings to the client. the payload of an integer is way less, so it would probably be better to send the ID's instead of the names. Only one question would come to mind, are the ID's constant on the server and on the client? for vanilla minecraft this is probably the case, but what if other mods add items, would those id's be the same on the client and on the server? and what if the client has more mods installed than the server has, the client would still be able to join, but would the id's be the same?

 

Now if you really want to continue in the way you were, I'm surprised that the packet is large. You only need to have the client send a list of item ids that have subtypes and how many there are. Server can assume that remaining items don't have subtypes. So it should only be several dozen bytes long I think -- for example all 16 dyes would just be represented by three bytes (two for id and one for number of subtypes).

 

This would be, if i would implement such a system, which would probably be better to be honest. However the system that i am using at the moment sends the itemStacks of the subitems to the server, for vanilla only this works fine, however if i start adding other mods, the list of items becomes longer and as a result the payload of the packet becomes larger.

 

By the way, to answer your specific question about large payloads: for the logic in creating large payloads, the protocols are usually simple -- in the first bytes of the payload you simply send a boolean to indicate whether this packet is the last packet or not. If not, the receiver will continue to concatenate incoming packets. You don't need to send anything about the actual size, just whether you're finished or more is coming.

 

The problem currently is not so much how many packets i need to send, but more how many itemStacks i can write to a single packet. Since it's better to send one big packet than multiple smaller packets i am currently trying to fit as many itemStacks as i can into every packet i send. so my question is how i can calculate the payload (specifically of an NBTTagCompound) so i can send the packet away if the payload get's too large, and start writing the rest of the itemStacks to a new packet.

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

I fixed it!

I have been looking at the write methods within the subclasses of NBTBase, and calculated the payload per type of NBT. I am iterating through the keys of the NBTTagCompound and adding the payload of every key together to calculate the payload of the full compound.

 

I was interested to see how many packets it would get split up into, and the payload of these packets. this is what i found:

 

http://pastebin.com/bavmL5ds

 

I was quite shocked by the result.

previously i was able to send all itemStacks in one packet (which is probably the first packet containing 841 items).

I have added a single mod, and now i need 27 packets (most of which only contain 19 items...)

I am almost certain now that I am going to rewrite this system sometime in the future, I don't want to think about the amount of packets needed for a small modpack...

 

It makes me wonder though, why would you ever need that much data in an itemStack........ :o

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

I don't think you understand how easy it is to do what you want. All you need is the client to send information about those few items that have more than one type.

 

I wrote some code to do this, and this was the result (item id and number of subtypes):

{1=7, 322=2, 3=3, 5=6, 6=6, 263=2, 139=2, 12=2, 397=5, 17=4, 145=3, 18=4, 19=2, 24=3, 155=3, 349=4, 350=2, 31=2, 95=16, 159=16, 351=16, 160=16, 97=6, 161=2, 98=4, 162=2, 35=16, 38=9, 168=3, 425=16, 171=16, 44=7, 175=6, 179=3, 373=61, 126=6, 383=27}

 

You can double check the accuracy here: http://minecraft-ids.grahamedgecombe.com/

 

For example, it says iD#1 has 7 sub-types, which is correct (it is various types of stone block).

 

So you just need to pack that info into a packet and send it.

 

Here is my code. I run it in the client proxy since there are some client-only methods. Note you must do this in the post-init stage since you want to make sure all mods have registered their items as well.

 

 

 

public Map<Integer, Integer> itemSubTypeMap = new HashMap<Integer, Integer>();

public Map<Integer, Integer> sparseItemSubTypeMap = new HashMap<Integer, Integer>();

 

    @Override

protected Map getSubTypesForItems()

    {

List subItemList = new ArrayList();

for (Object theObj: Item.itemRegistry)

{

((Item)theObj).getSubItems((Item)theObj, null, subItemList);

itemSubTypeMap.put(Item.itemRegistry.getIDForObject(theObj), subItemList.size());

subItemList.clear();

}

// DEBUG

System.out.println("Item subtypes list = "+itemSubTypeMap.toString() );

return itemSubTypeMap;

    }

   

    @Override

protected Map getSparseSubTypesForItems()

    {

Iterator theIterator = itemSubTypeMap.entrySet().iterator();

 

sparseItemSubTypeMap.clear();

while (theIterator.hasNext())

{

        Map.Entry<Integer, Integer> pair = (Map.Entry)theIterator.next();

        if (pair.getValue() > 1)

        {

        sparseItemSubTypeMap.put(pair.getKey(), pair.getValue());

        }

        theIterator.remove(); // avoids a ConcurrentModificationException

}

 

        // DEBUG

        System.out.println("Sparse item id list = "+sparseItemSubTypeMap.toString());

 

return sparseItemSubTypeMap;

    }

 

 

I just run each method during post-init. I have two map fields, one that holds all items and another that is "sparse" meaning only containing those items that have more than one sub-type.

 

Then if you send this info to the server in a packet, it would go create a list of ItemStack by through the list of items but also accounting for the number of sub-types the client said there were.

 

 

 

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

I don't think you understand how easy it is to do what you want. All you need is the client to send information about those few items that have more than one type.

 

I wrote some code to do this, and this was the result (item id and number of subtypes):

{1=7, 322=2, 3=3, 5=6, 6=6, 263=2, 139=2, 12=2, 397=5, 17=4, 145=3, 18=4, 19=2, 24=3, 155=3, 349=4, 350=2, 31=2, 95=16, 159=16, 351=16, 160=16, 97=6, 161=2, 98=4, 162=2, 35=16, 38=9, 168=3, 425=16, 171=16, 44=7, 175=6, 179=3, 373=61, 126=6, 383=27}

 

You can double check the accuracy here: http://minecraft-ids.grahamedgecombe.com/

 

For example, it says iD#1 has 7 sub-types, which is correct (it is various types of stone block).

 

So you just need to pack that info into a packet and send it.were.

 

The biggest problem i have with this, is more a question than a problem. as i said earlier, i have no doubt that the id's are the same on the client and on the sever when using only vanila, however, will the id's be the same if more mods are installed? and what happens if the client has more mods installed than the server?

 

second problem: the rest of my mod is fully based around having a list of itemStacks on the server, if i change this out to a map of id's to subItems, i basically have to rewrite my whole mod, which i don't feel like doing right now, this is why i said i will probably change the system later.

 

Then if you send this info to the server in a packet, it would go create a list of ItemStack by through the list of items but also accounting for the number of sub-types the client said there were.

 

this is interesting, if there is a way to convert this map to a list of ItemStacks i could easily integrate it into the rest of the mod, and i would happily change my current system to this system.

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

If the ID's on the client and server are different, you will have much bigger problems that your worry.

 

I am not entirely sure how the new ID system works, but since minecraft stopped using id's i have tried to avoid them...

but from your answer i assume it's safe to say ID's will be constant on the client and the server?

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

Minecraft does use IDs, just like it did before. They are just dynamically assigned. Yes, they are consistent between client & server.

 

Thank you! might have to look into using ID's then, since the payload of an integer is way less than that of a String.

could probably even convert most of them to bytes/shorts for even more efficiency  :)

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

The biggest problem i have with this, is more a question than a problem. as i said earlier, i have no doubt that the id's are the same on the client and on the sever when using only vanila, however, will the id's be the same if more mods are installed? and what happens if the client has more mods installed than the server?

 

second problem: the rest of my mod is fully based around having a list of itemStacks on the server, if i change this out to a map of id's to subItems, i basically have to rewrite my whole mod, which i don't feel like doing right now, this is why i said i will probably change the system later.

 

is is interesting, if there is a way to convert this map to a list of ItemStacks i could easily integrate it into the rest of the mod, and i would happily change my current system to this system.

 

Like mentioned, the IDs must match as that is how the server communicates. If you don't trust that, I suppose you could use unlocalized name strings which should also provide a unique way to look up things.

 

Yes, the server can create an actual list of ItemStacks using this information from the client. Basically the server would receive the packet from the client and then it would go through the Item.itemRegistry and would create a list of ItemStacks that would have metadata=0 if there was no match in the packet payload, otherwise would use the value from the packet payload and create multiple ItemStacks (one for each metadata value).

 

So steps would be like this:

  1) have a field on server to contain the List of ItemStacks

  2) when receiving the client packet, the server should iterate or loop through the Item.itemRegistry and check if the item has an id that matches a key in the map sent in the packet. If yes, then use the map value, otherwise use 0.

  3) For the number you get in Step #2, you'd loop and create a new ItemStack that contains the item. Like if the packet said there were 2 values, then you'd create one stack with metadata 0 and one with metadata 1. You'd add each stack to the List from Step #1.

 

After that the server would permanently have a list of all items and subtypes that you could use to do what you want.

 

This was actually an interesting topic. It does indeed suck that the getSubTypes() method is only client-side. It does seem useful to have an easy way to access all items including subtypes. I think I'll write this up as a utility as it might be useful sometime.

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

One note to watch out for. The example I give has the client indicate the number of different subtypes there are. In almost every case, the metadata values all start at 0 and go up with no gaps. However, I realized that in vanilla items, that spawn eggs (id = 383) actually start at 50. So my code will correctly say there are 27 spawn eggs but you won't know what the starting metadata value is. For vanilla you could just handle that special case, but other mods could have any scheme they wanted.

 

So to be really safe you probably have to send more information. I see two options:

1) if you just want to use this for random item generation, then the server could use messages to get the mapping to actual metadata after it chooses the item. In other words, if server knew there was 27 spawn eggs and it chose spawn egg 14, then it could send a message to the client asking what the actual metadata value should be.

2) You could create the initial list with a bit of extra information. For example, you could have something in the payload that flags any item that doesn't have regular pattern of metadata. Like the payload data could be a boolean (for whether it is normal), the item id, and the number of subtypes, then if it isn't normal you would provide the additional info (like start at 50).

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Yes, the server can create an actual list of ItemStacks using this information from the client. Basically the server would receive the packet from the client and then it would go through the Item.itemRegistry and would create a list of ItemStacks that would have metadata=0 if there was no match in the packet payload, otherwise would use the value from the packet payload and create multiple ItemStacks (one for each metadata value).

 

So steps would be like this:

  1) have a field on server to contain the List of ItemStacks

  2) when receiving the client packet, the server should iterate or loop through the Item.itemRegistry and check if the item has an id that matches a key in the map sent in the packet. If yes, then use the map value, otherwise use 0.

  3) For the number you get in Step #2, you'd loop and create a new ItemStack that contains the item. Like if the packet said there were 2 values, then you'd create one stack with metadata 0 and one with metadata 1. You'd add each stack to the List from Step #1.

 

After that the server would permanently have a list of all items and subtypes that you could use to do what you want.

 

This system is not able to check if the item has a creativeTab, and as a result placeholder blocks like water_still, lava_flowing and piston_head would end up in the list.

however, this is easily fixable by making another map of the id's to booleans (creativetab == null) and combine the data of the two lists to construct the final list on the server.

 

There is still another problem with this system: it assumes the itemDamage of the subItems will increase as the amount of subItems does. While this is the case most of the time, even in vanilla there are cases where this is not true, look for instance at the spawn_egg.

This could however be solved by sending the damageValues of the subItems (in response to a requester packet from the server or something).

but as you can see the amount of data transferring is already rising.

 

Then there is a final problem: This system will not work with subItems that have nbtData.

I don't think in vanilla there are any items that use this, but in other mods it is used sometimes.

 

Here are two examples of it in Tconstruct:

https://github.com/SlimeKnights/TinkersConstruct/blob/a7405a3d10318bb5c486ec75fb62897a8149d1a6/src/main/java/tconstruct/tools/items/CreativeModifier.java

https://github.com/SlimeKnights/TinkersConstruct/blob/a7405a3d10318bb5c486ec75fb62897a8149d1a6/src/main/java/tconstruct/items/tools/FryingPan.java

 

The server would have itemStacks without nbtData, and possibly even with damageValues that are not used in that item.

There is no way for the server to reconstruct the nbtData, so the ItemStack must be sent to the server. (or at least it's nbtData).

There is no way for the server to 'know' if a subItem has nbtData, and because of this you will have to send the itemStacks of all subItems.

 

Unless... You want to use hasTagCompound() on the client on the subItems, and make a list of ID's that have subItems with nbt, and also send this list to the server to take into account.

But at this point you are sending so much data to the server that you might as well just send the itemStacks to the server.

 

If there are any mistakes in my thought process, be sure to tell me about them ;)

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

One note to watch out for. The example I give has the client indicate the number of different subtypes there are. In almost every case, the metadata values all start at 0 and go up with no gaps. However, I realized that in vanilla items, that spawn eggs (id = 383) actually start at 50. So my code will correctly say there are 27 spawn eggs but you won't know what the starting metadata value is. For vanilla you could just handle that special case, but other mods could have any scheme they wanted.

 

So to be really safe you probably have to send more information. I see two options:

1) if you just want to use this for random item generation, then the server could use messages to get the mapping to actual metadata after it chooses the item. In other words, if server knew there was 27 spawn eggs and it chose spawn egg 14, then it could send a message to the client asking what the actual metadata value should be.

2) You could create the initial list with a bit of extra information. For example, you could have something in the payload that flags any item that doesn't have regular pattern of metadata. Like the payload data could be a boolean (for whether it is normal), the item id, and the number of subtypes, then if it isn't normal you would provide the additional info (like start at 50).

 

When i wrote my previous post, i hadn't read this yet: you can scrape problem n. 2 off the list  :)

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

The NBT shouldn't be a big issue, I don't think. The getSubItems() method will get a List of ItemStacks based on whatever the mod author wanted, but the result is the same -- a list of ItemStacks with Item and metadata value. My code above will still properly count the number of subtypes. Then when you tell the client you're interested in the 5th sub-type, you can just look that up by taking that element from the list.

 

Otherwise, you're on the right track -- I can tell you understand the basic idea: you just need client to give information to server about the number of subtypes, and the Item itself can be referenced by ID. The server doesn't actually need to know the metadata value, it just needs to know the sub-types' index in the List that is returned by the client-side getSubItems(). So you shouldn't need to send that much data.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

The NBT shouldn't be a big issue, I don't think. The getSubItems() method will get a List of ItemStacks based on whatever the mod author wanted, but the result is the same -- a list of ItemStacks with Item and metadata value. My code above will still properly count the number of subtypes. Then when you tell the client you're interested in the 5th sub-type, you can just look that up by taking that element from the list.

 

Otherwise, you're on the right track -- I can tell you understand the basic idea: you just need client to give information to server about the number of subtypes, and the Item itself can be referenced by ID. The server doesn't actually need to know the metadata value, it just needs to know the sub-types' index in the List that is returned by the client-side getSubItems(). So you shouldn't need to send that much data.

 

ahh, i see what you're saying, this would totally work.

It is however not a system that constructs a list of itemStacks on the server, this is a system that gives the server all the information it needs to request any itemStack from the client.

But with this system, if you need the actual itemStack on the server you still need to send it from the client. (probably as a respond to a requester packet containing the ID and the subItem index)

 

however, if optimized correctly the respond packet would most of the time only contain two shorts/ a short and an int. (ID and dmgValue)

Unless the itemStack has nbt, I think there's no way to avoid a big packet in that case...

 

This would probably be a really fun project to write and try to optimize it as best as possible.

I will probably try to write it in a separate project, and when it's fully working and optimized integrate it in the mod.

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

 

ahh, i see what you're saying, this would totally work.

It is however not a system that constructs a list of itemStacks on the server, this is a system that gives the server all the information it needs to request any itemStack from the client.

But with this system, if you need the actual itemStack on the server you still need to send it from the client. (probably as a respond to a requester packet containing the ID and the subItem index)

 

however, if optimized correctly the respond packet would most of the time only contain two shorts/ a short and an int. (ID and dmgValue)

Unless the itemStack has nbt, I think there's no way to avoid a big packet in that case...

 

This would probably be a really fun project to write and try to optimize it as best as possible.

I will probably try to write it in a separate project, and when it's fully working and optimized integrate it in the mod.

 

I agree it is a fun project.

 

It got me interested when I confirmed your point that server doesn't really have full concept of the sub-types. But every Item sub-type can be represented ultimately by the metadata. It's just that the server doesn't know the full list of possible metadata values.

 

I think ultimately you could create an List of ItemStacks on the server if you wanted to, you just have to do the work of transferring the actual metadata values from client to server. You can do that in a number of ways, and I think you have some ideas on how to do that. It would take a bit of thought, but seems quite doable. Good luck!

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

I couldn't let the topic go and kept working on it. I think I have success -- I can create a list from a byte buffer (which could be payload of a packet from client) that contains one of every item variant.

 

Here is what the output of the resulting List toString() looks like:

 

[1xtile.stone@0, 1xtile.stone@1, 1xtile.stone@2, 1xtile.stone@3, 1xtile.stone@4, 1xtile.stone@5, 1xtile.stone@6, 1xtile.cobbleWall@0, 1xtile.cobbleWall@1, 1xtile.dirt@0, 1xtile.dirt@1, 1xtile.dirt@2, 1xtile.wood@0, 1xtile.wood@1, 1xtile.wood@2, 1xtile.wood@3, 1xtile.wood@4, 1xtile.wood@5, 1xtile.sapling@0, 1xtile.sapling@1, 1xtile.sapling@2, 1xtile.sapling@3, 1xtile.sapling@4, 1xtile.sapling@5, 1xitem.dyePowder@0, 1xitem.dyePowder@1, 1xitem.dyePowder@2, 1xitem.dyePowder@3, 1xitem.dyePowder@4, 1xitem.dyePowder@5, 1xitem.dyePowder@6, 1xitem.dyePowder@7, 1xitem.dyePowder@8, 1xitem.dyePowder@9, 1xitem.dyePowder@10, 1xitem.dyePowder@11, 1xitem.dyePowder@12, 1xitem.dyePowder@13, 1xitem.dyePowder@14, 1xitem.dyePowder@15, 1xitem.fish@0, 1xitem.fish@1, 1xitem.fish@0, 1xitem.fish@1, 1xitem.fish@2, 1xitem.fish@3, 1xtile.sand@0, 1xtile.sand@1, 1xtile.log@0, 1xtile.log@1, 1xtile.log@2, 1xtile.log@3, 1xtile.sponge@0, 1xtile.sponge@1, 1xtile.leaves@0, 1xtile.leaves@1, 1xtile.leaves@2, 1xtile.leaves@3, 1xtile.quartzBlock@0, 1xtile.quartzBlock@1, 1xtile.quartzBlock@2, 1xitem.appleGold@0, 1xitem.appleGold@1, 1xitem.coal@0, 1xitem.coal@1, 1xitem.skull@0, 1xitem.skull@1, 1xitem.skull@2, 1xitem.skull@3, 1xitem.skull@4, 1xtile.clayHardenedStained@0, 1xtile.clayHardenedStained@1, 1xtile.clayHardenedStained@2, 1xtile.clayHardenedStained@3, 1xtile.clayHardenedStained@4, 1xtile.clayHardenedStained@5, 1xtile.clayHardenedStained@6, 1xtile.clayHardenedStained@7, 1xtile.clayHardenedStained@8, 1xtile.clayHardenedStained@9, 1xtile.clayHardenedStained@10, 1xtile.clayHardenedStained@11, 1xtile.clayHardenedStained@12, 1xtile.clayHardenedStained@13, 1xtile.clayHardenedStained@14, 1xtile.clayHardenedStained@15, 1xtile.sandStone@0, 1xtile.sandStone@1, 1xtile.sandStone@2, 1xtile.anvil@0, 1xtile.anvil@1, 1xtile.anvil@2, 1xtile.stainedGlass@0, 1xtile.stainedGlass@1, 1xtile.stainedGlass@2, 1xtile.stainedGlass@3, 1xtile.stainedGlass@4, 1xtile.stainedGlass@5, 1xtile.stainedGlass@6, 1xtile.stainedGlass@7, 1xtile.stainedGlass@8, 1xtile.stainedGlass@9, 1xtile.stainedGlass@10, 1xtile.stainedGlass@11, 1xtile.stainedGlass@12, 1xtile.stainedGlass@13, 1xtile.stainedGlass@14, 1xtile.stainedGlass@15, 1xtile.tallgrass@1, 1xtile.tallgrass@2, 1xitem.potion@0, 1xitem.potion@8193, 1xitem.potion@8225, 1xitem.potion@8257, 1xitem.potion@16385, 1xitem.potion@16417, 1xitem.potion@16449, 1xitem.potion@8194, 1xitem.potion@8226, 1xitem.potion@8258, 1xitem.potion@16386, 1xitem.potion@16418, 1xitem.potion@16450, 1xitem.potion@8227, 1xitem.potion@8259, 1xitem.potion@16419, 1xitem.potion@16451, 1xitem.potion@8196, 1xitem.potion@8228, 1xitem.potion@8260, 1xitem.potion@16388, 1xitem.potion@16420, 1xitem.potion@16452, 1xitem.potion@8261, 1xitem.potion@8229, 1xitem.potion@16453, 1xitem.potion@16421, 1xitem.potion@8230, 1xitem.potion@8262, 1xitem.potion@16422, 1xitem.potion@16454, 1xitem.potion@8232, 1xitem.potion@8264, 1xitem.potion@16424, 1xitem.potion@16456, 1xitem.potion@8201, 1xitem.potion@8233, 1xitem.potion@8265, 1xitem.potion@16393, 1xitem.potion@16425, 1xitem.potion@16457, 1xitem.potion@8234, 1xitem.potion@8266, 1xitem.potion@16426, 1xitem.potion@16458, 1xitem.potion@8267, 1xitem.potion@8235, 1xitem.potion@16459, 1xitem.potion@16427, 1xitem.potion@8268, 1xitem.potion@8236, 1xitem.potion@16460, 1xitem.potion@16428, 1xitem.potion@8237, 1xitem.potion@8269, 1xitem.potion@16429, 1xitem.potion@16461, 1xitem.potion@8238, 1xitem.potion@8270, 1xitem.potion@16430, 1xitem.potion@16462, 1xtile.woolCarpet@0, 1xtile.woolCarpet@1, 1xtile.woolCarpet@2, 1xtile.woolCarpet@3, 1xtile.woolCarpet@4, 1xtile.woolCarpet@5, 1xtile.woolCarpet@6, 1xtile.woolCarpet@7, 1xtile.woolCarpet@8, 1xtile.woolCarpet@9, 1xtile.woolCarpet@10, 1xtile.woolCarpet@11, 1xtile.woolCarpet@12, 1xtile.woolCarpet@13, 1xtile.woolCarpet@14, 1xtile.woolCarpet@15, 1xtile.cloth@0, 1xtile.cloth@1, 1xtile.cloth@2, 1xtile.cloth@3, 1xtile.cloth@4, 1xtile.cloth@5, 1xtile.cloth@6, 1xtile.cloth@7, 1xtile.cloth@8, 1xtile.cloth@9, 1xtile.cloth@10, 1xtile.cloth@11, 1xtile.cloth@12, 1xtile.cloth@13, 1xtile.cloth@14, 1xtile.cloth@15, 1xtile.prismarine@0, 1xtile.prismarine@1, 1xtile.prismarine@2, 1xtile.flower2@0, 1xtile.flower2@1, 1xtile.flower2@2, 1xtile.flower2@3, 1xtile.flower2@4, 1xtile.flower2@5, 1xtile.flower2@6, 1xtile.flower2@7, 1xtile.flower2@8, 1xtile.stonebricksmooth@0, 1xtile.stonebricksmooth@1, 1xtile.stonebricksmooth@2, 1xtile.stonebricksmooth@3, 1xtile.doublePlant@0, 1xtile.doublePlant@1, 1xtile.doublePlant@2, 1xtile.doublePlant@3, 1xtile.doublePlant@4, 1xtile.doublePlant@5, 1xtile.monsterStoneEgg@0, 1xtile.monsterStoneEgg@1, 1xtile.monsterStoneEgg@2, 1xtile.monsterStoneEgg@3, 1xtile.monsterStoneEgg@4, 1xtile.monsterStoneEgg@5, 1xtile.log@0, 1xtile.log@1, 1xitem.monsterPlacer@50, 1xitem.monsterPlacer@51, 1xitem.monsterPlacer@52, 1xitem.monsterPlacer@54, 1xitem.monsterPlacer@55, 1xitem.monsterPlacer@56, 1xitem.monsterPlacer@57, 1xitem.monsterPlacer@58, 1xitem.monsterPlacer@59, 1xitem.monsterPlacer@60, 1xitem.monsterPlacer@61, 1xitem.monsterPlacer@62, 1xitem.monsterPlacer@65, 1xitem.monsterPlacer@66, 1xitem.monsterPlacer@67, 1xitem.monsterPlacer@68, 1xitem.monsterPlacer@90, 1xitem.monsterPlacer@91, 1xitem.monsterPlacer@92, 1xitem.monsterPlacer@93, 1xitem.monsterPlacer@94, 1xitem.monsterPlacer@95, 1xitem.monsterPlacer@96, 1xitem.monsterPlacer@98, 1xitem.monsterPlacer@100, 1xitem.monsterPlacer@101, 1xitem.monsterPlacer@120, 1xtile.leaves@0, 1xtile.leaves@1, 1xtile.thinStainedGlass@0, 1xtile.thinStainedGlass@1, 1xtile.thinStainedGlass@2, 1xtile.thinStainedGlass@3, 1xtile.thinStainedGlass@4, 1xtile.thinStainedGlass@5, 1xtile.thinStainedGlass@6, 1xtile.thinStainedGlass@7, 1xtile.thinStainedGlass@8, 1xtile.thinStainedGlass@9, 1xtile.thinStainedGlass@10, 1xtile.thinStainedGlass@11, 1xtile.thinStainedGlass@12, 1xtile.thinStainedGlass@13, 1xtile.thinStainedGlass@14, 1xtile.thinStainedGlass@15, 1xtile.stoneSlab@0, 1xtile.stoneSlab@1, 1xtile.stoneSlab@3, 1xtile.stoneSlab@4, 1xtile.stoneSlab@5, 1xtile.stoneSlab@6, 1xtile.stoneSlab@7, 1xtile.banner@15, 1xtile.banner@14, 1xtile.banner@13, 1xtile.banner@12, 1xtile.banner@11, 1xtile.banner@10, 1xtile.banner@9, 1xtile.banner@8, 1xtile.banner@7, 1xtile.banner@6, 1xtile.banner@5, 1xtile.banner@4, 1xtile.banner@3, 1xtile.banner@2, 1xtile.banner@1, 1xtile.banner@0, 1xtile.redSandStone@0, 1xtile.redSandStone@1, 1xtile.redSandStone@2, 1xtile.woodSlab@0, 1xtile.woodSlab@1, 1xtile.woodSlab@2, 1xtile.woodSlab@3, 1xtile.woodSlab@4, 1xtile.woodSlab@5]

 

 

You can see for example that the spawn eggs (called monster placers) start at metadata value of 50 like they're supposed to, etc.

 

Here is the code I run to create the byte buffer (you need to run each method in a row on client side). You need to put this code in the client proxy because it calls the client-side only methods:

 

public Map<Integer, Integer> itemSubTypeMap = new HashMap<Integer, Integer>();

public Map<Integer, Integer> sparseItemSubTypeMap = new HashMap<Integer, Integer>();

 

    @Override

protected Map getSubTypesForItems()

    {

List subItemList = new ArrayList();

for (Object theObj: Item.itemRegistry)

{

((Item)theObj).getSubItems((Item)theObj, null, subItemList);

itemSubTypeMap.put(Item.itemRegistry.getIDForObject(theObj), subItemList.size());

subItemList.clear();

}

// DEBUG

System.out.println("Item subtypes list = "+itemSubTypeMap.toString() );

return itemSubTypeMap;

    }

   

    @Override

protected Map getSparseSubTypesForItems()

    {

Iterator theIterator = itemSubTypeMap.entrySet().iterator();

 

sparseItemSubTypeMap.clear();

while (theIterator.hasNext())

{

        Map.Entry<Integer, Integer> pair = (Map.Entry)theIterator.next();

        if (pair.getValue() > 1)

        {

        sparseItemSubTypeMap.put(pair.getKey(), pair.getValue());

        }

        theIterator.remove(); // avoids a ConcurrentModificationException

}

 

        // DEBUG

        System.out.println("Sparse item id list = "+sparseItemSubTypeMap.toString());

 

return sparseItemSubTypeMap;

    }

   

    public ByteBuf getSparseItemPayload()

    {

        ByteBuf theBuffer = Unpooled.buffer();

        Iterator theIterator = sparseItemSubTypeMap.entrySet().iterator();

       

        // DEBUG

        String outputString = "Sparse items with metadata =";

 

        while (theIterator.hasNext())

        {           

            Map.Entry<Integer, Integer> pair = (Map.Entry)theIterator.next();

           

            // write item id and number of sub-types

            theBuffer.writeInt(pair.getKey());

            theBuffer.writeByte(pair.getValue());

           

            // DEBUG

            outputString += " "+pair.getKey().toString()+" "+pair.getValue().toString();

           

            // write metadata values for each of the sub-types

            ArrayList<ItemStack> subTypes = new ArrayList();

            Item theItem = Item.getItemById(pair.getKey());

            theItem.getSubItems(theItem, null, subTypes);

            for (int i = 0; i < subTypes.size(); i++)

            {

                theBuffer.writeInt(subTypes.get(i).getMetadata());

                outputString += " "+subTypes.get(i).getMetadata();

            }

            theIterator.remove(); // avoids a ConcurrentModificationException

        }

       

        // DEBUG

        System.out.println(outputString);

        return theBuffer;

    }

 

 

And here is the code that can receive the byte buffer on the server side and create the list:

 

    public List<ItemStack> getCompleteItemStackList(ByteBuf theBuffer)

    {

        List<ItemStack> theList = new ArrayList();

        while (theBuffer.isReadable())

        {

            int theID = theBuffer.readInt();

            byte numVariants = theBuffer.readByte();

            if (numVariants > 1)

            {

                for (int i = 0; i < numVariants; i++)

                {

                    theList.add(new ItemStack(Item.getItemById(theID), 1, theBuffer.readInt()));

                }

            }

            else

            {

                theList.add(new ItemStack(Item.getItemById(theID)));

            }

        }

        // DEBUG

        System.out.println(theList.toString());

       

        return theList;     

    }

 

 

 

Note that the code probably needs some exception handling in case the byte buffer doesn't come in in the expected format. The expected format is:

  1) int for item ID

  2) byte for number of subtypes

  3) if the subtypes is more than 1, then each of the metadata values as integers.

 

Since the third part can be variable, you need to use loops to create and retrieve the values based on the number of subtypes.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Nice! this system only doesn't support nbtdata yet, right? I'll have some time later today and than i will start on my system :)

 

It does support NBT data. The getSubTypes() method returns an ItemStack of items with different metadata. That metadata might have been generated by NBT, but the result is the same and that is what I'm passing back and forth.

 

Remember that there is a difference between the NBT used to make variants and item NBT used for further player customization. This whole scheme is about giving player's fresh items, not copying specific items that are customized by the player. The server already has the default NBT. You just need to pass the metadata mapping and the server can re-create the same item stack.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

For the normal use of getSubItems this is true, it should return itemStacks with different damageValues, but other mods use it differently.

If you have a look at this implementation for instance:

https://github.com/SlimeKnights/TinkersConstruct/blob/a7405a3d10318bb5c486ec75fb62897a8149d1a6/src/main/java/tconstruct/tools/items/CreativeModifier.java

 

The only difference between the itemStacks created in the for loop is the "TargetLock" tag in their nbt, and this would not get picked up by your current system.

 

You are however right that getSubItems is not intended for such an implementation, since it's description says that it should return a list of items with different damagevalues ;)

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

It does support NBT data. The getSubTypes() method returns an ItemStack of items with different metadata. That metadata might have been generated by NBT, but the result is the same and that is what I'm passing back and forth.

 

I am currently working on my system, and i am writing a system that maps the amount of data needed to reconstruct the subItems on the server.

I ran into something to think about, and it made me think of what you said earlier (the quote): can an itemStack have default nbtdata?

and if so, can this nbtdata be requested on the server?

 

My system is not functional yet, if it produces actually useful results i will post the code.

 

Also, if you don't mind i will change the title to something that fits the current discussion better ;)

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

The system is coming along quite nicely, I have figured out how i want to go about doing things, and it just produced the first useful results.

My system tries to find a pattern in the subItems, and maps this pattern to every id. this way i only have to send the pattern to the server to reconstruct the subItems.

 

This is the id system i am currently using (There are two front slashes since i copied it from the comments within my class :P)

//Using an id system to visualize the amount of data needed to reconstruct on the server
//id 0: no subItems
//id 1: dmg subItems, starting at 0, incrementing by 1 for every subItem
//id 2: dmg subitems, starting at another value, incrementing by 1 for every subItem
//id 3: dmg subitems, starting at 0, incrementing by another value for every subItem
//id 4: dmg subItems, starting at another value, incrementing with another value for every subItem, but with regular pattern
//id 5: dmg subItems, with irregular pattern
//id 6: nbt subItems...? (still need to figure this mapping out...)
//
//How to send this to the server?
//First send the id of the needed data
//
//id 0: Item id
//id 1: Item id, amount of subItems
//id 2: Item id, amount of subItems, start value
//id 3: Item id, amount of subItems, increment value
//id 4: Item id, amount of subItems, start value, increment value
//id 5: Item id, amount of subItems, dmg values
//id 6: not sure how to map this yet, as a result not sure how to send it yet 
//
//variable formats:
//data id --> byte
//item id --> short will probably do (don't think id's go higher than 32767)
//amount of subItems --> byte (if you have more than 127 subItems you're doing something wrong...)
//start value --> byte? haven't encountered a startValue higher than 127
//increment value --> byte
//dmg value --> not sure yet, maybe a scaling system with a header byte indicating the format

 

There were some interesting results there, every id has been mapped at least once, except 4 (and 6 obviously), which i thought was pretty interesting.

It generated the following mapping:

http://pastebin.com/uYCirVy8

(I generated this list in minecraft 1.7.10, this is why the 1.8 items are missing from the list)

 

The code i used to generate this can be found here:

https://gist.github.com/wesserboy/b05aa0129d3079083ac8

 

This is what i am planning on implementing next:

--> write a method that optimizes the amount of data needed by remapping some id's

--> make a system that transfers the data to the server

--> make a system that constructs a list of itemStacks on the server, based on the data received from the client

----- at this point it should be fully functional for vanilla minecraft -----

--> figure out how to map the nbtData as efficient as possible

 

Since I am not quite sure yet how to efficiently map the nbtData, any idea's are welcome :)

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

Link to comment
Share on other sites

Just use ByteBufUtils to write NBT and read NBT into your packet payload.

 

I've gone ahead and think I have a full working implementation now to make the list, put it into a ByteBuf suitable to be a packet payload and then take that payload and convert it back to a list of ItemStacks, including both metadata and NBT.

 

Here is my code for initializing a public field to contain an "ItemStack registry" and then creating and reading the ByteBuf packet payload. This must go in your client proxy since it calls some client side only methods:

 

    public List itemStackRegistry = new ArrayList();

 

    /*

    * This initializes the List in the public field itemListFromRegistry with all possilbe

    * ItemStack types (all valid metadata values, as well as any NBT that is used to create variants

    * in mods like Tinker's Construct).

    */

    @Override

protected void initItemStackRegistry()

    {

itemStackRegistry.clear();

 

for (Object theObj: Item.itemRegistry)

{

((Item)theObj).getSubItems((Item)theObj, null, itemStackRegistry);

}

 

// DEBUG

System.out.println("ItemStack registry = "+itemStackRegistry.toString());

 

return;

    }

 

    /*

    * Returns a ByteBuf suitable to be used as a packet payload to be sent to the server

    */

    public ByteBuf convertItemStackListToPayload()

    {

        ByteBuf theBuffer = Unpooled.buffer();

        Iterator theIterator = itemStackRegistry.iterator();

     

        // DEBUG

        String outputString = "Item list payload =";

 

        while (theIterator.hasNext())

        {         

            ItemStack theStack = (ItemStack) theIterator.next();

           

            // write item id and metadata

            theBuffer.writeInt(Item.getIdFromItem(theStack.getItem()));

            theBuffer.writeInt(theStack.getMetadata());

           

            // DEBUG

            outputString += " "+Item.getIdFromItem(theStack.getItem())+" "+theStack.getMetadata();

            boolean hasNBT = theStack.hasTagCompound();

            theBuffer.writeBoolean(hasNBT);

            // DEBUG

            outputString += " "+hasNBT;

            if (hasNBT)

            {

                // DEBUG

                System.out.println("The stack "+theStack.toString()+" has NBT = "+theStack.getTagCompound().toString());

                outputString+= " = "+theStack.getTagCompound().toString();

                ByteBufUtils.writeTag(theBuffer, theStack.getTagCompound());

            }

            theIterator.remove(); // avoids a ConcurrentModificationException

        }

       

        // DEBUG

        System.out.println(outputString);

       

        return theBuffer;

    }

 

 

    /*

    * Provides a list of item stacks giving every registered item along with its metadata variants

    * based on a message payload from the client that gives the valid metadata values for those

    * items with variants. Also will include NBT for mods like Tinker's Construct that use NBT on the

    * ItemStacks to make variants instead of metadata.

    */

    public List<ItemStack> convertPayloadToItemStackList(ByteBuf theBuffer)

    {

        List<ItemStack> theList = new ArrayList();

       

        while (theBuffer.isReadable())

        {

            int theID = theBuffer.readInt();

            int theMetadata = theBuffer.readInt();

            ItemStack theStack = new ItemStack(Item.getItemById(theID), 1, theMetadata);

           

            // Handle the case of mods like Tinker's Construct that use NBT instead of metadata

            boolean hasNBT = theBuffer.readBoolean();

            if (hasNBT)

            {

                theStack.setTagCompound(ByteBufUtils.readTag(theBuffer));

                // DEBUG

                System.out.println("The stack "+theStack.toString()+" has NBT = "+theStack.getTagCompound().toString());

            }

           

          theList.add(theStack);

        }

 

        // DEBUG

        System.out.println(theList.toString());

 

        return theList;     

    }

 

 

 

I put a lot of console statements to help trace the execution (this is really important in packet payloads because if you make any mismatch in the type or order of data in the payload it will screw up. The results show that it indeed creates a full list (I'm using 1.8 so you'll see multiple variants of stone and such) including a custom item ("sheep skin") that has NBT data. You can see that the final list finds the item with NBT and includes it in the list.

 

First here is the ItemStack list on the sending side:

 

 

[21:42:00] [Client thread/INFO] [sTDOUT]: [com.blogspot.jabelarminecraft.blocksmith.proxy.ClientProxy:initItemStackRegistry:268]: ItemStack registry = [1xtile.stone@0, 1xtile.stone@1, 1xtile.stone@2, 1xtile.stone@3, 1xtile.stone@4, 1xtile.stone@5, 1xtile.stone@6, 1xtile.grass@0, 1xtile.dirt@0, 1xtile.dirt@1, 1xtile.dirt@2, 1xtile.stonebrick@0, 1xtile.wood@0, 1xtile.wood@1, 1xtile.wood@2, 1xtile.wood@3, 1xtile.wood@4, 1xtile.wood@5, 1xtile.sapling@0, 1xtile.sapling@1, 1xtile.sapling@2, 1xtile.sapling@3, 1xtile.sapling@4, 1xtile.sapling@5, 1xtile.bedrock@0, 1xtile.sand@0, 1xtile.sand@1, 1xtile.gravel@0, 1xtile.oreGold@0, 1xtile.oreIron@0, 1xtile.oreCoal@0, 1xtile.log@0, 1xtile.log@1, 1xtile.log@2, 1xtile.log@3, 1xtile.leaves@0, 1xtile.leaves@1, 1xtile.leaves@2, 1xtile.leaves@3, 1xtile.sponge@0, 1xtile.sponge@1, 1xtile.glass@0, 1xtile.oreLapis@0, 1xtile.blockLapis@0, 1xtile.dispenser@0, 1xtile.sandStone@0, 1xtile.sandStone@1, 1xtile.sandStone@2, 1xtile.musicBlock@0, 1xtile.goldenRail@0, 1xtile.detectorRail@0, 1xtile.pistonStickyBase@0, 1xtile.web@0, 1xtile.tallgrass@1, 1xtile.tallgrass@2, 1xtile.deadbush@0, 1xtile.pistonBase@0, 1xtile.cloth@0, 1xtile.cloth@1, 1xtile.cloth@2, 1xtile.cloth@3, 1xtile.cloth@4, 1xtile.cloth@5, 1xtile.cloth@6, 1xtile.cloth@7, 1xtile.cloth@8, 1xtile.cloth@9, 1xtile.cloth@10, 1xtile.cloth@11, 1xtile.cloth@12, 1xtile.cloth@13, 1xtile.cloth@14, 1xtile.cloth@15, 1xtile.flower1@0, 1xtile.flower2@0, 1xtile.flower2@1, 1xtile.flower2@2, 1xtile.flower2@3, 1xtile.flower2@4, 1xtile.flower2@5, 1xtile.flower2@6, 1xtile.flower2@7, 1xtile.flower2@8, 1xtile.mushroom@0, 1xtile.mushroom@0, 1xtile.blockGold@0, 1xtile.blockIron@0, 1xtile.stoneSlab@0, 1xtile.stoneSlab@1, 1xtile.stoneSlab@3, 1xtile.stoneSlab@4, 1xtile.stoneSlab@5, 1xtile.stoneSlab@6, 1xtile.stoneSlab@7, 1xtile.brick@0, 1xtile.tnt@0, 1xtile.bookshelf@0, 1xtile.stoneMoss@0, 1xtile.obsidian@0, 1xtile.torch@0, 1xtile.mobSpawner@0, 1xtile.stairsWood@0, 1xtile.chest@0, 1xtile.oreDiamond@0, 1xtile.blockDiamond@0, 1xtile.workbench@0, 1xtile.farmland@0, 1xtile.furnace@0, 1xtile.furnace@0, 1xtile.ladder@0, 1xtile.rail@0, 1xtile.stairsStone@0, 1xtile.lever@0, 1xtile.pressurePlateStone@0, 1xtile.pressurePlateWood@0, 1xtile.oreRedstone@0, 1xtile.notGate@0, 1xtile.button@0, 1xtile.snow@0, 1xtile.ice@0, 1xtile.snow@0, 1xtile.cactus@0, 1xtile.clay@0, 1xtile.jukebox@0, 1xtile.fence@0, 1xtile.pumpkin@0, 1xtile.hellrock@0, 1xtile.hellsand@0, 1xtile.lightgem@0, 1xtile.litpumpkin@0, 1xtile.stainedGlass@0, 1xtile.stainedGlass@1, 1xtile.stainedGlass@2, 1xtile.stainedGlass@3, 1xtile.stainedGlass@4, 1xtile.stainedGlass@5, 1xtile.stainedGlass@6, 1xtile.stainedGlass@7, 1xtile.stainedGlass@8, 1xtile.stainedGlass@9, 1xtile.stainedGlass@10, 1xtile.stainedGlass@11, 1xtile.stainedGlass@12, 1xtile.stainedGlass@13, 1xtile.stainedGlass@14, 1xtile.stainedGlass@15, 1xtile.trapdoor@0, 1xtile.monsterStoneEgg@0, 1xtile.monsterStoneEgg@1, 1xtile.monsterStoneEgg@2, 1xtile.monsterStoneEgg@3, 1xtile.monsterStoneEgg@4, 1xtile.monsterStoneEgg@5, 1xtile.stonebricksmooth@0, 1xtile.stonebricksmooth@1, 1xtile.stonebricksmooth@2, 1xtile.stonebricksmooth@3, 1xtile.mushroom@0, 1xtile.mushroom@0, 1xtile.fenceIron@0, 1xtile.thinGlass@0, 1xtile.melon@0, 1xtile.vine@0, 1xtile.fenceGate@0, 1xtile.stairsBrick@0, 1xtile.stairsStoneBrickSmooth@0, 1xtile.mycel@0, 1xtile.waterlily@0, 1xtile.netherBrick@0, 1xtile.netherFence@0, 1xtile.stairsNetherBrick@0, 1xtile.enchantmentTable@0, 1xtile.endPortalFrame@0, 1xtile.whiteStone@0, 1xtile.dragonEgg@0, 1xtile.redstoneLight@0, 1xtile.woodSlab@0, 1xtile.woodSlab@1, 1xtile.woodSlab@2, 1xtile.woodSlab@3, 1xtile.woodSlab@4, 1xtile.woodSlab@5, 1xtile.stairsSandStone@0, 1xtile.oreEmerald@0, 1xtile.enderChest@0, 1xtile.tripWireSource@0, 1xtile.blockEmerald@0, 1xtile.stairsWoodSpruce@0, 1xtile.stairsWoodBirch@0, 1xtile.stairsWoodJungle@0, 1xtile.commandBlock@0, 1xtile.beacon@0, 1xtile.cobbleWall@0, 1xtile.cobbleWall@1, 1xtile.button@0, 1xtile.anvil@0, 1xtile.anvil@1, 1xtile.anvil@2, 1xtile.chestTrap@0, 1xtile.weightedPlate_light@0, 1xtile.weightedPlate_heavy@0, 1xtile.daylightDetector@0, 1xtile.blockRedstone@0, 1xtile.netherquartz@0, 1xtile.hopper@0, 1xtile.quartzBlock@0, 1xtile.quartzBlock@1, 1xtile.quartzBlock@2, 1xtile.stairsQuartz@0, 1xtile.activatorRail@0, 1xtile.dropper@0, 1xtile.clayHardenedStained@0, 1xtile.clayHardenedStained@1, 1xtile.clayHardenedStained@2, 1xtile.clayHardenedStained@3, 1xtile.clayHardenedStained@4, 1xtile.clayHardenedStained@5, 1xtile.clayHardenedStained@6, 1xtile.clayHardenedStained@7, 1xtile.clayHardenedStained@8, 1xtile.clayHardenedStained@9, 1xtile.clayHardenedStained@10, 1xtile.clayHardenedStained@11, 1xtile.clayHardenedStained@12, 1xtile.clayHardenedStained@13, 1xtile.clayHardenedStained@14, 1xtile.clayHardenedStained@15, 1xtile.thinStainedGlass@0, 1xtile.thinStainedGlass@1, 1xtile.thinStainedGlass@2, 1xtile.thinStainedGlass@3, 1xtile.thinStainedGlass@4, 1xtile.thinStainedGlass@5, 1xtile.thinStainedGlass@6, 1xtile.thinStainedGlass@7, 1xtile.thinStainedGlass@8, 1xtile.thinStainedGlass@9, 1xtile.thinStainedGlass@10, 1xtile.thinStainedGlass@11, 1xtile.thinStainedGlass@12, 1xtile.thinStainedGlass@13, 1xtile.thinStainedGlass@14, 1xtile.thinStainedGlass@15, 1xtile.leaves@0, 1xtile.leaves@1, 1xtile.log@0, 1xtile.log@1, 1xtile.stairsWoodAcacia@0, 1xtile.stairsWoodDarkOak@0, 1xtile.slime@0, 1xtile.barrier@0, 1xtile.ironTrapdoor@0, 1xtile.prismarine@0, 1xtile.prismarine@1, 1xtile.prismarine@2, 1xtile.seaLantern@0, 1xtile.hayBlock@0, 1xtile.woolCarpet@0, 1xtile.woolCarpet@1, 1xtile.woolCarpet@2, 1xtile.woolCarpet@3, 1xtile.woolCarpet@4, 1xtile.woolCarpet@5, 1xtile.woolCarpet@6, 1xtile.woolCarpet@7, 1xtile.woolCarpet@8, 1xtile.woolCarpet@9, 1xtile.woolCarpet@10, 1xtile.woolCarpet@11, 1xtile.woolCarpet@12, 1xtile.woolCarpet@13, 1xtile.woolCarpet@14, 1xtile.woolCarpet@15, 1xtile.clayHardened@0, 1xtile.blockCoal@0, 1xtile.icePacked@0, 1xtile.doublePlant@0, 1xtile.doublePlant@1, 1xtile.doublePlant@2, 1xtile.doublePlant@3, 1xtile.doublePlant@4, 1xtile.doublePlant@5, 1xtile.redSandStone@0, 1xtile.redSandStone@1, 1xtile.redSandStone@2, 1xtile.stairsRedSandStone@0, 1xtile.stoneSlab2@0, 1xtile.spruceFenceGate@0, 1xtile.birchFenceGate@0, 1xtile.jungleFenceGate@0, 1xtile.darkOakFenceGate@0, 1xtile.acaciaFenceGate@0, 1xtile.spruceFence@0, 1xtile.birchFence@0, 1xtile.jungleFence@0, 1xtile.darkOakFence@0, 1xtile.acaciaFence@0, 1xtile.tanningrack@0, 1xtile.grinder@0, 1xtile.compactor@0, 1xtile.deconstructor@0, 1xtile.forge@0, 1xtile.movinglightsource@0, 1xitem.shovelIron@0, 1xitem.pickaxeIron@0, 1xitem.hatchetIron@0, 1xitem.flintAndSteel@0, 1xitem.apple@0, 1xitem.bow@0, 1xitem.arrow@0, 1xitem.coal@0, 1xitem.coal@1, 1xitem.diamond@0, 1xitem.ingotIron@0, 1xitem.ingotGold@0, 1xitem.swordIron@0, 1xitem.swordWood@0, 1xitem.shovelWood@0, 1xitem.pickaxeWood@0, 1xitem.hatchetWood@0, 1xitem.swordStone@0, 1xitem.shovelStone@0, 1xitem.pickaxeStone@0, 1xitem.hatchetStone@0, 1xitem.swordDiamond@0, 1xitem.shovelDiamond@0, 1xitem.pickaxeDiamond@0, 1xitem.hatchetDiamond@0, 1xitem.stick@0, 1xitem.bowl@0, 1xitem.mushroomStew@0, 1xitem.swordGold@0, 1xitem.shovelGold@0, 1xitem.pickaxeGold@0, 1xitem.hatchetGold@0, 1xitem.string@0, 1xitem.feather@0, 1xitem.sulphur@0, 1xitem.hoeWood@0, 1xitem.hoeStone@0, 1xitem.hoeIron@0, 1xitem.hoeDiamond@0, 1xitem.hoeGold@0, 1xitem.seeds@0, 1xitem.wheat@0, 1xitem.bread@0, 1xitem.helmetCloth@0, 1xitem.chestplateCloth@0, 1xitem.leggingsCloth@0, 1xitem.bootsCloth@0, 1xitem.helmetChain@0, 1xitem.chestplateChain@0, 1xitem.leggingsChain@0, 1xitem.bootsChain@0, 1xitem.helmetIron@0, 1xitem.chestplateIron@0, 1xitem.leggingsIron@0, 1xitem.bootsIron@0, 1xitem.helmetDiamond@0, 1xitem.chestplateDiamond@0, 1xitem.leggingsDiamond@0, 1xitem.bootsDiamond@0, 1xitem.helmetGold@0, 1xitem.chestplateGold@0, 1xitem.leggingsGold@0, 1xitem.bootsGold@0, 1xitem.flint@0, 1xitem.porkchopRaw@0, 1xitem.porkchopCooked@0, 1xitem.painting@0, 1xitem.appleGold@0, 1xitem.appleGold@1, 1xitem.sign@0, 1xitem.doorOak@0, 1xitem.bucket@0, 1xitem.bucketWater@0, 1xitem.bucketLava@0, 1xitem.minecart@0, 1xitem.saddle@0, 1xitem.doorIron@0, 1xitem.redstone@0, 1xitem.snowball@0, 1xitem.boat@0, 1xitem.leather@0, 1xitem.milk@0, 1xitem.brick@0, 1xitem.clay@0, 1xitem.reeds@0, 1xitem.paper@0, 1xitem.book@0, 1xitem.slimeball@0, 1xitem.minecartChest@0, 1xitem.minecartFurnace@0, 1xitem.egg@0, 1xitem.compass@0, 1xitem.fishingRod@0, 1xitem.clock@0, 1xitem.yellowDust@0, 1xitem.fish@0, 1xitem.fish@1, 1xitem.fish@2, 1xitem.fish@3, 1xitem.fish@0, 1xitem.fish@1, 1xitem.dyePowder@0, 1xitem.dyePowder@1, 1xitem.dyePowder@2, 1xitem.dyePowder@3, 1xitem.dyePowder@4, 1xitem.dyePowder@5, 1xitem.dyePowder@6, 1xitem.dyePowder@7, 1xitem.dyePowder@8, 1xitem.dyePowder@9, 1xitem.dyePowder@10, 1xitem.dyePowder@11, 1xitem.dyePowder@12, 1xitem.dyePowder@13, 1xitem.dyePowder@14, 1xitem.dyePowder@15, 1xitem.bone@0, 1xitem.sugar@0, 1xitem.cake@0, 1xitem.bed@0, 1xitem.diode@0, 1xitem.cookie@0, 1xitem.map@0, 1xitem.shears@0, 1xitem.melon@0, 1xitem.seeds_pumpkin@0, 1xitem.seeds_melon@0, 1xitem.beefRaw@0, 1xitem.beefCooked@0, 1xitem.chickenRaw@0, 1xitem.chickenCooked@0, 1xitem.rottenFlesh@0, 1xitem.enderPearl@0, 1xitem.blazeRod@0, 1xitem.ghastTear@0, 1xitem.goldNugget@0, 1xitem.netherStalkSeeds@0, 1xitem.potion@0, 1xitem.potion@8193, 1xitem.potion@8225, 1xitem.potion@8257, 1xitem.potion@16385, 1xitem.potion@16417, 1xitem.potion@16449, 1xitem.potion@8194, 1xitem.potion@8226, 1xitem.potion@8258, 1xitem.potion@16386, 1xitem.potion@16418, 1xitem.potion@16450, 1xitem.potion@8227, 1xitem.potion@8259, 1xitem.potion@16419, 1xitem.potion@16451, 1xitem.potion@8196, 1xitem.potion@8228, 1xitem.potion@8260, 1xitem.potion@16388, 1xitem.potion@16420, 1xitem.potion@16452, 1xitem.potion@8261, 1xitem.potion@8229, 1xitem.potion@16453, 1xitem.potion@16421, 1xitem.potion@8230, 1xitem.potion@8262, 1xitem.potion@16422, 1xitem.potion@16454, 1xitem.potion@8232, 1xitem.potion@8264, 1xitem.potion@16424, 1xitem.potion@16456, 1xitem.potion@8201, 1xitem.potion@8233, 1xitem.potion@8265, 1xitem.potion@16393, 1xitem.potion@16425, 1xitem.potion@16457, 1xitem.potion@8234, 1xitem.potion@8266, 1xitem.potion@16426, 1xitem.potion@16458, 1xitem.potion@8267, 1xitem.potion@8235, 1xitem.potion@16459, 1xitem.potion@16427, 1xitem.potion@8268, 1xitem.potion@8236, 1xitem.potion@16460, 1xitem.potion@16428, 1xitem.potion@8237, 1xitem.potion@8269, 1xitem.potion@16429, 1xitem.potion@16461, 1xitem.potion@8238, 1xitem.potion@8270, 1xitem.potion@16430, 1xitem.potion@16462, 1xitem.glassBottle@0, 1xitem.spiderEye@0, 1xitem.fermentedSpiderEye@0, 1xitem.blazePowder@0, 1xitem.magmaCream@0, 1xitem.brewingStand@0, 1xitem.cauldron@0, 1xitem.eyeOfEnder@0, 1xitem.speckledMelon@0, 1xitem.monsterPlacer@50, 1xitem.monsterPlacer@51, 1xitem.monsterPlacer@52, 1xitem.monsterPlacer@54, 1xitem.monsterPlacer@55, 1xitem.monsterPlacer@56, 1xitem.monsterPlacer@57, 1xitem.monsterPlacer@58, 1xitem.monsterPlacer@59, 1xitem.monsterPlacer@60, 1xitem.monsterPlacer@61, 1xitem.monsterPlacer@62, 1xitem.monsterPlacer@65, 1xitem.monsterPlacer@66, 1xitem.monsterPlacer@67, 1xitem.monsterPlacer@68, 1xitem.monsterPlacer@90, 1xitem.monsterPlacer@91, 1xitem.monsterPlacer@92, 1xitem.monsterPlacer@93, 1xitem.monsterPlacer@94, 1xitem.monsterPlacer@95, 1xitem.monsterPlacer@96, 1xitem.monsterPlacer@98, 1xitem.monsterPlacer@100, 1xitem.monsterPlacer@101, 1xitem.monsterPlacer@120, 1xitem.expBottle@0, 1xitem.fireball@0, 1xitem.writingBook@0, 1xitem.writtenBook@0, 1xitem.emerald@0, 1xitem.frame@0, 1xitem.flowerPot@0, 1xitem.carrots@0, 1xitem.potato@0, 1xitem.potatoBaked@0, 1xitem.potatoPoisonous@0, 1xitem.emptyMap@0, 1xitem.carrotGolden@0, 1xitem.skull@0, 1xitem.skull@1, 1xitem.skull@2, 1xitem.skull@3, 1xitem.skull@4, 1xitem.carrotOnAStick@0, 1xitem.netherStar@0, 1xitem.pumpkinPie@0, 1xitem.fireworks@0, 1xitem.fireworksCharge@0, 1xitem.enchantedBook@0, 1xitem.comparator@0, 1xitem.netherbrick@0, 1xitem.netherquartz@0, 1xitem.minecartTnt@0, 1xitem.minecartHopper@0, 1xitem.prismarineShard@0, 1xitem.prismarineCrystals@0, 1xitem.rabbitRaw@0, 1xitem.rabbitCooked@0, 1xitem.rabbitStew@0, 1xitem.rabbitFoot@0, 1xitem.rabbitHide@0, 1xitem.armorStand@0, 1xitem.horsearmormetal@0, 1xitem.horsearmorgold@0, 1xitem.horsearmordiamond@0, 1xitem.leash@0, 1xitem.nameTag@0, 1xitem.minecartCommandBlock@0, 1xitem.muttonRaw@0, 1xitem.muttonCooked@0, 1xtile.banner@15, 1xtile.banner@14, 1xtile.banner@13, 1xtile.banner@12, 1xtile.banner@11, 1xtile.banner@10, 1xtile.banner@9, 1xtile.banner@8, 1xtile.banner@7, 1xtile.banner@6, 1xtile.banner@5, 1xtile.banner@4, 1xtile.banner@3, 1xtile.banner@2, 1xtile.banner@1, 1xtile.banner@0, 1xitem.doorSpruce@0, 1xitem.doorBirch@0, 1xitem.doorJungle@0, 1xitem.doorAcacia@0, 1xitem.doorDarkOak@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.cowhide@0, 1xitem.sheepskin@0, 1xitem.pigskin@0, 1xitem.horsehide@0, 1xitem.swordExtended@0, 1xitem.spawn_egg_Test Pig@0]

 

 

Here you can see it recognizes my item has NBT and what the contents of the NBT are:

 

 

[21:42:00] [Client thread/INFO] [sTDOUT]: [com.blogspot.jabelarminecraft.blocksmith.proxy.ClientProxy:getItemListPayload:298]: The stack 1xitem.sheepskin@0 has NBT = {TargetLock:"test",}

 

 

Here is the contents of the packet payload:

 

 

[21:42:00] [Client thread/INFO] [sTDOUT]: [com.blogspot.jabelarminecraft.blocksmith.proxy.ClientProxy:getItemListPayload:306]: Item list payload = 1 0 false 1 1 false 1 2 false 1 3 false 1 4 false 1 5 false 1 6 false 2 0 false 3 0 false 3 1 false 3 2 false 4 0 false 5 0 false 5 1 false 5 2 false 5 3 false 5 4 false 5 5 false 6 0 false 6 1 false 6 2 false 6 3 false 6 4 false 6 5 false 7 0 false 12 0 false 12 1 false 13 0 false 14 0 false 15 0 false 16 0 false 17 0 false 17 1 false 17 2 false 17 3 false 18 0 false 18 1 false 18 2 false 18 3 false 19 0 false 19 1 false 20 0 false 21 0 false 22 0 false 23 0 false 24 0 false 24 1 false 24 2 false 25 0 false 27 0 false 28 0 false 29 0 false 30 0 false 31 1 false 31 2 false 32 0 false 33 0 false 35 0 false 35 1 false 35 2 false 35 3 false 35 4 false 35 5 false 35 6 false 35 7 false 35 8 false 35 9 false 35 10 false 35 11 false 35 12 false 35 13 false 35 14 false 35 15 false 37 0 false 38 0 false 38 1 false 38 2 false 38 3 false 38 4 false 38 5 false 38 6 false 38 7 false 38 8 false 39 0 false 40 0 false 41 0 false 42 0 false 44 0 false 44 1 false 44 3 false 44 4 false 44 5 false 44 6 false 44 7 false 45 0 false 46 0 false 47 0 false 48 0 false 49 0 false 50 0 false 52 0 false 53 0 false 54 0 false 56 0 false 57 0 false 58 0 false 60 0 false 61 0 false 62 0 false 65 0 false 66 0 false 67 0 false 69 0 false 70 0 false 72 0 false 73 0 false 76 0 false 77 0 false 78 0 false 79 0 false 80 0 false 81 0 false 82 0 false 84 0 false 85 0 false 86 0 false 87 0 false 88 0 false 89 0 false 91 0 false 95 0 false 95 1 false 95 2 false 95 3 false 95 4 false 95 5 false 95 6 false 95 7 false 95 8 false 95 9 false 95 10 false 95 11 false 95 12 false 95 13 false 95 14 false 95 15 false 96 0 false 97 0 false 97 1 false 97 2 false 97 3 false 97 4 false 97 5 false 98 0 false 98 1 false 98 2 false 98 3 false 99 0 false 100 0 false 101 0 false 102 0 false 103 0 false 106 0 false 107 0 false 108 0 false 109 0 false 110 0 false 111 0 false 112 0 false 113 0 false 114 0 false 116 0 false 120 0 false 121 0 false 122 0 false 123 0 false 126 0 false 126 1 false 126 2 false 126 3 false 126 4 false 126 5 false 128 0 false 129 0 false 130 0 false 131 0 false 133 0 false 134 0 false 135 0 false 136 0 false 137 0 false 138 0 false 139 0 false 139 1 false 143 0 false 145 0 false 145 1 false 145 2 false 146 0 false 147 0 false 148 0 false 151 0 false 152 0 false 153 0 false 154 0 false 155 0 false 155 1 false 155 2 false 156 0 false 157 0 false 158 0 false 159 0 false 159 1 false 159 2 false 159 3 false 159 4 false 159 5 false 159 6 false 159 7 false 159 8 false 159 9 false 159 10 false 159 11 false 159 12 false 159 13 false 159 14 false 159 15 false 160 0 false 160 1 false 160 2 false 160 3 false 160 4 false 160 5 false 160 6 false 160 7 false 160 8 false 160 9 false 160 10 false 160 11 false 160 12 false 160 13 false 160 14 false 160 15 false 161 0 false 161 1 false 162 0 false 162 1 false 163 0 false 164 0 false 165 0 false 166 0 false 167 0 false 168 0 false 168 1 false 168 2 false 169 0 false 170 0 false 171 0 false 171 1 false 171 2 false 171 3 false 171 4 false 171 5 false 171 6 false 171 7 false 171 8 false 171 9 false 171 10 false 171 11 false 171 12 false 171 13 false 171 14 false 171 15 false 172 0 false 173 0 false 174 0 false 175 0 false 175 1 false 175 2 false 175 3 false 175 4 false 175 5 false 179 0 false 179 1 false 179 2 false 180 0 false 182 0 false 183 0 false 184 0 false 185 0 false 186 0 false 187 0 false 188 0 false 189 0 false 190 0 false 191 0 false 192 0 false 198 0 false 199 0 false 200 0 false 201 0 false 202 0 false 203 0 false 256 0 false 257 0 false 258 0 false 259 0 false 260 0 false 261 0 false 262 0 false 263 0 false 263 1 false 264 0 false 265 0 false 266 0 false 267 0 false 268 0 false 269 0 false 270 0 false 271 0 false 272 0 false 273 0 false 274 0 false 275 0 false 276 0 false 277 0 false 278 0 false 279 0 false 280 0 false 281 0 false 282 0 false 283 0 false 284 0 false 285 0 false 286 0 false 287 0 false 288 0 false 289 0 false 290 0 false 291 0 false 292 0 false 293 0 false 294 0 false 295 0 false 296 0 false 297 0 false 298 0 false 299 0 false 300 0 false 301 0 false 302 0 false 303 0 false 304 0 false 305 0 false 306 0 false 307 0 false 308 0 false 309 0 false 310 0 false 311 0 false 312 0 false 313 0 false 314 0 false 315 0 false 316 0 false 317 0 false 318 0 false 319 0 false 320 0 false 321 0 false 322 0 false 322 1 false 323 0 false 324 0 false 325 0 false 326 0 false 327 0 false 328 0 false 329 0 false 330 0 false 331 0 false 332 0 false 333 0 false 334 0 false 335 0 false 336 0 false 337 0 false 338 0 false 339 0 false 340 0 false 341 0 false 342 0 false 343 0 false 344 0 false 345 0 false 346 0 false 347 0 false 348 0 false 349 0 false 349 1 false 349 2 false 349 3 false 350 0 false 350 1 false 351 0 false 351 1 false 351 2 false 351 3 false 351 4 false 351 5 false 351 6 false 351 7 false 351 8 false 351 9 false 351 10 false 351 11 false 351 12 false 351 13 false 351 14 false 351 15 false 352 0 false 353 0 false 354 0 false 355 0 false 356 0 false 357 0 false 358 0 false 359 0 false 360 0 false 361 0 false 362 0 false 363 0 false 364 0 false 365 0 false 366 0 false 367 0 false 368 0 false 369 0 false 370 0 false 371 0 false 372 0 false 373 0 false 373 8193 false 373 8225 false 373 8257 false 373 16385 false 373 16417 false 373 16449 false 373 8194 false 373 8226 false 373 8258 false 373 16386 false 373 16418 false 373 16450 false 373 8227 false 373 8259 false 373 16419 false 373 16451 false 373 8196 false 373 8228 false 373 8260 false 373 16388 false 373 16420 false 373 16452 false 373 8261 false 373 8229 false 373 16453 false 373 16421 false 373 8230 false 373 8262 false 373 16422 false 373 16454 false 373 8232 false 373 8264 false 373 16424 false 373 16456 false 373 8201 false 373 8233 false 373 8265 false 373 16393 false 373 16425 false 373 16457 false 373 8234 false 373 8266 false 373 16426 false 373 16458 false 373 8267 false 373 8235 false 373 16459 false 373 16427 false 373 8268 false 373 8236 false 373 16460 false 373 16428 false 373 8237 false 373 8269 false 373 16429 false 373 16461 false 373 8238 false 373 8270 false 373 16430 false 373 16462 false 374 0 false 375 0 false 376 0 false 377 0 false 378 0 false 379 0 false 380 0 false 381 0 false 382 0 false 383 50 false 383 51 false 383 52 false 383 54 false 383 55 false 383 56 false 383 57 false 383 58 false 383 59 false 383 60 false 383 61 false 383 62 false 383 65 false 383 66 false 383 67 false 383 68 false 383 90 false 383 91 false 383 92 false 383 93 false 383 94 false 383 95 false 383 96 false 383 98 false 383 100 false 383 101 false 383 120 false 384 0 false 385 0 false 386 0 false 387 0 false 388 0 false 389 0 false 390 0 false 391 0 false 392 0 false 393 0 false 394 0 false 395 0 false 396 0 false 397 0 false 397 1 false 397 2 false 397 3 false 397 4 false 398 0 false 399 0 false 400 0 false 401 0 false 402 0 false 403 0 false 404 0 false 405 0 false 406 0 false 407 0 false 408 0 false 409 0 false 410 0 false 411 0 false 412 0 false 413 0 false 414 0 false 415 0 false 416 0 false 417 0 false 418 0 false 419 0 false 420 0 false 421 0 false 422 0 false 423 0 false 424 0 false 425 15 false 425 14 false 425 13 false 425 12 false 425 11 false 425 10 false 425 9 false 425 8 false 425 7 false 425 6 false 425 5 false 425 4 false 425 3 false 425 2 false 425 1 false 425 0 false 427 0 false 428 0 false 429 0 false 430 0 false 431 0 false 2256 0 false 2257 0 false 2258 0 false 2259 0 false 2260 0 false 2261 0 false 2262 0 false 2263 0 false 2264 0 false 2265 0 false 2266 0 false 2267 0 false 4096 0 false 4097 0 true = {TargetLock:"test",} 4098 0 false 4099 0 false 4100 0 false 4101 0 false

 

 

 

Here you can see that the receiving side recognizes my item with NBT and gets the correct NBT content:

 

 

[21:42:00] [Client thread/INFO] [sTDOUT]: [com.blogspot.jabelarminecraft.blocksmith.proxy.ClientProxy:getCompleteItemStackList:333]: The stack 1xitem.sheepskin@0 has NBT = {TargetLock:"test",}

 

 

And finally here is the reconstructed ItemStack list, which you can see perfectly matches the one that was sent:

 

 

[21:42:00] [Client thread/INFO] [sTDOUT]: [com.blogspot.jabelarminecraft.blocksmith.proxy.ClientProxy:getCompleteItemStackList:343]: [1xtile.stone@0, 1xtile.stone@1, 1xtile.stone@2, 1xtile.stone@3, 1xtile.stone@4, 1xtile.stone@5, 1xtile.stone@6, 1xtile.grass@0, 1xtile.dirt@0, 1xtile.dirt@1, 1xtile.dirt@2, 1xtile.stonebrick@0, 1xtile.wood@0, 1xtile.wood@1, 1xtile.wood@2, 1xtile.wood@3, 1xtile.wood@4, 1xtile.wood@5, 1xtile.sapling@0, 1xtile.sapling@1, 1xtile.sapling@2, 1xtile.sapling@3, 1xtile.sapling@4, 1xtile.sapling@5, 1xtile.bedrock@0, 1xtile.sand@0, 1xtile.sand@1, 1xtile.gravel@0, 1xtile.oreGold@0, 1xtile.oreIron@0, 1xtile.oreCoal@0, 1xtile.log@0, 1xtile.log@1, 1xtile.log@2, 1xtile.log@3, 1xtile.leaves@0, 1xtile.leaves@1, 1xtile.leaves@2, 1xtile.leaves@3, 1xtile.sponge@0, 1xtile.sponge@1, 1xtile.glass@0, 1xtile.oreLapis@0, 1xtile.blockLapis@0, 1xtile.dispenser@0, 1xtile.sandStone@0, 1xtile.sandStone@1, 1xtile.sandStone@2, 1xtile.musicBlock@0, 1xtile.goldenRail@0, 1xtile.detectorRail@0, 1xtile.pistonStickyBase@0, 1xtile.web@0, 1xtile.tallgrass@1, 1xtile.tallgrass@2, 1xtile.deadbush@0, 1xtile.pistonBase@0, 1xtile.cloth@0, 1xtile.cloth@1, 1xtile.cloth@2, 1xtile.cloth@3, 1xtile.cloth@4, 1xtile.cloth@5, 1xtile.cloth@6, 1xtile.cloth@7, 1xtile.cloth@8, 1xtile.cloth@9, 1xtile.cloth@10, 1xtile.cloth@11, 1xtile.cloth@12, 1xtile.cloth@13, 1xtile.cloth@14, 1xtile.cloth@15, 1xtile.flower1@0, 1xtile.flower2@0, 1xtile.flower2@1, 1xtile.flower2@2, 1xtile.flower2@3, 1xtile.flower2@4, 1xtile.flower2@5, 1xtile.flower2@6, 1xtile.flower2@7, 1xtile.flower2@8, 1xtile.mushroom@0, 1xtile.mushroom@0, 1xtile.blockGold@0, 1xtile.blockIron@0, 1xtile.stoneSlab@0, 1xtile.stoneSlab@1, 1xtile.stoneSlab@3, 1xtile.stoneSlab@4, 1xtile.stoneSlab@5, 1xtile.stoneSlab@6, 1xtile.stoneSlab@7, 1xtile.brick@0, 1xtile.tnt@0, 1xtile.bookshelf@0, 1xtile.stoneMoss@0, 1xtile.obsidian@0, 1xtile.torch@0, 1xtile.mobSpawner@0, 1xtile.stairsWood@0, 1xtile.chest@0, 1xtile.oreDiamond@0, 1xtile.blockDiamond@0, 1xtile.workbench@0, 1xtile.farmland@0, 1xtile.furnace@0, 1xtile.furnace@0, 1xtile.ladder@0, 1xtile.rail@0, 1xtile.stairsStone@0, 1xtile.lever@0, 1xtile.pressurePlateStone@0, 1xtile.pressurePlateWood@0, 1xtile.oreRedstone@0, 1xtile.notGate@0, 1xtile.button@0, 1xtile.snow@0, 1xtile.ice@0, 1xtile.snow@0, 1xtile.cactus@0, 1xtile.clay@0, 1xtile.jukebox@0, 1xtile.fence@0, 1xtile.pumpkin@0, 1xtile.hellrock@0, 1xtile.hellsand@0, 1xtile.lightgem@0, 1xtile.litpumpkin@0, 1xtile.stainedGlass@0, 1xtile.stainedGlass@1, 1xtile.stainedGlass@2, 1xtile.stainedGlass@3, 1xtile.stainedGlass@4, 1xtile.stainedGlass@5, 1xtile.stainedGlass@6, 1xtile.stainedGlass@7, 1xtile.stainedGlass@8, 1xtile.stainedGlass@9, 1xtile.stainedGlass@10, 1xtile.stainedGlass@11, 1xtile.stainedGlass@12, 1xtile.stainedGlass@13, 1xtile.stainedGlass@14, 1xtile.stainedGlass@15, 1xtile.trapdoor@0, 1xtile.monsterStoneEgg@0, 1xtile.monsterStoneEgg@1, 1xtile.monsterStoneEgg@2, 1xtile.monsterStoneEgg@3, 1xtile.monsterStoneEgg@4, 1xtile.monsterStoneEgg@5, 1xtile.stonebricksmooth@0, 1xtile.stonebricksmooth@1, 1xtile.stonebricksmooth@2, 1xtile.stonebricksmooth@3, 1xtile.mushroom@0, 1xtile.mushroom@0, 1xtile.fenceIron@0, 1xtile.thinGlass@0, 1xtile.melon@0, 1xtile.vine@0, 1xtile.fenceGate@0, 1xtile.stairsBrick@0, 1xtile.stairsStoneBrickSmooth@0, 1xtile.mycel@0, 1xtile.waterlily@0, 1xtile.netherBrick@0, 1xtile.netherFence@0, 1xtile.stairsNetherBrick@0, 1xtile.enchantmentTable@0, 1xtile.endPortalFrame@0, 1xtile.whiteStone@0, 1xtile.dragonEgg@0, 1xtile.redstoneLight@0, 1xtile.woodSlab@0, 1xtile.woodSlab@1, 1xtile.woodSlab@2, 1xtile.woodSlab@3, 1xtile.woodSlab@4, 1xtile.woodSlab@5, 1xtile.stairsSandStone@0, 1xtile.oreEmerald@0, 1xtile.enderChest@0, 1xtile.tripWireSource@0, 1xtile.blockEmerald@0, 1xtile.stairsWoodSpruce@0, 1xtile.stairsWoodBirch@0, 1xtile.stairsWoodJungle@0, 1xtile.commandBlock@0, 1xtile.beacon@0, 1xtile.cobbleWall@0, 1xtile.cobbleWall@1, 1xtile.button@0, 1xtile.anvil@0, 1xtile.anvil@1, 1xtile.anvil@2, 1xtile.chestTrap@0, 1xtile.weightedPlate_light@0, 1xtile.weightedPlate_heavy@0, 1xtile.daylightDetector@0, 1xtile.blockRedstone@0, 1xtile.netherquartz@0, 1xtile.hopper@0, 1xtile.quartzBlock@0, 1xtile.quartzBlock@1, 1xtile.quartzBlock@2, 1xtile.stairsQuartz@0, 1xtile.activatorRail@0, 1xtile.dropper@0, 1xtile.clayHardenedStained@0, 1xtile.clayHardenedStained@1, 1xtile.clayHardenedStained@2, 1xtile.clayHardenedStained@3, 1xtile.clayHardenedStained@4, 1xtile.clayHardenedStained@5, 1xtile.clayHardenedStained@6, 1xtile.clayHardenedStained@7, 1xtile.clayHardenedStained@8, 1xtile.clayHardenedStained@9, 1xtile.clayHardenedStained@10, 1xtile.clayHardenedStained@11, 1xtile.clayHardenedStained@12, 1xtile.clayHardenedStained@13, 1xtile.clayHardenedStained@14, 1xtile.clayHardenedStained@15, 1xtile.thinStainedGlass@0, 1xtile.thinStainedGlass@1, 1xtile.thinStainedGlass@2, 1xtile.thinStainedGlass@3, 1xtile.thinStainedGlass@4, 1xtile.thinStainedGlass@5, 1xtile.thinStainedGlass@6, 1xtile.thinStainedGlass@7, 1xtile.thinStainedGlass@8, 1xtile.thinStainedGlass@9, 1xtile.thinStainedGlass@10, 1xtile.thinStainedGlass@11, 1xtile.thinStainedGlass@12, 1xtile.thinStainedGlass@13, 1xtile.thinStainedGlass@14, 1xtile.thinStainedGlass@15, 1xtile.leaves@0, 1xtile.leaves@1, 1xtile.log@0, 1xtile.log@1, 1xtile.stairsWoodAcacia@0, 1xtile.stairsWoodDarkOak@0, 1xtile.slime@0, 1xtile.barrier@0, 1xtile.ironTrapdoor@0, 1xtile.prismarine@0, 1xtile.prismarine@1, 1xtile.prismarine@2, 1xtile.seaLantern@0, 1xtile.hayBlock@0, 1xtile.woolCarpet@0, 1xtile.woolCarpet@1, 1xtile.woolCarpet@2, 1xtile.woolCarpet@3, 1xtile.woolCarpet@4, 1xtile.woolCarpet@5, 1xtile.woolCarpet@6, 1xtile.woolCarpet@7, 1xtile.woolCarpet@8, 1xtile.woolCarpet@9, 1xtile.woolCarpet@10, 1xtile.woolCarpet@11, 1xtile.woolCarpet@12, 1xtile.woolCarpet@13, 1xtile.woolCarpet@14, 1xtile.woolCarpet@15, 1xtile.clayHardened@0, 1xtile.blockCoal@0, 1xtile.icePacked@0, 1xtile.doublePlant@0, 1xtile.doublePlant@1, 1xtile.doublePlant@2, 1xtile.doublePlant@3, 1xtile.doublePlant@4, 1xtile.doublePlant@5, 1xtile.redSandStone@0, 1xtile.redSandStone@1, 1xtile.redSandStone@2, 1xtile.stairsRedSandStone@0, 1xtile.stoneSlab2@0, 1xtile.spruceFenceGate@0, 1xtile.birchFenceGate@0, 1xtile.jungleFenceGate@0, 1xtile.darkOakFenceGate@0, 1xtile.acaciaFenceGate@0, 1xtile.spruceFence@0, 1xtile.birchFence@0, 1xtile.jungleFence@0, 1xtile.darkOakFence@0, 1xtile.acaciaFence@0, 1xtile.tanningrack@0, 1xtile.grinder@0, 1xtile.compactor@0, 1xtile.deconstructor@0, 1xtile.forge@0, 1xtile.movinglightsource@0, 1xitem.shovelIron@0, 1xitem.pickaxeIron@0, 1xitem.hatchetIron@0, 1xitem.flintAndSteel@0, 1xitem.apple@0, 1xitem.bow@0, 1xitem.arrow@0, 1xitem.coal@0, 1xitem.coal@1, 1xitem.diamond@0, 1xitem.ingotIron@0, 1xitem.ingotGold@0, 1xitem.swordIron@0, 1xitem.swordWood@0, 1xitem.shovelWood@0, 1xitem.pickaxeWood@0, 1xitem.hatchetWood@0, 1xitem.swordStone@0, 1xitem.shovelStone@0, 1xitem.pickaxeStone@0, 1xitem.hatchetStone@0, 1xitem.swordDiamond@0, 1xitem.shovelDiamond@0, 1xitem.pickaxeDiamond@0, 1xitem.hatchetDiamond@0, 1xitem.stick@0, 1xitem.bowl@0, 1xitem.mushroomStew@0, 1xitem.swordGold@0, 1xitem.shovelGold@0, 1xitem.pickaxeGold@0, 1xitem.hatchetGold@0, 1xitem.string@0, 1xitem.feather@0, 1xitem.sulphur@0, 1xitem.hoeWood@0, 1xitem.hoeStone@0, 1xitem.hoeIron@0, 1xitem.hoeDiamond@0, 1xitem.hoeGold@0, 1xitem.seeds@0, 1xitem.wheat@0, 1xitem.bread@0, 1xitem.helmetCloth@0, 1xitem.chestplateCloth@0, 1xitem.leggingsCloth@0, 1xitem.bootsCloth@0, 1xitem.helmetChain@0, 1xitem.chestplateChain@0, 1xitem.leggingsChain@0, 1xitem.bootsChain@0, 1xitem.helmetIron@0, 1xitem.chestplateIron@0, 1xitem.leggingsIron@0, 1xitem.bootsIron@0, 1xitem.helmetDiamond@0, 1xitem.chestplateDiamond@0, 1xitem.leggingsDiamond@0, 1xitem.bootsDiamond@0, 1xitem.helmetGold@0, 1xitem.chestplateGold@0, 1xitem.leggingsGold@0, 1xitem.bootsGold@0, 1xitem.flint@0, 1xitem.porkchopRaw@0, 1xitem.porkchopCooked@0, 1xitem.painting@0, 1xitem.appleGold@0, 1xitem.appleGold@1, 1xitem.sign@0, 1xitem.doorOak@0, 1xitem.bucket@0, 1xitem.bucketWater@0, 1xitem.bucketLava@0, 1xitem.minecart@0, 1xitem.saddle@0, 1xitem.doorIron@0, 1xitem.redstone@0, 1xitem.snowball@0, 1xitem.boat@0, 1xitem.leather@0, 1xitem.milk@0, 1xitem.brick@0, 1xitem.clay@0, 1xitem.reeds@0, 1xitem.paper@0, 1xitem.book@0, 1xitem.slimeball@0, 1xitem.minecartChest@0, 1xitem.minecartFurnace@0, 1xitem.egg@0, 1xitem.compass@0, 1xitem.fishingRod@0, 1xitem.clock@0, 1xitem.yellowDust@0, 1xitem.fish@0, 1xitem.fish@1, 1xitem.fish@2, 1xitem.fish@3, 1xitem.fish@0, 1xitem.fish@1, 1xitem.dyePowder@0, 1xitem.dyePowder@1, 1xitem.dyePowder@2, 1xitem.dyePowder@3, 1xitem.dyePowder@4, 1xitem.dyePowder@5, 1xitem.dyePowder@6, 1xitem.dyePowder@7, 1xitem.dyePowder@8, 1xitem.dyePowder@9, 1xitem.dyePowder@10, 1xitem.dyePowder@11, 1xitem.dyePowder@12, 1xitem.dyePowder@13, 1xitem.dyePowder@14, 1xitem.dyePowder@15, 1xitem.bone@0, 1xitem.sugar@0, 1xitem.cake@0, 1xitem.bed@0, 1xitem.diode@0, 1xitem.cookie@0, 1xitem.map@0, 1xitem.shears@0, 1xitem.melon@0, 1xitem.seeds_pumpkin@0, 1xitem.seeds_melon@0, 1xitem.beefRaw@0, 1xitem.beefCooked@0, 1xitem.chickenRaw@0, 1xitem.chickenCooked@0, 1xitem.rottenFlesh@0, 1xitem.enderPearl@0, 1xitem.blazeRod@0, 1xitem.ghastTear@0, 1xitem.goldNugget@0, 1xitem.netherStalkSeeds@0, 1xitem.potion@0, 1xitem.potion@1, 1xitem.potion@33, 1xitem.potion@65, 1xitem.potion@1, 1xitem.potion@33, 1xitem.potion@65, 1xitem.potion@2, 1xitem.potion@34, 1xitem.potion@66, 1xitem.potion@2, 1xitem.potion@34, 1xitem.potion@66, 1xitem.potion@35, 1xitem.potion@67, 1xitem.potion@35, 1xitem.potion@67, 1xitem.potion@4, 1xitem.potion@36, 1xitem.potion@68, 1xitem.potion@4, 1xitem.potion@36, 1xitem.potion@68, 1xitem.potion@69, 1xitem.potion@37, 1xitem.potion@69, 1xitem.potion@37, 1xitem.potion@38, 1xitem.potion@70, 1xitem.potion@38, 1xitem.potion@70, 1xitem.potion@40, 1xitem.potion@72, 1xitem.potion@40, 1xitem.potion@72, 1xitem.potion@9, 1xitem.potion@41, 1xitem.potion@73, 1xitem.potion@9, 1xitem.potion@41, 1xitem.potion@73, 1xitem.potion@42, 1xitem.potion@74, 1xitem.potion@42, 1xitem.potion@74, 1xitem.potion@75, 1xitem.potion@43, 1xitem.potion@75, 1xitem.potion@43, 1xitem.potion@76, 1xitem.potion@44, 1xitem.potion@76, 1xitem.potion@44, 1xitem.potion@45, 1xitem.potion@77, 1xitem.potion@45, 1xitem.potion@77, 1xitem.potion@46, 1xitem.potion@78, 1xitem.potion@46, 1xitem.potion@78, 1xitem.glassBottle@0, 1xitem.spiderEye@0, 1xitem.fermentedSpiderEye@0, 1xitem.blazePowder@0, 1xitem.magmaCream@0, 1xitem.brewingStand@0, 1xitem.cauldron@0, 1xitem.eyeOfEnder@0, 1xitem.speckledMelon@0, 1xitem.monsterPlacer@50, 1xitem.monsterPlacer@51, 1xitem.monsterPlacer@52, 1xitem.monsterPlacer@54, 1xitem.monsterPlacer@55, 1xitem.monsterPlacer@56, 1xitem.monsterPlacer@57, 1xitem.monsterPlacer@58, 1xitem.monsterPlacer@59, 1xitem.monsterPlacer@60, 1xitem.monsterPlacer@61, 1xitem.monsterPlacer@62, 1xitem.monsterPlacer@65, 1xitem.monsterPlacer@66, 1xitem.monsterPlacer@67, 1xitem.monsterPlacer@68, 1xitem.monsterPlacer@90, 1xitem.monsterPlacer@91, 1xitem.monsterPlacer@92, 1xitem.monsterPlacer@93, 1xitem.monsterPlacer@94, 1xitem.monsterPlacer@95, 1xitem.monsterPlacer@96, 1xitem.monsterPlacer@98, 1xitem.monsterPlacer@100, 1xitem.monsterPlacer@101, 1xitem.monsterPlacer@120, 1xitem.expBottle@0, 1xitem.fireball@0, 1xitem.writingBook@0, 1xitem.writtenBook@0, 1xitem.emerald@0, 1xitem.frame@0, 1xitem.flowerPot@0, 1xitem.carrots@0, 1xitem.potato@0, 1xitem.potatoBaked@0, 1xitem.potatoPoisonous@0, 1xitem.emptyMap@0, 1xitem.carrotGolden@0, 1xitem.skull@0, 1xitem.skull@1, 1xitem.skull@2, 1xitem.skull@3, 1xitem.skull@4, 1xitem.carrotOnAStick@0, 1xitem.netherStar@0, 1xitem.pumpkinPie@0, 1xitem.fireworks@0, 1xitem.fireworksCharge@0, 1xitem.enchantedBook@0, 1xitem.comparator@0, 1xitem.netherbrick@0, 1xitem.netherquartz@0, 1xitem.minecartTnt@0, 1xitem.minecartHopper@0, 1xitem.prismarineShard@0, 1xitem.prismarineCrystals@0, 1xitem.rabbitRaw@0, 1xitem.rabbitCooked@0, 1xitem.rabbitStew@0, 1xitem.rabbitFoot@0, 1xitem.rabbitHide@0, 1xitem.armorStand@0, 1xitem.horsearmormetal@0, 1xitem.horsearmorgold@0, 1xitem.horsearmordiamond@0, 1xitem.leash@0, 1xitem.nameTag@0, 1xitem.minecartCommandBlock@0, 1xitem.muttonRaw@0, 1xitem.muttonCooked@0, 1xtile.banner@15, 1xtile.banner@14, 1xtile.banner@13, 1xtile.banner@12, 1xtile.banner@11, 1xtile.banner@10, 1xtile.banner@9, 1xtile.banner@8, 1xtile.banner@7, 1xtile.banner@6, 1xtile.banner@5, 1xtile.banner@4, 1xtile.banner@3, 1xtile.banner@2, 1xtile.banner@1, 1xtile.banner@0, 1xitem.doorSpruce@0, 1xitem.doorBirch@0, 1xitem.doorJungle@0, 1xitem.doorAcacia@0, 1xitem.doorDarkOak@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.record@0, 1xitem.cowhide@0, 1xitem.sheepskin@0, 1xitem.pigskin@0, 1xitem.horsehide@0, 1xitem.swordExtended@0, 1xitem.spawn_egg_Test Pig@0]

 

 

 

Overall you can see that the code is really quite simple. The main thing is to come up with a mapping into the payload that can be decoded in the far end. The format I used was:

a) the Item ID as an int

b) the Item metadata as an int

c) a boolean for whether or not there is NBT

d) the NBT if any

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

My system is functional for vanilla now :)

 

It doesn't handle nbt data yet, but this is the next thing i am going to work on.

 

This is the itemStack list it generated on the server:

http://pastebin.com/KZ78zkhE

 

the 2048 indicates the amount of bytes used to transfer the data to the server (I found this number using buf.array().length, which i am guessing is the amount of bytes... but 2048 almost seems too perfect ;))

 

I am using the same mapping system i posted earlier, i just wrote a system to increase efficiency after the first mapping, and to send it all to the server, if you're interested in any of those i will happily post them, but i think they're quite generic.

 

Now i will implement nbt support.

I did know about ByteBufUtils, but i want to look for patterns in the nbtData before i send it to make sure i send the least amount of data needed.

I made the Mob Particles mod, you can check it out here: http://www.minecraftforum.net/topic/2709242-172-forge-mob-particles/

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • As the title says i keep on crashing on forge 1.20.1 even without any mods downloaded, i have the latest drivers (nvidia) and vanilla minecraft works perfectly fine for me logs: https://pastebin.com/5UR01yG9
    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
    • It is an issue with quark - update it to this build: https://www.curseforge.com/minecraft/mc-mods/quark/files/3642325
    • Remove Instant Massive Structures Mod from your server     Add new crash-reports with sites like https://paste.ee/  
  • Topics

×
×
  • Create New...

Important Information

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