Hi Guys,
I´m trying to decode this gump in c language. Can someone help me?
My Code:
Code: 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: 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: 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: -- 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
|