Jump to content

wesserboy

Members
  • Posts

    71
  • Joined

  • Last visited

Everything posted by wesserboy

  1. You can write a byte to the NBTTagCompound, and give it a certain value, this value would be the 'ID' of the spell, this way you can use something like a switch with that value to determine what spell should be used. (If you plan on using multiple spells this is an easier system than writing a boolean for each and every spell) java.lang.NullPointerException: Ticking memory connection at com.OlympiansMod.Item.RandomWand.onItemRightClick(RandomWand.java:26) some object you're using on line 26 of randomWand.java is null. I'm guessing it's this line: int spell = itemstack.stackTagCompound.getInteger("Spell"); if this is the line, the stackTagCompound is probably null. You don't seem to do anything special in onItemUseFirst, except setting the tagCompound if needed, why don't you just put that code into your onItemRightClick method? this will probably also fix your nullpointer (unless my guess about the line was wrong) Side notes: stack.getTagCompound() == null You can use stack.hasTagCompound() for this stack.stackTagCompound You are still referencing the direct field here public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer player) Add @Override annotations to the methods you override from superclasses, it makes sure you actually override something, because it will throw an error at you if you don't. (It's a safety measure)
  2. 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
  3. 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
  4. As far as i can see, your reading and writing to and from the nbt is correct. However, in onItemUseFirst you are always creating a new compound, even if the stack already had one, so you're basically replacing all the data it had with new empty data... You are right that the stackTagCompound can be null and in that case you must create a new one, you can check this using stack.hasTagCompound() (or something similar, i don't have my IDE open). If this is false you should create a new one, else you should just use the one the itemStack already has. Some side notes: * You are referencing the direct field of the itemStack (stack.stackTagCompound), whilst this will work, it's a good habit to use getter and setter methods instead of direct fields. * I don't see you using the damageValue anywhere, if you're not using this, can't you use that instead of nbt? * Why are you writing integers to define the state??? If you want to continue the way you are now you can at least replace them with booleans, but even better would be just to have a single byte which contains the id of the current active spell. (Or if you have more than 127 spells you can use a short )
  5. 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.
  6. When you register your worldGenerator (using GameRegistry.registerWorldGenerator()), you can specify a 'weight', which basically means the higher the number, the later your generator will generate. If you use a high number there (Integer.MAX_VALUE ) your generator should be the last one to add it's worldGen.
  7. When i wrote my previous post, i hadn't read this yet: you can scrape problem n. 2 off the list
  8. 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
  9. 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
  10. 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?
  11. 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. 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.
  12. 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........
  13. 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? 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. 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.
  14. 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.
  15. ahh, I think I understand what you mean now, this will however not work: You can get the boolean to know if an item has subtypes on the server, you can however not get those subtypes on the server, this is why I request those subtypes from the client. This is another approach i thought of which is similar to yours, which also doesn't involve as much client data on the server: - Create a list of all items on the server. (excl. subitems) - Get a random item to assign. - If the item has subitems, send it to the client --> let the client generate a random subItem and send it back to the server --> assign itemstack as challenge. - else just make a new itemStack with damagevalue 0 and assign this to the player. (no client interaction at all) This would not work as i would like it to and i will tell you why: First you get a random item, if this item doesn't have subitems it's immediately assigned, so the chance to get that itemStack as a challenge is 1 / amount_of_items. if it does have subItems, one subitem is randomized, so the chance of getting that itemStack as a challenge is (1 / amount_of_items) * (1 / amount_of_subItems) = 1 / (items * subItems). This would make it so some itemStacks have a higher chance of being the challenge than others. A way to fix this would be to add the items that have subItems once to the list for every subItem. then the chance of getting a certain subItem would be subItems / items * subItems = 1 / items (the same as all the other items) But as far as i know there is no way to get the amount of subitems an item has, and this makes it so this approach would not work (as intended).
  16. I am checking if an item actually has subItems on the server (using item.getHasSubtypes(), which strangely enough isn't ClientSide only), before i add it to the list that is being sent to the client, and I have a blackList system in the config file, which gives servers more control over what items end up in the list, but other than that you are totally right... I could maybe implement a system that checks whether the items of the ItemStacks were actually sent to the client, as an extra security measure. However, I am not sure if it's worth the effort, I am only using this list of itemStacks to assign a 'ChallengeStack' to the player, the player should then try to acquire this itemStack. I am checking this in the ItemPickupEvent, ItemCraftedEvent and ItemSmeltedEvent. If the itemStack the player picked up/crafted/smelted is equal to the assigned itemStack the player gets a message notifying him of completing the challenge, and a soundeffect starts playing. After that i just assign a new ItemStack as a new challenge. Since I am never giving the player any of these itemStacks, never spawning them in the world and never placing blocks, I think the level of control the client gets is very little, which is why i don't think it's that big of a problem. but if I missed something, be sure to tell me
  17. I am not quite sure how hacked clients work and what exploits they are using to achieve what they're doing, but is there a way for me to make my mod more secure? Maybe general rules to stick to? Or some kind of technique I am unfamiliar with? Preferably something that doesn't involve me having to rewrite my list construction (again), unless it's really necessary...
  18. This is what I am doing after the list is constructed, I only do this the first time any client joins, because i need a clientSide only method to construct the item list. I store this list on the server and after that point any other clients joining will not get this packet.
  19. after a good night of rest i have figured it out... It was an incredibly stupid mistake. In my handleClientSide method I was using the field of the object handleClientSide was being called from, instead of the field of the message parameter. Moral of the story: Don't code if you're tired, it can only end badly...
  20. My idea is to make a mod which assigns a random item to each player to acquire, to give the player something to work towards whilst playing. I need to assign this itemStack on the server (for obvious reasons). It would be silly if the mod would only ever assign bonemeal, instead of all possible dyes, and only oak wood instead of all types of planks/logs. This is why i need to index the subItems of these items.
  21. This is the code I am currently using for my packet from server to client: https://gist.github.com/wesserboy/dc7f1f88afb3b83aaac6 (In this code i am still sending multiple small packets to the server, I am changing that as we speak, however this can not be related to the issue, since the code crashes before this is done) This is the stackTrace of the nullPointer: http://pastebin.com/cnGGaVuV (from what i can tell it's the same crash happening three times in a row, that's why i've added spaces in between the three individual stackTraces) Line 76 (The for loop in the handleClientSide() method) crashes with a nullPointer. I started to trace this variable backwards (that's why there's a lot of System.out.println()) and this is what i found: on line 74 (the beginning of the handleClientSide() method) the items field is null, this is obviously what causes the nullPointer. However, on line 46 (the end of the fromBytes() method) the items field is not null... I am not quite sure how packets work behind the scenes, but to my knowledge these methods should follow each other with no changes made in between... Also, it seems very odd to me that a stackTrace refers to a package declaration... (line 4 of the stackTrace)
  22. 1. I need a list of all possible items on the server, to achieve this I'm iterating through the itemRegistry, and if an Item has subItems, i need to get those, otherwise i'm just adding a stack with damagevalue 1. the Item.getSubItems() method is ClientSide only, and this is why i need to process this data on the client. 2. This is what i needed to know, I am currently sending one big packet from the server to the client, and i am responding with a lot of little packets, but i will change this out to one big packet as well. 3. You are right . The crash is happening on the client when handeling the packet. It's a really strange nullPointer and i thought that data maybe got lost because i was using such big packets to the client. Since this is the way to go, this clearly doesn't cause my problems, and i will post more info about the crash in the next post, because i can't seem to figure out the cause myself...
  23. For my current mod I need to process data on the client, and send the results back to the server. I am using a system of packets to achieve this, however, I'm not sure what's the best/most efficient way to achieve my goal. The first time any client connects to a server, I will send a packet/packets containing the data I need that client to process. After its done I send the result(s) back to the server via another packet/other packets. On the server I will save these results and after that point no more packets will be sent. As you can probably tell from the way I describe my problem I am not sure what's the most efficient way to achieve this. This is where my question comes in: If you need to process (a lot) of data, is it better to send one big packet, containing all the data which has to be processed, and send a big packet back containing all the results, or is it better to send little packets which each contain a single piece of the data, and send little packets back containing the individual results? my current code crashes every time I join a (new) world, I think this crash is related to my question because i am currently using a mix of big and little packets... but if you need a (not yet working) piece of my code, i will happily supply it.
  24. MineMaarten has a tutorial about multiblocks where he explains a similar system like you want, you can find it
  25. Thank you for your explanation, I understand it a lot better now I had a look at renderStandardBlockWithAmbientOcclusion, but it looks really difficult, so I'll just leave it the way it is now. The difference is so small that it's probably not worth the effort anyway.
×
×
  • Create New...

Important Information

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