I wrote this function based on the broken english description given in http://forum.valhallalegends.com/index.php?topic=14994.0
Maybe some of ya'll can find it useful. It's used in the Warcraft III game create, game listing, and game advertising packets... and probably some other ones as well.
This goes to show, don't reverse what you don't have to. ;)
It would be easiest to pass in a buffer allocated with malloc(strlen(encoded)) for the decoded buffer.
/*
* This function is used to decode data in certain packets
* sent by Warcraft III.
*
* Parameters:
* encoded [in] - The data to be decoded
* decoded [out] - The decoded data
* returns the size of the decoded data
*/
unsigned int decode_map_data(const char * encoded, char * decoded)
{
unsigned int i = 0, j;
unsigned int len = 0;
char d;
while (*encoded) {
if (i % 8) {
decoded[len++] = *encoded & ((d >> ++j) | ~1);
} else {
j = 0;
d = *encoded;
}
i++;
encoded++;
}
return len;
}
I notice you have while(*encoded). Does that mean the encoded map data will never have NULLs?
Quote from: MyndFyre[vL] on July 19, 2006, 06:19 PM
I notice you have while(*encoded). Does that mean the encoded map data will never have NULLs?
yes, the zero bit is always 1.
Could anyone port this to Delphi?
Quote from: Savior on July 19, 2006, 08:14 PM
Could anyone port this to Delphi?
Don't want to sound rude, but why don't you? Unless we have someone very generous out there who would be willing to do that for you.
Public Function DecodeMapData(ByVal Encoded As String, ByRef Decoded As String) As Long
' Ported to VB by l2k-Shadow
Dim enc() As Byte, dec() As Byte
Dim i As Long, j As Long, d As Byte, lngLen As Long
enc = StrConv(Encoded, vbFromUnicode)
For i = 0 To UBound(enc)
If (i Mod 8) Then
ReDim Preserve dec(lngLen)
dec(lngLen) = (enc(i) And ((RShift(d, 1 + j) Or Not 1)))
j = j + 1
lngLen = lngLen + 1
Else
j = 0
d = enc(i)
End If
Next i
Decoded = StrConv(dec, vbUnicode)
DecodeMapData = lngLen
End Function
Public Function RShift(ByVal pnValue As Long, ByVal pnShift As Long) As Long
RShift = CLng(pnValue \ (2 ^ pnShift))
End Function
There's a quick VB port, untested don't know if it works, you should be able to port that to delphi easily enough though. If anyone sees a mistake, correct it please.
Thank you.