david.broto Posted February 14, 2012 Share Posted February 14, 2012 Hi there! I'm developing custom server with raknet to work with unigine. I can connect my unigine client code with my custom server code and stablish a connection but when I'm sending data to the server I get an ID_TIMESTAMP package id even if I send a different package Id. In unigine I do this: SharedData shared = class_manage(new SharedData()); shared.addField(50); shared.addField("SOME TEXT!"); network.send(shared,address); In my server i get an ID_TIMESTAMP package id (I can't recall if it was 21 or 27) So, I'm 100% sure i'm doing something wrong, or I'm at the middle of some process. Could you help me figure out what's happening here please? :) Thanks! Edit: I'm using raknet last stable build. Link to comment
Guest anet Posted February 15, 2012 Share Posted February 15, 2012 Unigine client application sends timestamped packets. In this case to get the real packet type you have to read data after ID_TIMESTAMP and timestamp itself. Here is a slightly tweaked code sample of getting a packet type taken from here: unsigned char GetPacketIdentifier(Packet *p) { if ((unsigned char)p->data[0] == ID_TIMESTAMP) return (unsigned char) p->data[sizeof(unsigned char) + sizeof(TimeMS)]; else return (unsigned char) p->data[0]; } Link to comment
david.broto Posted February 15, 2012 Author Share Posted February 15, 2012 So, i don't quite get it, it says it should work with sizeof(unsigned char) + sizeof(unsigned long) but it isn't till p->data+15 where my id 50 is found and the text is supposed to be found at p->data+16 right? But the text is at p->data+19. I atached a picture of memory snapshot. p->data starts at 0x816cb88. What am I missing? Could it be something related with endianness? Something with my raknet version? Thanks for your time :) PS: I'm using ubuntu 11.10, GNU GCC and Eclipse for C/C++ developers Link to comment
Guest anet Posted February 16, 2012 Share Posted February 16, 2012 Sorry, my previous answer was incorrect. If you get packet type the way it is done in the sample you will always get PT_CUSTOM. Here is the full scheme of SharedData serialization: PT_TIMESTMAP (unsigned char) timestamp (RakNet::Time = uint64_t) PT_CUSTOM (unsigned char) Number of fields in SharedData (uint8_t) (in your case it is 2) for (i = 0; i < Number of fileds in SharedData; i ++)Type of ith field (uint8_t) (in your case it is Unigine::Variable::INT = 0 for i = 0 and Unigine::Variable::STRING = 13 for i = 1) Value of ith field (50 and "SOME TEXT!") Thus, this is a sample of SharedData deserialization on the server side: bit_stream.Read(packet_type);if(packet_type == PT_TIMESTAMP) { bit_stream.Read(timestamp); bit_stream.Read(packet_type);}int num_fields = 0;int res = stream.ReadCasted<uint8_t,int>(num_fields);data.reserveFields(num_fields);for(int i = 0; i < num_fields; ++i) { Variable field; res = deserialize(field,stream); data.setField(i,field);} After that you can get your custom packet type this way: int custom_packet_type = shared_data.getField(0).getInt(); Exact serialization / deserialization code can be found in our SDK (both binary and source versions): source/plugins/Network/source/utils/NetworkUtilsRakNet.cpp - writeDataToBitStream and readDataFromBitStream functions source/plugins/Network/source/utils/SerializerRakNet.cpp Link to comment
david.broto Posted February 16, 2012 Author Share Posted February 16, 2012 Thanks! That was what I wanted :D I would suggest this info to be added at the networking area of the documentation. Thanks again :) Link to comment
Guest anet Posted February 16, 2012 Share Posted February 16, 2012 You are welcome :) I'll ask our technical writer ot add this info into documentation. Link to comment
david.broto Posted February 16, 2012 Author Share Posted February 16, 2012 One more question, could it be that unigine in x64 mode could send a uint64_t timestamp? Link to comment
Guest anet Posted February 17, 2012 Share Posted February 17, 2012 Oops, I was wrong again. Timestamp should always be a 64 bit integer (for 32 and 64 bit modes). Link to comment
david.broto Posted February 17, 2012 Author Share Posted February 17, 2012 Thanks, but once again I have some strange behaviour, I read an unsigned char (ID_TIMESTAMP), a RakNet::TimeUS (uint64_t) and then I have to skip 6 bytes to actually read my custom package id. Any idea what is the engine adding in those 6 bytes? In the example i posted before the skipped bytes values are 129 2 0 0 0 0 Thanks for your time! Link to comment
Guest anet Posted February 17, 2012 Share Posted February 17, 2012 129 is PT_CUSTOM packet type 2 should be a number of fields in SharedData 1 zero byte is a type of the first field (Unigine::Variable::INT = 0) 3 other bytes could be leading zeroes for your integer value (it should take 4 bytes in a bitstream) Link to comment
Guest anet Posted February 17, 2012 Share Posted February 17, 2012 What value do you get if you read your bitstream like this: bit_stream.Read(packet_type); if(packet_type == PT_TIMESTAMP) { bit_stream.Read(timestamp); bit_stream.Read(packet_type); } int num_fields = 0; int res = stream.ReadCasted<uint8_t,int>(num_fields); data.reserveFields(num_fields); for(int i = 0; i <; num_fields; ++i) { Variable field; res = deserialize(field,stream); data.setField(i,field); } where deserialize is: int deserialize(Variable &variable,BitStream &stream) { int variable_type = 0; stream.ReadCasted<uint8_t,int>(variable_type); switch(variable_type) { case Variable::INT: return deserialize_int32(variable,stream); //... } return 0; } and deserialize_int32 is: int deserialize_int32(Variable &variable,BitStream &stream) { int32_t value = 0; if(!stream.Read(value)) return 0; variable.setInt(static_cast<int>(value)); return 1; } ? Link to comment
david.broto Posted February 17, 2012 Author Share Posted February 17, 2012 Oh! This time the mistake was mine. I understood "PT_CUSTOM" as "hey, here will be your custom package id" instead of literally PT_CUSTOM enum :D This makes sense all together because in my tests i'm not using enums in unigine and i'm sending my 'package id' in the first field with a literal so it's normal that unigine sends a 4byte integer. Well this closes the circle :D After the 50 value, it comes 1 byte for a type string, and then the characters for the "SOME TEXT!" Thanks a lot :) Link to comment
Recommended Posts