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).
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
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.
Filter parser?
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.
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)
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 :)
Do a search, but this link might be of some help. http://forum.valhallalegends.com/phpbbs/index.php?topic=12188.0
Quote from: Tontow on July 14, 2005, 08:52 PM
Do a search, but this link might be of some help. http://forum.valhallalegends.com/phpbbs/index.php?topic=12188.0
You do realize, he's the one who made that post, right? :p
Quote from: Tontow on July 14, 2005, 08:52 PM
Do a search, but this link might be of some help. http://forum.valhallalegends.com/phpbbs/index.php?topic=12188.0
Dude.. lol...
Read the links you are posting before doing so.
Opps, umm, the Devil made me do it?
Devil*?
Quote from: Ringo on July 14, 2005, 08:18 PM
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.
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)
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 :)
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.
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) ;)
"splitting up" these packets is the entire front-end point of the parser. So, once again, please elborate.
Quote from: LivedKrad.fe on July 16, 2005, 12:09 PM
"splitting up" these packets is the entire front-end point of the parser. So, once again, please elborate.
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