Packet 0xdd (Compressed Gump). Help!

General Injection issues

Moderators: Murderator+, Murderator

Post Reply
RonaldoBRILHA
Posts: 1
Joined: 2010-01-08 14:56:39

Packet 0xdd (Compressed Gump). Help!

Post by RonaldoBRILHA »

Hi Guys,

I´m trying to decode this gump in c language. Can someone help me?

My Code:

Code: Select all

int compressed_gump(char *buf, int len) // 0xdd

int PlayerSerial,GumpID,x,y,CLen,DLen,size;

    size = unpack16(buf+1);
   PlayerSerial = unpack32(buf+3);
   GumpID  = unpack32(buf+7);
   x  = unpack32(buf+11);
   y  = unpack32(buf+15);
   
   CLen = unpack32(buf+19);

   if (CLen < 4)
   {
    LogPrint(3, "[ERROR] Compress Length < 4.");
     return 0;
   }

   CLen -= 4;
   
    if((28 + CLen) > (size))
   {
   LogPrint(3, "[ERROR] Bad Compressed Gumpdata !");
    return 0;
    }

   DLen = unpack32(buf+23);
   return 0;
}


Packet Description:

Packet Name: Compressed Gump
Last Modified: 2009-09-10 16:06:57
Modified By: Grin

Packet: 0xDD
Sent By: Server
Size: variable

Packet Build
BYTE[1] Cmd
BYTE[2] len
BYTE[4] Player Serial
BYTE[4] Gump ID
BYTE[4] x
BYTE[4] y
BYTE[4] Compressed Gump Layout Length (CLen)
BYTE[4] Decompressed Gump Layout Length (DLen)
BYTE[CLen-4] Gump Data, zlib compressed
BYTE[4] Number of text lines
BYTE[4] Compressed Text Line Length (CTxtLen)
BYTE[4] Decompressed Text Line Length (DTxtLen)
BYTE[CTxtLen-4] Gump's Compressed Text data, zlib compressed

Subcommand Build
N/A

Notes
text lines is in Big-Endian Unicode formate, not NULL terminated
loop:

BYTE[2] Length
BYTE[Length*2] text

endloop

Default level for decompresion

I Founded some open sources . But my dev is in C++.

C# code

Code: Select all

private void CompressedGump( PacketReader pvSrc ) {
         int serial = pvSrc.ReadInt32();
         int dialogID = pvSrc.ReadInt32();
         int x = pvSrc.ReadInt32();
         int y = pvSrc.ReadInt32();
         string layout = GetCompressedReader( pvSrc ).ReadString();
         string[] text = new string[pvSrc.ReadInt32()];
         pvSrc = GetCompressedReader( pvSrc );
         for ( int i = 0; i < text.Length; i++ ) {
            text[i] = pvSrc.ReadUnicodeString( pvSrc.ReadUInt16() );
         }

      }

      public PacketReader GetCompressedReader( PacketReader pvSrc ) {
         if ( m_CompBuffer == null ) {
            m_CompBuffer = new byte[0x1000];
         }
         int num = pvSrc.ReadInt32();
         if ( num == 0 ) {
            return new PacketReader( m_CompBuffer, 0, 3, false, 0, "Gump Subset" );
         }
         int destLength = pvSrc.ReadInt32();
         if ( destLength == 0 ) {
            return new PacketReader( m_CompBuffer, 0, 3, false, 0, "Gump Subset" );
         }
         byte[] source = pvSrc.ReadBytes( num - 4 );
         if ( destLength > m_CompBuffer.Length ) {
            m_CompBuffer = new byte[( destLength + 0xfff ) & -4096];
         }
         Zlib.Unpack( m_CompBuffer, ref destLength, source, source.Length );
         PacketReader reader = new PacketReader( m_CompBuffer, 0, destLength, true, 0, "Gump Subset" );
         reader.Seek( 0, SeekOrigin.Begin );
         return reader;
      }


Source: http://www.runuo.com/forums/third-party ... -0xdd.html

C# [2] code

Code: Select all

case 0xDD: //generic gump
                    int serialdd = packet[3] << 24 | packet[4] << 16 | packet[5] << 8 | packet[6];
                    int iddd = packet[7] << 24 | packet[8] << 16 | packet[9] << 8 | packet[10];
                    int xdd = packet[11] << 24 | packet[12] << 16 | packet[13] << 8 | packet[14];
                    int ydd = packet[15] << 24 | packet[16] << 16 | packet[17] << 8 | packet[18];
                    int compressLendd = packet[19] << 24 | packet[20] << 16 | packet[21] << 8 | packet[22];
                    if (compressLendd <= 4) return;
                    else compressLendd -= 4;
                    int decompressLendd = packet[23] << 24 | packet[24] << 16 | packet[25] << 8 | packet[26] + 1;
                    byte[] decompresseddd = new byte[decompressLendd];
                    byte[] compresseddd = new byte[compressLendd];
                    Buffer.BlockCopy(packet, 27, compresseddd, 0, compressLendd);
                    int success;
                    //if (IntPtr.Size == 8) success = Win32.uncompress64(decompresseddd, ref decompressLendd, compresseddd, compressLendd);
                    success = Win32.uncompress32(decompresseddd, ref decompressLendd, compresseddd, compressLendd);
                    if (success != 0)
                    {
                        Log.LogDataMessage(client, packet, "*** Error decompressing gump layout:");
                        return;
                    }
                   
                    string layoutdd = ASCIIEncoding.ASCII.GetString(decompresseddd).TrimEnd('\0');
                    int offsetdd = 27 + compressLendd;
                    int linesdd = packet[offsetdd] << 24 | packet[offsetdd + 1] << 16 | packet[offsetdd + 2] << 8 | packet[offsetdd + 3];
                    compressLendd = packet[offsetdd + 4] << 24 | packet[offsetdd + 5] << 16 | packet[offsetdd + 6] << 8 | packet[offsetdd + 7];
                    string[] textdd = new string[linesdd];
                    if (compressLendd > 4)
                    {
                        compressLendd -= 4;
                        compresseddd = new byte[compressLendd];
                        Buffer.BlockCopy(packet, offsetdd + 12, compresseddd, 0, compressLendd);
                        decompressLendd = packet[offsetdd + 8] << 24 | packet[offsetdd + 9] << 16 | packet[offsetdd + 10] << 8 | packet[offsetdd + 11] + 1;
                        decompresseddd = new byte[decompressLendd];
                        //if (IntPtr.Size == 8) success = Win32.uncompress64(decompresseddd, ref decompressLendd, compresseddd, compressLendd);
                        success = Win32.uncompress32(decompresseddd, ref decompressLendd, compresseddd, compressLendd);
                        if (success != 0)
                        {
                            Log.LogDataMessage(client, packet, "*** Error decompressing gump strings:");
                            return;
                        }
                        offsetdd = 0;
                        int lendd = 0;
                        for (int x = 0; x < linesdd; x++)
                        {
                            lendd = (decompresseddd[offsetdd] << 8 | decompresseddd[offsetdd + 1]) * 2;
                            offsetdd += 2;
                            textdd[x] = UnicodeEncoding.BigEndianUnicode.GetString(decompresseddd, offsetdd, lendd);
                            offsetdd += lendd;
                        }
                    }
                    IncomingPackets.OnGenericGump(client, serialdd, iddd, xdd, ydd, layoutdd, textdd);
                    return;


Source: UO Machine Source Code

LUA Code

Code: Select all

-- compressed Gump
function gPacketHandler.kPacket_Compressed_Gump ()   --0xDD
   local input = GetRecvFIFO()
   local popped_start = input:GetTotalPopped()
   local id = input:PopNetUint8()
   local size = input:PopNetUint16()
   local newgump = {}

   newgump.playerid = input:PopNetUint32()
   newgump.dialogId = input:PopNetUint32()
   newgump.x = input:PopNetUint32()
   newgump.y = input:PopNetUint32()

   newgump.Length_CompressedData = input:PopNetUint32() - 4
   newgump.Length_Data = input:PopNetUint32()

   printdebug("net",sprintf("NET: Length_CompressedData=%d Length_UncompressedData=%d\n",newgump.Length_CompressedData,newgump.Length_Data))

   if (28 + newgump.Length_CompressedData > size) then
      printf("NET: BROKEN - kPacket_Compressed_Gump packet, compressed gumplen = 0x%08x\n",newgump.Length_CompressedData)
      print("Error: Server Sends bad Compressed Gumpdata ! Please report.")
      print("FATAL ! kPacket_Compressed_Gump -> forced Crash")
      NetCrash()
   end

   --- Data Part ---
   local decompressed = CreateFIFO()
   -- pop and decompress data into decompress fifo
   input:PeekDecompressIntoFifo(newgump.Length_CompressedData,newgump.Length_Data,decompressed)
   -- skip compressed part (peeked)
   input:PopRaw(newgump.Length_CompressedData)
   newgump.Data = decompressed:PopFilledString(decompressed:Size())
   -- and clear the decompress fifo for later usage
   decompressed:Clear()
   
   -- WARNING  strange -4 on compression ahead (see runuo2 source)
   --- Textlines Part ---
   newgump.numTextLines = input:PopNetUint32()

   if (newgump.numTextLines ~= 0) then
      newgump.Length_CompressedTextLines = input:PopNetUint32() - 4
      newgump.Length_TextLines = input:PopNetUint32()
   
      -- pop and decompress data into decompress fifo
      input:PeekDecompressIntoFifo(newgump.Length_CompressedTextLines,newgump.Length_TextLines,decompressed)
      -- skip compressed part (peeked)
      input:PopRaw(newgump.Length_CompressedTextLines)
      
      -- print gumpdata
      for k,v in pairs(newgump) do printdebug("gump",sprintf("newgump.%s = ",k),v) end
      
      local textlen = 0
      newgump.textline = {}
      newgump.textline_unicode = {}
      --Index 0 because Serverside Gump Commands use this Index as textline references
      for i = 0,newgump.numTextLines-1 do
         textlen = decompressed:PopNetUint16()
         printdebug("gump","reading text line ",i," with length ",textlen)
         newgump.textline[i],newgump.textline_unicode[i] = UniCodeDualPop(decompressed,textlen)
         printdebug("gump",sprintf("newgump.textline[%d](len=%d)=\n",i,textlen),newgump.textline[i])
      end
   end

   decompressed:Destroy()

   if ( (input:Size() >= 4) and (input:GetTotalPopped()-popped_start < size) ) then
      local unknownterminator=input:PopNetUint32()
   end

   local dialog = GumpParser(newgump)
   NotifyListener("Hook_OpenServersideGump",dialog,newgump.playerid,newgump.dialogId,newgump.Length_Data,true,newgump)   
end



Source: http://iris.schattenkind.net/svn/branch ... t.gump.lua
Post Reply