Valhalla Legends Forums Archive | Battle.net Bot Development | [Solved]D2 Game Server Packets

AuthorMessageTime
Ringo
Hi, iv currently spent alot of time logging d2 game server packets trying to make sence of incoming ones - but got driven mad.
Then common sence kinda hit me in the face and i thought i would ask here to see if anyone has a ported VB version of this:
https://davnit.net/bnet/vL/phpbbs/index.php?topic=585.0
Or is there a .dll that can decompress the packets?
Iv been really stuck and confused with this for the past week and really need some info - i have looked through the forum and found "1.10" tables posted by smoke (i cant rememebr the link) and was wundering if them tables (in the above link) will still work for the current d2 patch?

Any help/info on decompressing the packets would be great!

Thanks in advance!

[edit]
Thanks everyone!
dll for d2 ingame decompression: D2GS.dll
May 5, 2005, 7:20 PM
KkBlazekK
If it still works, why not just compile that code as a C++ dll?
May 5, 2005, 7:27 PM
Ringo
[quote author=Blaze link=topic=11497.msg111167#msg111167 date=1115321271]
If it still works, why not just compile that code as a C++ dll?
[/quote]
Because i dont have any c++ programing software or know any c/c++ :(

[edit]
Is it possible somone could do this for me? that would great thanks!
May 5, 2005, 7:31 PM
Yegg
I myself only know a little bit of C/C++. But if you take time to actually look at the code, you can figure out what some of it is doing. If you desperately need the proper code, but not in C++, you should just study C++ for a little while, so that you understand what the code is doing and how you can convert it to another language (Visual Basic 6?).
May 5, 2005, 8:11 PM
Ringo
[code]
Public Function GamePacketSize(data As String, size As Integer, offset As Integer) As Integer

    Dim a As Long 'String  ?

    If Len(data) < Chr(&HF0) Then
        size = Len(data) - 1
        offset = 1
        GamePacketSize = 1
        End Function
   End If
   'a = data & chr(&HF) << 8 /left shift?
   a = CDbl(data & Chr(&HF) * (2 ^ 8))
   size = Asc(a) + Len(data) - 2
   offset = 2
   'return &data[2];
   GamePacketSize = 2
End Function
Public Function GamePacketDecode(indata As String, insize As Integer, outdata As String, outmax As Integer, outsize As Integer)
'int GamePacketDecode(unsigned char *indata, unsigned int insize,
'                    unsigned char *outdata, unsigned int outmax,
'                    unsigned int *outsize)
'{
   Dim a, b, c, d As Integer
   Dim maxcnt, index As Integer
   Dim cnt As Long
   Dim outptr, inptr As String
   Dim size As Integer

   b = 0

   size = insize
   inptr = indata
   maxcnt = outmax
   outptr = outdata
   cnt = &H20  'long?

   'while (1) { 'size > 1?

       If cnt > &H8 Then
           While (size > 0 And cnt > &H8)
               cnt = cnt - &H8
               'size--;
               'a = *inptr++ << cnt;
               'b |= a;

           Wend
       End If

       index = CharIndex(CDbl(b \ (2 ^ &H18)))
       a = CharTable(index)
       d = CDbl(b \ (2 ^ (&H18 - a))) & BitMasks(a)
       c = CharTable(index + 2 * (d + 2))

       cnt = cnt + c
       If cnt > &H20 Then
           outsize = outmax - maxcnt
           GamePacketDecode = 1
           End Function
       End If

       'if (maxcnt-- == 0)
       '    return 0;
           'GamePacketDecode = 0
           
       a = CharTable(index + 2 * (d + 1))
       '*outptr++ = (unsigned char)a;

       'b <<= (c & 0xFF);
   '}

   'assert(0);
   'return 0;
'}
End Function
[/code]
i cant do it... my head is gonner go bang, iv tryed for to many days now.

[edit]
iv tryed restarting a few times, iv tryed looking at the c++ code vs packet log data to try and figger out what byte shift operations are taking place.
I can only guess what some of that code above means..
beleave me i have tryed.
May 5, 2005, 8:30 PM
Yegg
Can you re-post the code, but show which is VB6 and which is C++? You seem to have added notes in the VB6 code of C++ code you wern't sure of, that sort of threw me off. Also, << is left shift and >> is right shift for bit shifting. You can probably find the code to an LShift function and an RShift function in VB6, many bots have them.
May 5, 2005, 8:43 PM
Ringo
(im probly not even close to right on what im doing here lol)
VB6:
[code]
Public Function GamePacketSize(data As String, size As Integer, offset As Integer) As Integer
    Dim a As Long
    If Len(data) < Chr(&HF0) Then
        size = Len(data) - 1
        offset = 1
        GamePacketSize = 1
        End Function
  End If
  a = CDbl(data & Chr(&HF) * (2 ^ 8))
  size = Asc(a) + Len(data) - 2
  offset = 2
  GamePacketSize = 2
End Function
Public Function GamePacketDecode(indata As String, insize As Integer, outdata As String, outmax As Integer, outsize As Integer) As Integer '?
  Dim a, b, c, d As Integer
  Dim maxcnt, index As Integer
  Dim cnt As Long
  Dim outptr, inptr As String
  Dim size As Integer
 
  b = 0
  size = insize
  inptr = indata
  maxcnt = outmax
  outptr = outdata
  cnt = &H20


      If cnt > &H8 Then
          While (size > 0 And cnt > &H8)
              cnt = cnt - &H8

          Wend
      End If

      index = CharIndex(CDbl(b \ (2 ^ &H18)))
      a = CharTable(index)
      d = CDbl(b \ (2 ^ (&H18 - a))) & BitMasks(a)
      c = CharTable(index + 2 * (d + 2))

      cnt = cnt + c
      If cnt > &H20 Then
          outsize = outmax - maxcnt
          GamePacketDecode = 1
          End Function
      End If

      a = CharTable(index + 2 * (d + 1))

End Function
[/code]

c++:
[code]
unsigned char *GamePacketSize(unsigned char *data, unsigned int *size,
                            unsigned int *offset)
{
  unsigned int a;

  if (data[0] < 0xF0) {
      *size = data[0] - 1;
      *offset = 1;
      return &data[1];
  }

  a = (data[0] & 0xF) << 8;
  *size = a + data[1] - 2;
  *offset = 2;
  return &data[2];
}


int GamePacketDecode(unsigned char *indata, unsigned int insize,
                    unsigned char *outdata, unsigned int outmax,
                    unsigned int *outsize)
{
  unsigned int a, b, c, d;
  unsigned int maxcnt, index, cnt;
  unsigned char *outptr, *inptr;
  int size;

  b = 0;

  size = insize;
  inptr = indata;

  maxcnt = outmax;
  outptr = outdata;
  cnt = 0x20;

  while (1) {

      if (cnt >= 0x8) {
          while (size > 0 && cnt >= 8) {
              cnt -= 0x8;
              size--;
              a = *inptr++ << cnt;
              b |= a;
          };
      }

      index = CharIndex[b >> 0x18];
      a = CharTable[index];
      d = (b >> (0x18 - a)) & BitMasks[a];
      c = CharTable[index + 2*d + 2];

      cnt += c;
      if (cnt > 0x20) {
          *outsize = outmax - maxcnt;
          return 1;
      }

      if (maxcnt-- == 0)
          return 0;

      a = CharTable[index + 2*d + 1];
      *outptr++ = (unsigned char)a;

      b <<= (c & 0xFF);
  }

  assert(0);
  return 0;
}
[/code]
If i left anything out, Brand.X's code can be fouund here:
https://davnit.net/bnet/vL/phpbbs/index.php?topic=585.0

Thanks inadvance for any weight you can lift off my sholders.
May 5, 2005, 8:52 PM
Ringo
Hmm could somone please explain what these mean in VB6?

no idea what its basing a loop on here...
[code]
while (1) {
[/code]

Size somthing..
[code]
'size--;
[/code]

a = somthing inptr left shift cnt?
[code]
a = *inptr++ << cnt;
[/code]

[code]
b |= a;
[/code]
b = b Xor a?

if maxcnt somthing somthing 0 then
[code]
if (maxcnt-- == 0)
[/code]

outputr somthing = somthing a?
[code]
outptr++ = (unsigned char)a;
[/code]

Not sure how its leftshifting b
[code]
b <<= (c & 0xFF)
[/code]

Also if somone could say if the guess's iv taken (below) are anything close to what they really mean in c/c++ ?

thanks

[edit]
Attempt #128409 to make sence of it

[code]
Public Function GamePacketSize(data As String, size As Integer, offset As Integer) As Integer
    Dim a As Long
    If Len(data) < Chr(&HF0) Then
        size = Len(data) - 1
        offset = 1
        GamePacketSize = 1
        End Function
   End If
   a = LeftShift(data & Chr(&HF), 8)
   size = Asc(a) + Len(data) - 2
   offset = 2
   GamePacketSize = 2
End Function
Public Function GamePacketDecode(indata As String, insize As Integer, outdata As String, outmax As Integer, outsize As Integer) As Integer
   Dim a As Integer
   Dim b As Integer
   Dim c As Integer
   Dim d As Integer
   Dim maxcnt As Integer
   Dim index As Integer
   Dim cnt As Long
   Dim outptr As String
   Dim inptr As String
   Dim size As Integer
   b = 0
   size = insize
   inptr = indata
   maxcnt = outmax
   outptr = outdata
   cnt = &H20

'///while (1) {
       If (cnt > Chr(&H8)) Then
           While (size > 0 And cnt > Chr(&H8))
               cnt = cnt - &H8
        '///// size--; / no idea
        '///// a = *inptr++ << cnt;
        '///// b |= a;
           Wend
       End If
       index = CharIndex(RightShift(b, &H18))
       a = CharTable(index)
       d = RightShift(b, (&H18 - a)) & BitMasks(a)
       c = CharTable(index + (2 * d) + 2)
       cnt = cnt + c
       If (cnt > Chr(&H20)) Then
           outsize = outmax - maxcnt
           GamePacketDecode = 1
           Exit Function
       End If
'/////if (maxcnt-- == 0)
'/////     return 0;
       a = CharTable(index + (2 * d) + 1)
'///// *outptr++ = (unsigned char)a;

'///// b <<= (c & &HFF)
   '}
'///// assert(0);
'///// return 0;
'}
End Function
Private Function RightShift(ByVal Value As Long, ByVal Shift As Long) As Double
RightShift = CDbl(Value \ (2 ^ Shift))
End Function
Private Function LeftShift(ByVal Value As Long, ByVal Shift As Long) As Double
LeftShift = CDbl(Value * (2 ^ Shift))
End Function
[/code]
May 5, 2005, 11:05 PM
Myndfyr
[quote author=Ringo link=topic=11497.msg111202#msg111202 date=1115334353]
Hmm could somone please explain what these mean in VB6?

no idea what its basing a loop on here...
[code]
while (1) {
[/code]
[/quote]
This is IMO bad programming style, but legal C.  It's essentially "while (true)".  There's a break statement inside somewhere.

[quote author=Ringo link=topic=11497.msg111202#msg111202 date=1115334353]
Size somthing..
[code]
'size--;
[/code]
[/quote]
Equivalent code: size = size - 1;  It's the decrement operator.

[quote author=Ringo link=topic=11497.msg111202#msg111202 date=1115334353]
a = somthing inptr left shift cnt?
[code]
a = *inptr++ << cnt;
[/code]
[/quote]
The value currently pointed to of the inptr array (pointers and arrays work identically in C) is left-shifted by the number of bits in the cnt variable.  The result is stored in "a".  Then, inptr points to the next element in the array.

[quote author=Ringo link=topic=11497.msg111202#msg111202 date=1115334353]
[code]
b |= a;
[/code]
b = b Xor a?
[/quote]
Close.  b = b Or a.  The Xor operator in C is ^

[quote author=Ringo link=topic=11497.msg111202#msg111202 date=1115334353]
if maxcnt somthing somthing 0 then
[code]
if (maxcnt-- == 0)
[/code]
[/quote]
The decrement operator again.  This is important: these unary (one-variable) operators can either be prefixed or postfixed.  This is an example of a prefixed operator: --maxcnt.  This is an example of a postfixed operator: maxcnt--.  As you can see, the code example you gave is postfixed.  If the operator is postfixed, the code evaluates the expression and then performs the operator's function; in this case, the expression (maxcnt-- == 0) returns false of all values except 0.  After that expression is evaluated, the value in maxcnt is decremented by 1.  If the operator is prefixed, the code performs the operator's function first, so the expression (--maxcnt == 0) would return false for all values except 1, because if maxcnt equalled 1, it would be decremented and then compared to 0.

[quote author=Ringo link=topic=11497.msg111202#msg111202 date=1115334353]
outputr somthing = somthing a?
[code]
outptr++ = (unsigned char)a;
[/code]
[/quote]
You misquoted that code.  There's an asterisk preceeding it:
[code]
*outptr++ = (unsigned char)a;
[/code]
The array item that outptr currently points to is assigned the byte value (unsigned char is an 8-bit positive-only value) currently stored in the a variable.  Then the outptr variable is incremented to point to the next array item.

[quote author=Ringo link=topic=11497.msg111202#msg111202 date=1115334353]Not sure how its leftshifting b
[code]
b <<= (c & 0xFF)
[/code]
[/quote]
First, evaluate the expression (c & 0xff).  That is the and operator.  By ANDing c and 0xff, you're effectively limiting the range of values that the result can hold from 0 to 0xff.  b is then left-shifted by the number of values returned by the expression I just described.

[quote author=Ringo link=topic=11497.msg111202#msg111202 date=1115334353]
[edit]
Attempt #128409 to make sence of it
[/quote]
Stop whining.  I highly recommend looking up a tutorial on pointers in C.  It'll help you make sense of the two pointer things you asked about.
May 5, 2005, 11:52 PM
Ringo
[quote]
Stop whining.  I highly recommend looking up a tutorial on pointers in C.  It'll help you make sense of the two pointer things you asked about.
[/quote]

Thanks for explaining what they mean!

Im not whining im being honest ;)

Also why do people think i want to learn c/c++ ?

Pointer things?
May 6, 2005, 12:14 AM
Myndfyr
[quote author=Ringo link=topic=11497.msg111215#msg111215 date=1115338465]
Also why do people think i want to learn c/c++ ?
[/quote]
I didn't say you want to learn C/++.  I said you should learn enough of it to help you figure out how to translate the code, since that's what you're doing.  Pointers aren't an easy topic to learn.
May 6, 2005, 12:15 AM
Ringo
Nore is C :P

Im just kiddin with ya, thanks for your help, im gonner give it another go in a sec :)
May 6, 2005, 12:18 AM
Myndfyr
[quote author=Ringo link=topic=11497.msg111217#msg111217 date=1115338680]
Nore is C :P
[/quote]

Nor is programming, but you're trying that, aren't you?

If you're not willing to help yourself, you will quickly find that others here will be increasingly unwilling to help you.
May 6, 2005, 12:19 AM
Ringo
-_-?
I posted here as a last option but i think ur missing the point.
I dont ask for help unless i really cant see light at the end of the tunnle and iv tryed my hardest to do the task in hand :P

Read top post ;)
Or my log of total posts here at VL..

[edit]
damn what did i do to get a nice flaming like that :P
And what makes u think im "trying" to program?
lol :(
May 6, 2005, 12:22 AM
Ringo
Ok thats enough - my head just exploded.
cant somone just take 5 seconds to put it in a C dll?
May 6, 2005, 1:56 AM
HdxBmx27
Speakin of DLL files, can anyone point me twoords a tut on making come? In c of coruse, mainly how to give access to sertian functions.
~-~(HDX)~-~
May 6, 2005, 2:14 AM
Ringo
http://support.microsoft.com/kb/q187912/#XSLTH3125121122120121120120
think this is what ur looking for, if not it should beable to take u to the place that does :P
May 6, 2005, 2:23 AM
Ringo
Its now 7am in the morning and im no closer to understanding this, im more confused than anything else.
After another look through the forum, it seems alot of you have the code for ingame compression, maybe somone who knows both C and VB can help me convert the rest of it?
Or if anyone who has it in VB could possibly post it so i can see how it works?

May 6, 2005, 5:36 AM
HdxBmx27
[quote author=Ringo link=topic=11497.msg111237#msg111237 date=1115346227]
http://support.microsoft.com/kb/q187912/#XSLTH3125121122120121120120
think this is what ur looking for, if not it should beable to take u to the place that does :P
[/quote]
THANK YOU THANK YOU THANK YOU!!!
Gah, you dont know how long i've been looking for an example of that :/ So much more easier then using a header file.

Now I can finally port my most tedious functions to C to optamize them!
~-~(HDX)~-~
May 6, 2005, 5:58 AM
Ringo
np, if u feel like pasteing brand.x's code into a dll somtime please post it ^_^
May 6, 2005, 6:04 AM
Myndfyr
[quote author=Ringo link=topic=11497.msg111257#msg111257 date=1115359474]
np, if u feel like pasteing brand.x's code into a dll somtime please post it ^_^
[/quote]

OMG just get gcc already if you just want it in a DLL!
May 6, 2005, 9:14 AM
Ringo
[quote author=MyndFyre link=topic=11497.msg111267#msg111267 date=1115370887]
[quote author=Ringo link=topic=11497.msg111257#msg111257 date=1115359474]
np, if u feel like pasteing brand.x's code into a dll somtime please post it ^_^
[/quote]

OMG just get gcc already if you just want it in a DLL!
[/quote]

And how much will that set me back?
May 6, 2005, 2:11 PM
QwertyMonster
Why doesnt somebody just do this guy a favour and compile it to a .DLL.

MyndFyre, you can. You program in C/C++.
May 6, 2005, 2:22 PM
Yegg
[quote author=QwertyMonster link=topic=11497.msg111288#msg111288 date=1115389353]
Why doesnt somebody just do this guy a favour and compile it to a .DLL.

MyndFyre, you can. You program in C/C++.

[/quote]
MyndFyre already answered every question of Ringo's earlier in this thread. I was going to try and help him, but after reading through MyndFyre's post, everything was already done. I don't really think he needs a dll.
May 6, 2005, 6:57 PM
UserLoser.
[quote author=QwertyMonster link=topic=11497.msg111288#msg111288 date=1115389353]
Why doesnt somebody just do this guy a favour and compile it to a .DLL.

MyndFyre, you can. You program in C/C++.
[/quote]

Just use D2Client.dll
May 6, 2005, 6:58 PM
shout
I put it in a dll, but there is no guarantee it will work. It compiled fine and I exported the two functions.

If it does not work, tough luck, don't whine to me.

PM me your e-mail and I will send it to you.

[quote author=Yegg link=topic=11497.msg111306#msg111306 date=1115405832]
[quote author=QwertyMonster link=topic=11497.msg111288#msg111288 date=1115389353]
Why doesnt somebody just do this guy a favour and compile it to a .DLL.

MyndFyre, you can. You program in C/C++.

[/quote]
MyndFyre already answered every question of Ringo's earlier in this thread. I was going to try and help him, but after reading through MyndFyre's post, everything was already done. I don't really think he needs a dll.
[/quote]

MyndFyre is a .Net guru.
May 6, 2005, 8:09 PM
laurion
had to remove assert(0);
d2.dll
May 6, 2005, 9:24 PM
Ringo
Thanks very much!

[edit]
Im getting entry point not found :(
[code]
Private Declare Function GamePacketSize Lib "d2.dll" (ByRef Data As String, ByRef Size As Integer, ByRef Offset As Integer) As Integer
Private Declare Function GamePacketDecode Lib "d2.dll" (ByRef inData As String, ByVal inSize As Integer, ByRef outData As String, ByVal outMax As Integer, ByRef outSize As Integer) As Integer
[/code]
Is that right in VB6?
May 6, 2005, 11:26 PM
Quarantine
Could possibly be an error in the DLL
May 7, 2005, 12:15 AM
Myndfyr
[quote author=Shout link=topic=11497.msg111314#msg111314 date=1115410151]
I put it in a dll, but there is no guarantee it will work. It compiled fine and I exported the two functions.

If it does not work, tough luck, don't whine to me.

PM me your e-mail and I will send it to you.

[quote author=Yegg link=topic=11497.msg111306#msg111306 date=1115405832]
[quote author=QwertyMonster link=topic=11497.msg111288#msg111288 date=1115389353]
Why doesnt somebody just do this guy a favour and compile it to a .DLL.

MyndFyre, you can. You program in C/C++.

[/quote]
MyndFyre already answered every question of Ringo's earlier in this thread. I was going to try and help him, but after reading through MyndFyre's post, everything was already done. I don't really think he needs a dll.
[/quote]

MyndFyre is a .Net guru.
[/quote]

I still know how to compile a C DLL.
May 7, 2005, 1:39 AM
laurion
do a google search for free c++ compiler
May 7, 2005, 2:56 AM
OnlyMeat
[quote author=laurion link=topic=11497.msg111344#msg111344 date=1115434574]
do a google search for free c++ compiler
[/quote]

Actually there is nothing in that code that is c++. You could compile it in pure c.
May 7, 2005, 3:42 AM
shout
I wonder what
[code]
assert(0)
[/code]
did. The tool tip is as follows:
[code]
#define assert((void)0)
[/code]

???
May 7, 2005, 5:46 AM
Ringo
[quote author=UserLoser link=topic=11497.msg111308#msg111308 date=1115405926]

Just use D2Client.dll
[/quote]

I looked everywhere for it and all i could find was  this: https://davnit.net/bnet/vL/phpbbs/index.php?topic=3357.0

Also thanks Shout / laurion for helping!
May 7, 2005, 6:08 AM
laurion
yea that was a bad .dll so i fixed it, here
d2.zip
should work fine now.

source:
d2source.zip
source is C; was made using Dev-C++
May 7, 2005, 12:05 PM
Ringo
[quote author=laurion link=topic=11497.msg111366#msg111366 date=1115467525]
yea that was a bad .dll so i fixed it, here
d2.zip
should work fine now.

source:
d2source.zip
source is C; was made using Dev-C++
[/quote]

Thanks!
Im still getting the same problem, Entry point in the dll not found.
I found dev c++ on the web and downloaded it but have no clue how to use it.
Also im not sure how to open the source files correctly. (cant get it to compile)
I was wundering if it was how i was trying to call the functions or if it was the functions not letting me call them.
How would i open the 2 files together and change the functions from:
[code]
unsigned char*GamePacketSize(unsigned char *data, unsigned int *size,
                             unsigned int *offset)

int GamePacketDecode(unsigned char *indata, unsigned int insize,
                    unsigned char *outdata, unsigned int outmax,
                    unsigned int *outsize)
[/code]

to:
[code]
unsigned char __stdcall *GamePacketSize(unsigned char *data, unsigned int *size,
                             unsigned int *offset)

int __stdcall  GamePacketDecode(unsigned char *indata, unsigned int insize,
                    unsigned char *outdata, unsigned int outmax,
                    unsigned int *outsize)
[/code]

And would there be anything else that would need to be changed to call the functions like this?

Again thank you very much for helping!
May 7, 2005, 3:36 PM
KkBlazekK
Wait a minute... http://www.clanvl.net/ ?
May 7, 2005, 3:52 PM
QwertyMonster
[quote author=Blaze link=topic=11497.msg111385#msg111385 date=1115481173]
Wait a minute... http://www.clanvl.net/ ?
[/quote]

How does that help, or even on topic?..
May 7, 2005, 4:08 PM
Quarantine
Are you exporting the functions (using a .def file) correctly?
May 7, 2005, 6:18 PM
Ringo
Hmm iv tryed following tha tutorial as a referance, but it seems somwhat differnt to how it shows to do it, aslo i had the source  laurion posted as a dev referance, thanks!

Iv created new project in dev c++ with a c and a h file, iv got this atm (it does return some strange shit)

the c file:
[code]
/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

unsigned int CharIndex[] = {
   0x0247, 0x0236, 0x0225, 0x0214, 0x0203, 0x01F2, 0x01E1, 0x01D0,
   0x01BF, 0x01AE, 0x019D, 0x018C, 0x017B, 0x016A, 0x0161, 0x0158,
   0x014F, 0x0146, 0x013D, 0x0134, 0x012B, 0x0122, 0x0119, 0x0110,
   0x0107, 0x00FE, 0x00F5, 0x00EC, 0x00E3, 0x00DA, 0x00D1, 0x00C8,
   0x00BF, 0x00B6, 0x00AD, 0x00A8, 0x00A3, 0x009E, 0x0099, 0x0094,
   0x008F, 0x008A, 0x0085, 0x0080, 0x007B, 0x0076, 0x0071, 0x006C,
   0x0069, 0x0066, 0x0063, 0x0060, 0x005D, 0x005A, 0x0057, 0x0054,
   0x0051, 0x004E, 0x004B, 0x0048, 0x0045, 0x0042, 0x003F, 0x003F,
   0x003C, 0x003C, 0x0039, 0x0039, 0x0036, 0x0036, 0x0033, 0x0033,
   0x0030, 0x0030, 0x002D, 0x002D, 0x002A, 0x002A, 0x0027, 0x0027,
   0x0024, 0x0024, 0x0021, 0x0021, 0x001E, 0x001E, 0x001B, 0x001B,
   0x0018, 0x0018, 0x0015, 0x0015, 0x0012, 0x0012, 0x0012, 0x0012,
   0x000F, 0x000F, 0x000F, 0x000F, 0x000C, 0x000C, 0x000C, 0x000C,
   0x0009, 0x0009, 0x0009, 0x0009, 0x0006, 0x0006, 0x0006, 0x0006,
   0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
   0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
unsigned char CharTable[] = {
   0x00,0x00,0x01,0x00,0x01,0x04,0x00,0xFF,0x06,0x00,0x14,0x06,
   0x00,0x13,0x06,0x00,0x05,0x06,0x00,0x02,0x06,0x00,0x80,0x07,
   0x00,0x6D,0x07,0x00,0x69,0x07,0x00,0x68,0x07,0x00,0x67,0x07,
   0x00,0x1E,0x07,0x00,0x15,0x07,0x00,0x12,0x07,0x00,0x0D,0x07,
   0x00,0x0A,0x07,0x00,0x08,0x07,0x00,0x07,0x07,0x00,0x06,0x07,
   0x00,0x04,0x07,0x00,0x03,0x07,0x00,0x6C,0x08,0x00,0x51,0x08,
   0x00,0x20,0x08,0x00,0x1F,0x08,0x00,0x1D,0x08,0x00,0x18,0x08,
   0x00,0x17,0x08,0x00,0x16,0x08,0x00,0x11,0x08,0x00,0x10,0x08,
   0x00,0x0F,0x08,0x00,0x0C,0x08,0x00,0x0B,0x08,0x00,0x09,0x08,
   0x01,0x96,0x09,0x97,0x09,0x01,0x90,0x09,0x95,0x09,0x01,0x64,
   0x09,0x6B,0x09,0x01,0x62,0x09,0x63,0x09,0x01,0x56,0x09,0x58,
   0x09,0x01,0x52,0x09,0x55,0x09,0x01,0x4D,0x09,0x50,0x09,0x01,
   0x45,0x09,0x4C,0x09,0x01,0x40,0x09,0x43,0x09,0x01,0x31,0x09,
   0x3B,0x09,0x01,0x28,0x09,0x30,0x09,0x01,0x1A,0x09,0x25,0x09,
   0x01,0x0E,0x09,0x19,0x09,0x02,0xE2,0x0A,0xE8,0x0A,0xF0,0x0A,
   0xF8,0x0A,0x02,0xC0,0x0A,0xC2,0x0A,0xCE,0x0A,0xE0,0x0A,0x02,
   0xA0,0x0A,0xA2,0x0A,0xB0,0x0A,0xB8,0x0A,0x02,0x8A,0x0A,0x8F,
   0x0A,0x93,0x0A,0x98,0x0A,0x02,0x81,0x0A,0x82,0x0A,0x83,0x0A,
   0x89,0x0A,0x02,0x7C,0x0A,0x7D,0x0A,0x7E,0x0A,0x7F,0x0A,0x02,
   0x77,0x0A,0x78,0x0A,0x79,0x0A,0x7A,0x0A,0x02,0x73,0x0A,0x74,
   0x0A,0x75,0x0A,0x76,0x0A,0x02,0x6E,0x0A,0x6F,0x0A,0x70,0x0A,
   0x72,0x0A,0x02,0x61,0x0A,0x65,0x0A,0x66,0x0A,0x6A,0x0A,0x02,
   0x5D,0x0A,0x5E,0x0A,0x5F,0x0A,0x60,0x0A,0x02,0x57,0x0A,0x59,
   0x0A,0x5A,0x0A,0x5B,0x0A,0x02,0x4A,0x0A,0x4B,0x0A,0x4E,0x0A,
   0x53,0x0A,0x02,0x46,0x0A,0x47,0x0A,0x48,0x0A,0x49,0x0A,0x02,
   0x3F,0x0A,0x41,0x0A,0x42,0x0A,0x44,0x0A,0x02,0x3A,0x0A,0x3C,
   0x0A,0x3D,0x0A,0x3E,0x0A,0x02,0x36,0x0A,0x37,0x0A,0x38,0x0A,
   0x39,0x0A,0x02,0x32,0x0A,0x33,0x0A,0x34,0x0A,0x35,0x0A,0x02,
   0x2B,0x0A,0x2C,0x0A,0x2D,0x0A,0x2E,0x0A,0x02,0x26,0x0A,0x27,
   0x0A,0x29,0x0A,0x2A,0x0A,0x02,0x21,0x0A,0x22,0x0A,0x23,0x0A,
   0x24,0x0A,0x03,0xFB,0x0B,0xFC,0x0B,0xFD,0x0B,0xFE,0x0B,0x1B,
   0x0A,0x1B,0x0A,0x1C,0x0A,0x1C,0x0A,0x03,0xF2,0x0B,0xF3,0x0B,
   0xF4,0x0B,0xF5,0x0B,0xF6,0x0B,0xF7,0x0B,0xF9,0x0B,0xFA,0x0B,
   0x03,0xE9,0x0B,0xEA,0x0B,0xEB,0x0B,0xEC,0x0B,0xED,0x0B,0xEE,
   0x0B,0xEF,0x0B,0xF1,0x0B,0x03,0xDE,0x0B,0xDF,0x0B,0xE1,0x0B,
   0xE3,0x0B,0xE4,0x0B,0xE5,0x0B,0xE6,0x0B,0xE7,0x0B,0x03,0xD6,
   0x0B,0xD7,0x0B,0xD8,0x0B,0xD9,0x0B,0xDA,0x0B,0xDB,0x0B,0xDC,
   0x0B,0xDD,0x0B,0x03,0xCD,0x0B,0xCF,0x0B,0xD0,0x0B,0xD1,0x0B,
   0xD2,0x0B,0xD3,0x0B,0xD4,0x0B,0xD5,0x0B,0x03,0xC5,0x0B,0xC6,
   0x0B,0xC7,0x0B,0xC8,0x0B,0xC9,0x0B,0xCA,0x0B,0xCB,0x0B,0xCC,
   0x0B,0x03,0xBB,0x0B,0xBC,0x0B,0xBD,0x0B,0xBE,0x0B,0xBF,0x0B,
   0xC1,0x0B,0xC3,0x0B,0xC4,0x0B,0x03,0xB2,0x0B,0xB3,0x0B,0xB4,
   0x0B,0xB5,0x0B,0xB6,0x0B,0xB7,0x0B,0xB9,0x0B,0xBA,0x0B,0x03,
   0xA9,0x0B,0xAA,0x0B,0xAB,0x0B,0xAC,0x0B,0xAD,0x0B,0xAE,0x0B,
   0xAF,0x0B,0xB1,0x0B,0x03,0x9F,0x0B,0xA1,0x0B,0xA3,0x0B,0xA4,
   0x0B,0xA5,0x0B,0xA6,0x0B,0xA7,0x0B,0xA8,0x0B,0x03,0x92,0x0B,
   0x94,0x0B,0x99,0x0B,0x9A,0x0B,0x9B,0x0B,0x9C,0x0B,0x9D,0x0B,
   0x9E,0x0B,0x03,0x86,0x0B,0x87,0x0B,0x88,0x0B,0x8B,0x0B,0x8C,
   0x0B,0x8D,0x0B,0x8E,0x0B,0x91,0x0B,0x03,0x2F,0x0B,0x4F,0x0B,
   0x54,0x0B,0x5C,0x0B,0x71,0x0B,0x7B,0x0B,0x84,0x0B,0x85,0x0B
};
unsigned int BitMasks[] = {
   0x0000,0x0001,0x0003,0x0007,0x000F,0x001F,0x003F,0x007F,
   0x00FF,0x01FF,0x03FF,0x07FF,0x0FFF,0x1FFF,0x3FFF,0x7FFF
};

DLLIMPORT unsigned char __stdcall *GamePacketSize(unsigned char *data, unsigned int *size,
                             unsigned int *offset)
{
   unsigned int a;
   if (data[0] < 0xF0) {
       *size = data[0] - 1;
       *offset = 1;
       return &data[1];
   }
   a = (data[0] & 0xF) << 8;
   *size = a + data[1] - 2;
   *offset = 2;
   return &data[2];
}

DLLIMPORT int __stdcall GamePacketDecode(unsigned char *indata, unsigned int insize,
                    unsigned char *outdata, unsigned int outmax,
                    unsigned int *outsize)
{
   unsigned int a, b, c, d;
   unsigned int maxcnt, index, cnt;
   unsigned char *outptr, *inptr;
   int size;
   b = 0;
   size = insize;
   inptr = indata;
   maxcnt = outmax;
   outptr = outdata;
   cnt = 0x20;
   
   while (1) {
       if (cnt >= 0x8) {
           while (size > 0 && cnt >= 8) {
               cnt -= 0x8;
               size--;
               a = *inptr++ << cnt;
               b |= a;
           };
       }
       index = CharIndex[b >> 0x18];
       a = CharTable[index];
       d = (b >> (0x18 - a)) & BitMasks[a];
       c = CharTable[index + 2*d + 2];
       cnt += c;
       if (cnt > 0x20) {
           *outsize = outmax - maxcnt;
           return 1;
       }
       if (maxcnt-- == 0)
           return 0;
       a = CharTable[index + 2*d + 1];
       *outptr++ = (unsigned char)a;
       b <<= (c & 0xFF);
   }
   assert(0);
   return 0;
}



BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}
[/code]

the h file:
[code]
#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */


//DLLIMPORT unsigned char *GamePacketSize (unsigned char);
//DLLIMPORT int GamePacketDecode (int);


#endif /* _DLL_H_ */
[/code]

May 7, 2005, 6:42 PM
Ringo
In:
[code]
3F 1F 1C 30 02 10 52 1D 29 0A 85 D5 22 AB 8D 66 65 96 9E 88 59 B0 B0 07 97 C0 B8 9C 36 99 81 76 96 A9 0C 00 84 14 87 4E 04 4C C0 23 4F 44 2C D8 52 1C 80 01 38 02 B8 25 33 1B 9A 7A 21 66 C0
[/code]

out:
[code]
03 00 8A 01 F2 AA B3 23 67 E4 95 67 47 01 72 0F 63 14 01 00 07 4B 00 05 6D 91 97 9E 3D 74 0F 9E 14 80 67 F2 AA B3 23 01 94 0F 71 14 01 00 07 4B 00 05 67 22 2F 3D 7B 01 AE 0F 75 14 01 00
[/code]

That looks a good sign!
I'v only tested it with that packet and havent tryed running incoming data through it yet. looks like theres a few null terminated string in there tho!


Thanks to everyone who helped!
Mostly to laurion, thank you ;)
Thanks to Brand.X for posting the code back in oct 2003.
Also thanks to MyndFyre, i will carry on trying to port it to VB in the not so distant future as i have your post to help me through it and can now 'see' the packets, so it should give me a bigger picture over time of how the decompression is fully working (and my head a rest)

I think there are a few others looking for d2 packet decompression as well, so i will put there dll here for them.
Iv also included a txt in the zip showing how to use the exports in VB6 to save people some trubble.

D2GS.dll
May 8, 2005, 1:48 AM
Ringo
Seems to crash when i try run large packets through it (like when on connecting to the game server)
Im thinking it might be a memery leek or somthing but im unsure.
Iv currently got it working by puting any packet over 15 bytes or under 100 through it and it seems to just about beable to hold out.

More of a warning to anyone that wants to use it.

The dll code is the same as the code posted 2 posts up and my calls to the dll in VB6 look somthing like this:
[code]
On Error Resume Next
Dim offset As Long
Dim Size As Long
Dim H1 As String
Dim H2 As Integer
Dim outdata As String
Dim maxsize As Long
Dim outsize As Long

H1 = GamePacketSize(data, Size, offset)
outdata = String(Size, vbNullChar)
H2 = GamePacketDecode(Mid(data, offset), Size, outdata, Len(outdata), outsize)
[/code]

could anyone take a few min to scroll through the dll source (above) and check that im not missing anything, and that my calls in VB match those in the dll? i kinda tolk a guess int was refering to an integer and char was refering to a String, im hoping i havent got somthing silly like that mixed up but still unsure.


May 8, 2005, 6:21 AM
laurion
[quote author=Ringo link=topic=11497.msg111473#msg111473 date=1115533319]
Seems to crash when i try run large packets through it (like when on connecting to the game server)
Im thinking it might be a memery leek or somthing but im unsure.
Iv currently got it working by puting any packet over 15 bytes or under 100 through it and it seems to just about beable to hold out.

More of a warning to anyone that wants to use it.

The dll code is the same as the code posted 2 posts up and my calls to the dll in VB6 look somthing like this:
[code]
On Error Resume Next
Dim offset As Long
Dim Size As Long
Dim H1 As String
Dim H2 As Integer
Dim outdata As String
Dim maxsize As Long
Dim outsize As Long

H1 = GamePacketSize(data, Size, offset)
outdata = String(Size, vbNullChar)
H2 = GamePacketDecode(Mid(data, offset), Size, outdata, Len(outdata), outsize)
[/code]

could anyone take a few min to scroll through the dll source (above) and check that im not missing anything, and that my calls in VB match those in the dll? i kinda tolk a guess int was refering to an integer and char was refering to a String, im hoping i havent got somthing silly like that mixed up but still unsure.



[/quote]
I think what Brand.X posted might be outdated, obsolete..?
May 8, 2005, 3:23 PM
Ringo
[quote author=laurion link=topic=11497.msg111526#msg111526 date=1115565804]
I think what Brand.X posted might be outdated, obsolete..?
[/quote]

Thats what i 1st thought, seems as mid 1.10 they introduced alot of new rune word items.
After some testing this after noon i found that it seems to be decompressing the packets ok:
[code]Sent from D2 >
15 01 00 54 45 53 54 20 54 45 53 54 20 54 45 53    ...TEST TEST TES
54 20 54 45 53 54 20 54 45 53 54 20 54 45 53 54    T TEST TEST TEST
20 67 6F 74 20 49 74 3F 20 3B 29 00 00 00           got It? ;)...
[/code]



[code]Recv from my bot >
42 0F 1E BF C5 F2 8A B5 2A 86 D1 90 6C 14 C6 41    B.......*...l..A
CA 00 8A 02 D8 02 3B 00 45 01 6C 01 1D 80 22 80    ......;.E.l...".
B6 00 8E C0 11 40 5B 00 47 60 08 A0 2D 80 23 B0    .....@[.G`..-.#.
04 50 16 C0 11 DA 91 A4 6D 3B 15 C6 D1 40 EC 9A    .P......m;...@..
1F 40                                              .@

After decomression:
06 C9 01 00 02 00 00 00 00 00 5B 4C 69 67 68 74    ..........[Light
61 73 44 61 79 00 54 45 53 54 20 54 45 53 54 20    asDay.TEST TEST
54 45 53 54 20 54 45 53 54 20 54 45 53 54 20 54    TEST TEST TEST T
45 53 54 20 67 6F 74 20 49 74 3F 20 3B 00 00 00    EST got It? ;...
00                                                 .
[/code]

The problem seems to be when its in the middle of decompressing a packet and another 1 gets put into the function, it causes VB6 to generate a error report.

After linking data to a command click sub and holding down the enter key, i did notice my cpu useage go up a fair bit but VB6 didnt crash for some reassion.

Im pritty sure its a memery leek somwhere in the dll thats causeing the slow decompression to take place but im not sure where i should be looking in the dll to try fix it, if thats where the problem is.

Also if i dont use 'On Erorr Resume Next' when calling the functions in VB6, i get a run time error '7' out of memery.

Im right out of ideas on this one :(
May 8, 2005, 10:53 PM
laurion
[quote author=Ringo link=topic=11497.msg111586#msg111586 date=1115592787]
...The problem seems to be when its in the middle of decompressing a packet and another 1 gets put into the function, it causes VB6 to generate a error report.
[/quote]
Create a queue type of thing. Add a listview to your form, or create an array. Everytime new data is received, add it to the array or listview. Create a timer that fires every second, or whatever, and decompress the first item, and remove it. That would solve that problem (if that is your problem, what you said in the quote).
May 8, 2005, 11:01 PM
Ringo
Iv thought of a few things like that, but the only ever time iv had this from useing a dll export was when useing the AlphaBlend export in msimg32.dll
(uses the TransparentBlt function in the GDI32 api witch has a nasty memery leek)
I dont know alot about memery leeks, but it seems to be giving the signs of one.

I might have to end up doing somthing like you said, but im not sure if it could keep up with the speed the data comes in.
Somthing iv never tryed is try useing 2 of the same dll's both in differnt locations in the app path to gain a 2nd set of functioins to optimize speed. Could this psossibly work?

Thanks for the help
May 8, 2005, 11:52 PM
UserLoser.
[quote author=laurion link=topic=11497.msg111588#msg111588 date=1115593288]
[quote author=Ringo link=topic=11497.msg111586#msg111586 date=1115592787]
...The problem seems to be when its in the middle of decompressing a packet and another 1 gets put into the function, it causes VB6 to generate a error report.
[/quote]
Create a queue type of thing. Add a listview to your form, or create an array. Everytime new data is received, add it to the array or listview. Create a timer that fires every second, or whatever, and decompress the first item, and remove it. That would solve that problem (if that is your problem, what you said in the quote).
[/quote]

Using a listview (or any object) to store data is the worst idea possible in this case.  VB, use a collection
May 9, 2005, 3:33 AM
NetNX
Well, I have tryed everything i know how todo to make this dll work it only partialy returns the decrypted message... Is there any particular reason why it would do this?
May 9, 2005, 10:23 PM
Ringo
[quote author=NetNX link=topic=11497.msg111768#msg111768 date=1115677423]
Well, I have tryed everything i know how todo to make this dll work it only partialy returns the decrypted message... Is there any particular reason why it would do this?
[/quote]

Have you tryed adding extra padding to the end of the message before decomressing it?

when testing i found when decomressing, based on the char's and the lengh of the chat packet you decomress,  had a big impackt on the data after decompression

I'v only tryed this on chat packets tho ( 0x0F before decomression ) and it seems to be giving me a good message:
[code]
On Error Resume Next
Dim offset As Long
Dim Size As Long
Dim H1 As String
Dim H2 As Integer
Dim outdata As String
Dim maxsize As Long
Dim outsize As Long

'D2GS_DATA = Data from server >

H1 = GamePacketSize(D2GS_DATA, Size, offset)
outdata = String(Size + 6, vbNullChar)
H2 = GamePacketDecode(Mid(D2GS_DATA, 1 + offset), Size + 5, outdata, Size + 5, outsize)

'outdata = decompressed data.
[/code]

If useing the same dll as this one im useing, do you have much problems with your project crashing in run time?
I think i know what the problem could partly be, if your getting the same problems as what im getting (mainly crashing when trying to decompress to many at once) it might give me more of a specific idea to what the problem could be.

thanks
May 9, 2005, 11:01 PM
Ringo
Iv fixed the memery leek in the dll, it was a  __declspec clashing with a __stdcall that was causing the extreamly slow decomression to take place.
I can jam almost anything through it at any speed with out hardly any system resources been taken up, but some shorter packets will still crash it. (guessing because of changes in 1.10)  It only seems to be packets shorter than 16 bytes tho.. but iv currently wrote a handler for these kind of packets and it seems to be working (and gives good packet format after decompression) or seems to be anyway.

Iv changed the link to the dll witch can be downloaded here:  D2GS.dll

Thanks again to everyone who helped with this!
Should beable to have some stable D2GS chatting now :)
May 11, 2005, 4:49 AM
NetNX
:D I'm at school right now ~_^ but i will definitly try that thanks for the suggestion and update can u contact me on AIM later? my SN is Grim Reaper Ice

<3 ~_^
May 11, 2005, 5:34 PM

Search