public object Deserialize(Stream stream)
{
var p = new Packet();
var intBytes = new byte[4];
// Read Len and Checksum
var startPos = stream.Position;
int len = stream.Read32BitEncodedInt();
int hash = stream.Read32BitEncodedInt();
// Decrypt and Check Chcksum
ArraySegment<byte> s0, s1;
GetBuffers(stream, (int)startPos + 8, len - 4, out s0, out s1);
var ctx = new DecryptContext { Key = _deserializeWrapKey };
Decrypt(s0.Array, s0.Offset, s0.Array, s0.Offset, s0.Count, ref ctx);
Decrypt(s1.Array, s1.Offset, s1.Array, s1.Offset, s1.Count, ref ctx);
if (ctx.Hash != hash)
throw new IOException("Hash mismatch");
if (_deserializeWrapKey != 0)
{
_deserializeWrapKey += 1;
if (_deserializeWrapKey == 0)
_deserializeWrapKey = 1;
}
// Read PacketType, ActorId, RequestId
var header = stream.ReadByte();
p.Type = (PacketType)(header & 0x0F);
p.ActorId = stream.Read7BitEncodedInt();
p.RequestId = stream.Read7BitEncodedInt();
// Read Message
if ((header & 0x80) != 0)
{
if (p.Type == PacketType.System)
{
p.Message = stream.ReadString();
}
else
{
var messageTypeAlias = stream.Read7BitEncodedInt();
var messageLen = stream.Read32BitEncodedInt();
Type type = _data.TypeTable.GetType(messageTypeAlias);
if (type == null)
throw new Exception("Cannot resolve message type. TypeAlias=" + messageTypeAlias);
p.Message = Activator.CreateInstance(type);
_data.MessageSerializer.Deserialize(stream, p.Message, type, messageLen);
}
}
// Read Exception
if ((header & 0x40) != 0)
{
p.Exception = _exceptionSerializer.Deserialize(stream);
}
var consumedLen = (int)(stream.Position - startPos);
if (len + 4 != consumedLen)
throw new Exception("Mismatched length: " + (len + 4) + " " + consumedLen);
return p;
}