Valhalla Legends Forums Archive | Battle.net Bot Development | [VB] D2GS Parser

AuthorMessageTime
LivedKrad
I am at the end of my sanity! I cannot for the life of me figure out why my parsing routine continually comes up with packet values higher than the highest packet (0xB3) or why it comes up with packet values that are of size 0 in the packet size table. Someone help me please, for the safety of me and others around me:

*Note: According to the decompressing functions of D2GS.dll, the compressed data is passed to the decompressor, and is output like "data" + "2F" + loads of nulled padding. (0x2F in the packet size table is considered of value 0, so technically it shouldn't be a packet and thus why it is used as a terminator).

[code]
Public Sub D2GSParserRoutine(ByVal data As String)
If data = vbNullString Then
  Exit Sub
End If
Dim pid As Byte
Dim pSize As Long
Dim tmpSize As Byte
Dim pName As String
pid = Asc(Mid$(data, 1, 1))
'AddChat2 vbWhite, DebugOutput(data)

'If pid = &HFF Then
'Call D2GSParserRoutine(Mid$(data, 2))
'Exit Sub
'End If

  If pid > 179 Then
AddChat vbWhite, "Broke on packet: 0x" & Hex(pid)
  AddChat2 vbWhite, "Last packet dump: " & DebugOutput(lastPacketDump)
AddChat2 vbWhite, "Dump: " & DebugOutput(data)
Exit Sub
  Else
  pSize = PACKET_SIZE(pid)
pName = vbNullString
End If

If pid = &H2F Then
'AddChat vbMagenta, "End of packet."
Exit Sub
End If

If pSize = &HFFFFFFFF Then

Select Case pid
  Case &HAA
  tmpSize = Asc(Mid$(data, 7, 1))
  Case &HAC
  tmpSize = Asc(Mid$(data, 13, 1))
  Case &H26
  tmpSize = Parsechat(data)
    If tmpSize = 0 Then
    Exit Sub
    End If
  Case &H5B
  AddChat &H80FF&, "Player in game: " & Mid$(data, 9, 15)
  ObjectId.numPlayers = ObjectId.numPlayers + 1
  tmpSize = Asc(Mid$(data, 2, 1))
  Case &H94
  tmpSize = 6 + ((Asc(Mid$(data, 2, 1)) * 3))
  AddChat vbCyan, "precasting.."
  Case &H9C
  tmpSize = Asc(Mid$(data, 3, 1))
  Case &H9D
  tmpSize = Asc(Mid$(data, 3, 1))
  Case &HA8
  tmpSize = Asc(Mid$(data, 7, 1))
  Case Else
  AddChat2 vbWhite, "Encountered packet with unknown size: 0x" & Hex(pid)
  AddChat2 vbWhite, "Dump: " & DebugOutput(data)
  Form1.scktD2GS.Close
  Exit Sub
End Select

AddChat vbWhite, "Received packet: 0x" & Hex(pid)
lastPacketDump = Mid$(data, 1, tmpSize + 3)
Call D2GSParserRoutine(Mid$(data, tmpSize + 1))
End If

If pSize <> &HFFFFFFFF And pSize <> &H0 Then

Select Case pid
  Case &H1
  pName = "Game acceptance??"
 
  Case &H51
  Dim objectType As Byte
  Dim ObjId As Long
  pName = "World object location"
  objectType = Asc(Mid$(data, 7, 1))
  ObjId = gdword(Mid$(data, 3, 4))
 
        AddChat &H80FF&, "World map info: Object type " & Hex(objectType)
       
    If objectType = &HB Then
              AddChat &H80FF&, "Stash found within 10 paces."
              ObjectId.Stash = ObjId
              InsertDWORD &H2
              InsertDWORD ObjectId.Stash
              D2GSSend (&H13)
              Call SendChat("Opened stash, ID = " & ObjectId.Stash, vbNullString, &H1)
    End If
   
  Case &H5A
  pName = "Player status"
  Dim pType As Byte
  Dim character As String
  p_data = Mid$(data, 2, pSize)
  pType = getBYTE
  getBYTE
  getDWORD
  getBYTE
  character = getSTRING
 
    Select Case pType
    Case &H0
      AddChat &HA0522D, character & " has dropped due to timeout."
    Case &H2
      AddChat &HA0522D, character & " has joined our world. Diablo's minions grow stronger! Ahh!"
    Case &H3
      AddChat &HA0522D, character & " has left our world. Diablo 2 will be better off."
    End Select
 
  Case &H76
  pName = "Player location (World)"
 
  Case &H8B
  Dim playerID As Long
  Dim status As Byte
  pName = "Player relations"
  p_data = Mid$(data, 2, 5)
 
  playerID = getDWORD
  status = getBYTE
 
    Select Case status
    Case &H2
      AddChat vbGreen, "A player wishes to party with you."
      InsertBYTE &H8
      InsertDWORD playerID
      D2GSSend (&H5E)
    Case &H1
      AddChat vbGreen, "A player has joined a party."
    Case &H0
      AddChat vbGreen, "A player is not in a party."
            InsertBYTE &H6
      InsertDWORD playerID
      D2GSSend (&H5E)
    End Select
 
End Select

AddChat vbWhite, "Received packet: 0x" & Hex(pid) & " *" & pName & "*"
  lastPacketDump = Mid$(data, 1, pSize + 3)
Call D2GSParserRoutine(Mid$(data, pSize + 1))
End If

If pSize = 0 Then
  AddChat vbWhite, "Received invalid packet?: 0x" & Hex(pid)
  AddChat2 vbWhite, "Last packet dump: " & DebugOutput(lastPacketDump)
  AddChat2 vbWhite, "Dump: " & DebugOutput(data)
  Exit Sub
End If

End Sub
[/code]
July 15, 2005, 12:25 AM
Ringo
If you know the packets you need to read but have problems getting to them, make a filter parser :P
When i said the other day i had only 4 packets in a parser, i only had 4 packet lenghs in there as well.

[edit]
The 0x2F terminator is caused by the extra padding created inorder to stop it from crashing.
July 15, 2005, 12:58 AM
LivedKrad
Filter parser?
July 15, 2005, 1:06 AM
Ringo
The idea is to know as much as possible about the packets your trying to parse, like what values it has in it, and what numbers they should range in, and so on.
Iv tryed countless methods, and this is the better one iv come up with, but only works perfectly if you parse alot of packets.
[code]
    Case &HB4 to &HFF: PARSE_D2GS Mid(Data, 2)

    Case &H15
      'player reasign
        '15 01 XX XX XX XX >> >> ^^ ^^ 01
        If IsValid_0x15(Data, rLen) = True Then
            gs0x15 Left(Data, rLen - 1)
        End If
        PARSE_D2GS Mid(Data, rLen)
[/code]

rLen should always return a lengh, even if the packet was found to be invalid (return 2)
This is kinda a sucky method, but it works :P
Iv since come up with a better method, but your welcome to this one if you want it :)
July 15, 2005, 1:18 AM
Tontow
Do a search, but this link might be of some help. https://davnit.net/bnet/vL/phpbbs/index.php?topic=12188.0
July 15, 2005, 1:52 AM
Elneroth
[quote author=Tontow link=topic=12225.msg120774#msg120774 date=1121392371]
Do a search, but this link might be of some help. https://davnit.net/bnet/vL/phpbbs/index.php?topic=12188.0
[/quote]

You do realize, he's the one who made that post, right? :p
July 15, 2005, 2:05 AM
Archangel
[quote author=Tontow link=topic=12225.msg120774#msg120774 date=1121392371]
Do a search, but this link might be of some help. https://davnit.net/bnet/vL/phpbbs/index.php?topic=12188.0
[/quote]

Dude.. lol...
Read the links you are posting before doing so.
July 15, 2005, 3:51 AM
Tontow
Opps, umm, the Devil made me do it?
July 15, 2005, 3:09 PM
R.a.B.B.i.T
Devil*?
July 15, 2005, 4:53 PM
LivedKrad
[quote author=Ringo link=topic=12225.msg120770#msg120770 date=1121390292]
The idea is to know as much as possible about the packets your trying to parse, like what values it has in it, and what numbers they should range in, and so on.
Iv tryed countless methods, and this is the better one iv come up with, but only works perfectly if you parse alot of packets.
[code]
    Case &HB4 to &HFF: PARSE_D2GS Mid(Data, 2)

    Case &H15
      'player reasign
        '15 01 XX XX XX XX >> >> ^^ ^^ 01
        If IsValid_0x15(Data, rLen) = True Then
            gs0x15 Left(Data, rLen - 1)
        End If
        PARSE_D2GS Mid(Data, rLen)
[/code]

rLen should always return a lengh, even if the packet was found to be invalid (return 2)
This is kinda a sucky method, but it works :P
Iv since come up with a better method, but your welcome to this one if you want it :)
[/quote]

We all share information on the forums, Ringo. If you're holding out on a more efficient parsing method, I'm open for suggestions. According to the table found by UserLoser in D2Net.dll, I have the packet lengths right for the definite length ones. However, since the data still seems to be not working when I try the parsing, it's odd that the parser seems to break on invalid packets or ones that are greater than 0xB3. I'm not saying it's any cut on your documentation, but I just don't know what else to do. I've been over my coding over and over again and for the life of me I cannot figure out what my problem is.

Thanks, and appreciate all the help I can get.
July 16, 2005, 1:04 AM
Ringo
Split up the large packets as well as the small packets, and you wont get a problem with crap data (the lengh header of a new compressed packet) ;)
July 16, 2005, 4:16 AM
LivedKrad
"splitting up" these packets is the entire front-end point of the parser. So, once again, please elborate.
July 16, 2005, 5:09 PM
Ringo
[quote author=LivedKrad.fe link=topic=12225.msg120995#msg120995 date=1121533785]
"splitting up" these packets is the entire front-end point of the parser. So, once again, please elborate.
[/quote]
You need to split up the compressed packets as well as splitting them up after you decompress them.
Thats why the server adds a lengh header to the buffer before sending it to you :P
The reassion they are clumped after there compressed, is because of the way a tcp socket works
July 16, 2005, 6:20 PM

Search