[SOLVED] ID_TIMESTAMP instead of custom package id


photo

Recommended Posts

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 post

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 post

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

post-501-0-75906500-1329349584_thumb.png

Link to post

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:

  1. PT_TIMESTMAP (unsigned char)
  2. timestamp (RakNet::Time = uint64_t)
  3. PT_CUSTOM (unsigned char)
  4. Number of fields in SharedData (uint8_t) (in your case it is 2)
  5. for (i = 0; i < Number of fileds in SharedData; i ++)

    1. 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)
    2. 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 post

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 post

You are welcome :)

I'll ask our technical writer ot add this info into documentation.

Link to post

One more question, could it be that unigine in x64 mode could send a uint64_t timestamp?

Link to post

Oops, I was wrong again.

Timestamp should always be a 64 bit integer (for 32 and 64 bit modes).

Link to post

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 post

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 post

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 post

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 post