RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

packet encoding

cal7

Wanderer
packet encoding

hi!
i know its not the right forum (?) ... but since the people here have the most knowledege in that area i hope someone here can answer my (more general and not related to runuo) question. i always wanted to write a uo emulator myself up to the point where i can connect, walk and talk. then i can sleep well with having in mind the rest is "just" a "i could do it but i am too lazy because its a shitload of work" thing...

i am now at the point where i can connect, walk and talk so everything is fine ... the only problem is the one piece of code that is not my work because it is not obvious, the packet encoding. i took some open source emulators and wrote their packet encoders together but something is not working right and i have to hardcode some packets (just sending the sniffed packets from a normal shard). for example in the walking sequence whenever it is "compressed" to 2 bytes instead of 3 the encoded outgoing packet is just wrong ...

my packet encoding routine looks like that

[code:1]
int encode_packet(unsigned char *in_packet, unsigned char *out_packet, int length)
{
int actByte = 0;
int bitByte = 0;
int nrBits;
int value;
int pos;

while (length--)
{
pos = (int) *in_packet;
nrBits = (int) encode_table[pos][0];
value = (int) encode_table[pos][1];
*in_packet++;

while (nrBits--)
{
out_packet[actByte] = (out_packet[actByte] << 1) | (unsigned char) ((value >> nrBits) & '\x01');
bitByte = (bitByte + 1) & '\x07';
if (bitByte == 0) actByte++;
}
}

nrBits = encode_table[256][0];
value = encode_table[256][1];

while (nrBits--)
{
out_packet[actByte] = (out_packet[actByte] << 1) | (unsigned char) ((value >> nrBits) & '\x01');
bitByte = (bitByte + 1) & '\x07';
if (bitByte == 0) actByte++;
}

if (bitByte != 0)
{
while (bitByte < 8)
{
out_packet[actByte] <<= 1;
bitByte++;
}
actByte++;
}

return actByte;
}

[/code:1]

with encode_table beeing the usual encoding table which i tripple checked if it is right...
am i doing something wrong? thanks a lot in advance if you can help me, i know some of you people out there do this for breakfast :eek:

cal
 

Correa

Wanderer
Hmmm I know that one :)

Debugged and profiled it once... well, I suppose that if you don't understand what it is, then you can't get the "accomplishment" feeling you are looking for... well, that's just my opinion. :D

If you copied it from LW/UOX/Wolfpack/UOXC/Whatever... it works there ( on all of those *g*, then for sure the problem isn't in that routine, but perhaps on how you are using it.

It might be helpfull to know that it's just a Huffman encoding. Any CS course will teach you how to write one of those.

Anyway, what I did to debug that stuff was printf it to the console and compare the results I got from mine with the results I get from older version of it. In Wolfpack we had this nice cUOPacket::dump routine for doing just that :)

Code:
/*!
  This is a debug method. It will dump a numerical hexa and ascii representation of the packet
  as well as a right table of offsets into \a s.
  For example:
  \code
  cUOPacket p;
  ...
  p.print(&cout);
  \endcode
  Will produce an output similar to this:
  \verbatim
	[ packet: 9b ; length: 258 ]
	0000: 9b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
	0100: 00 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- : ..
  \endverbatim
*/
QCString cUOPacket::dump( const QByteArray &data )
{
	Q_INT32 length = data.count();
	QCString dumped = QString( "\n[ packet: %1; length: %2 ]\n" ).arg( (Q_UINT8)data[0], 2, 16 ).arg( data.count() ).latin1();

	int lines = length / 16;
	if ( length % 16 ) // always round up.
		lines++;  

	for (int actLine = 0; actLine < lines; ++actLine)
	{
		QCString line; //= QString("%1: ").arg(actLine*16, 4, 16); // Faster, but doesn't look so good
		line.sprintf( "%04x: ", actLine * 16 );
		int actRow = 0;
		for(; actRow < 16; ++actRow)
		{
			if( actLine * 16 + actRow < length )
			{
				QCString number = QString::number( static_cast<uint>(static_cast<Q_UINT8>(data[actLine*16 + actRow])), 16 ).latin1() + QCString(" ");
				//line += QString().sprintf( "%02x ", (unsigned int)((unsigned char)data[actLine * 16 + actRow]) );
				if ( number.length() < 3 )
					number.prepend( "0" );
				line += number;
			}
			else 
				line += "-- ";
		}

		line += ": ";
 
		for(actRow = 0; actRow < 16; ++actRow)
		{
			if( actLine * 16 + actRow < length ) 
				line += ( isprint(static_cast< Q_UINT8 >( data[actLine * 16 + actRow] ) ) ) ? data[actLine * 16 + actRow] : '.' ;
		}

		line += "\n";
		dumped += line;
	}
	return dumped;
}

I agree that this code is cryptic to anyone looking at it :)
Hope this helps ;)
 

cal7

Wanderer
thank you very much! that was exactly what i needed to know,
its working now and i can sleep well :)
cal
 
Top