Register<SupportedFeaturesPacket>(0xB9, "Supported Features", 3, ReceiveEnableFeatures);
Register<SupportedFeaturesPacket>(0xB9, "Supported Features Extended", 5, ReceiveEnableFeatures);
if (!GetPacketSizeAndHandler(packetHandlers, outsize, out realLength, out packetHandler))
{
Tracer.Warn("Unhandled packet with id: 0x{0:x2}, possible subid: 0x{1:x2}", m_ReceiveBuffer[0], m_ReceiveBuffer[1]);
m_ReceiveBufferPosition = 0;
break;
}
while (m_Decompression.DecompressOnePacket(ref data, data.Length, ref m_ReceiveBuffer, ref outsize))
{
// @wake-up-neo
// Processing packet
ProcessPacket(m_ReceiveBuffer, outsize);
}
then // @wake-up-neo
// Moved outside OnReceive for recursive buffer processing
private void ProcessPacket(byte[] m_ReceiveBuffer, int outsize)
{
int realLength;
PacketHandler packetHandler;
List<PacketHandler> packetHandlers = GetHandlers(m_ReceiveBuffer[0], m_ReceiveBuffer[1]);
if (!GetPacketSizeAndHandler(packetHandlers, outsize, out realLength, out packetHandler))
{
Tracer.Warn("Unhandled packet with id: 0x{0:x2}, possible subid: 0x{1:x2}", m_ReceiveBuffer[0], m_ReceiveBuffer[1]);
m_ReceiveBufferPosition = 0;
return;
}
byte[] packetBuffer = new byte[realLength];
Buffer.BlockCopy(m_ReceiveBuffer, 0, packetBuffer, 0, realLength);
string name = packetHandler.Name;
AddPacket(name, packetHandler, packetBuffer, realLength);
// @wake-up-neo
// If something has left in the buffer after chunking the packet with fixed length
// we are reProcessing the left buffer recursevly
if (realLength < outsize)
{
// Empty chunk for copying
byte[] chunk = new byte[0x10000];
// Copy buffer without current packet length
Array.Copy(m_ReceiveBuffer, realLength, chunk, 0, outsize - realLength);
// Process as a new packet
ProcessPacket(chunk, outsize - realLength);
}
}
foreach (PacketHandler ph in packetHandlers)
{
if (ph.Length == -1)
{
realLength = m_ReceiveBuffer[2] | (m_ReceiveBuffer[1] << 8);
packetHandler = ph;
return true;
}
else if (expectedLength == -1 || expectedLength == ph.Length)
{
// note that this is never run when ph.Length == -1, as it would have been true in the previous if statement.
realLength = ph.Length;
packetHandler = ph;
return true;
}
// @wake-up-neo
// Extra check for merged packets with fixed length
else if (expectedLength > -1 && expectedLength > ph.Length)
{
realLength = ph.Length;
packetHandler = ph;
return true;
}
}
while (m_Decompression.DecompressOnePacket(ref data, data.Length, ref m_ReceiveBuffer, ref outsize))
{
while (m_Decompression.Decompress(ref data, data.Length, ref m_ReceiveBuffer, ref outsize))
{
while (m_Decompression.DecompressBlock(ref data, data.Length, ref m_ReceiveBuffer, ref outsize))
{
var index = 0;
var processedPacketLength = 0;
while(true)
{
int realLength;
PacketHandler packetHandler;
List<PacketHandler> packetHandlers = GetHandlers(m_ReceiveBuffer[index], m_ReceiveBuffer[index + 1]);
if (!GetPacketSizeAndHandler(packetHandlers, outsize, out realLength, out packetHandler))
{
var block = new byte[realLength - processedPacketLength];
Buffer.BlockCopy(buffer, index, block, 0, block.Length);
Tracer.Warn("Unhandled packet with id: 0x{0:x2}, possible subid: 0x{1:x2}{2}{3}", m_ReceiveBuffer[index], m_ReceiveBuffer[index + 1], Environment.NewLine, block.ToFormattedString());
m_ReceiveBufferPosition = 0;
break;
}
string name = packetHandler.Name;
byte[] packetBuffer = new byte[realLength];
Buffer.BlockCopy(m_ReceiveBuffer, index, packetBuffer, 0, realLength);
AddPacket(name, packetHandler, packetBuffer, realLength);
processedPacketLength += realLength;
if (processedPacketLength == outsize)
{
break;
}
}
if (processedPacketLength != outsize)
{
throw new Exception("Bad packet size!");
}
}
private bool GetPacketSizeAndHandler(List<PacketHandler> packetHandlers, int? expectedLength, out int realLength, out PacketHandler packetHandler)
{
realLength = 0;
packetHandler = null;
if (packetHandlers.Count == 0)
return false;
foreach (PacketHandler ph in packetHandlers)
{
if (ph.Length == -1)
{
realLength = m_ReceiveBuffer[2] | (m_ReceiveBuffer[1] << 8);
packetHandler = ph;
return true;
}
// note that this is never run when ph.Length == -1, as it would have been true in the previous if statement.
if ((expectedLength ?? int.MaxValue) < ph.Length)
{
continue;
}
realLength = ph.Length;
packetHandler = ph;
return true;
}
return false;
}
m_FileIndex = FileManager.IsUopFormat ? FileManager.CreateFileIndex("artLegacyMUL.uop", 0x10000, false, ".tga") : FileManager.CreateFileIndex("artidx.mul", "art.mul", 0x10000, -1); // !!! must find patch file reference for artdata.
public static int ItemIDMask
{
get { return IsUopFormat ? 0xffff : 0x3fff; }
}
Tracer.Warn("Unhandled packet with id: 0x{0:x2}, possible subid: 0x{1:x2}{2}{3}", m_ReceiveBuffer[index], m_ReceiveBuffer[index + 1], Environment.NewLine, block.ToFormattedString());
// note that this is never run when ph.Length == -1, as it would have been true in the previous if statement.
if ((expectedLength ?? int.MaxValue) < ph.Length)
{
continue;
}
Then.. With DecompressOneBlock and
foreach (PacketHandler ph in packetHandlers)
{
if (ph.Length == -1)
{
realLength = m_ReceiveBuffer[2] | (m_ReceiveBuffer[1] << 8);
packetHandler = ph;
return true;
}
else if (expectedLength == -1 || expectedLength == ph.Length)
{
// note that this is never run when ph.Length == -1, as it would have been true in the previous if statement.
realLength = ph.Length;
packetHandler = ph;
return true;
}
else if (expectedLength > -1 && expectedLength > ph.Length)
{
realLength = ph.Length;
packetHandler = ph;
return true;
}
}
I have infinite loop:
index += realLength;
index += realLength;
processedPacketLength += realLength;
if (processedPacketLength == outsize)
{
break;
}