I've looked through BnetDocs & know what each little thing is, I'm just not sure as how to go about seperating each little part on it's own.
Quote0000 FF 65 46 00 04 65 2D 33 37 37 00 00 00 00 00 00 .eF..e-377......
0010 00 00 5A 65 74 68 33 44 00 00 00 00 00 00 00 00 ..Zeth3D........
0020 43 72 41 7A 33 44 5B 78 4C 5D 00 01 02 50 58 45 CrAz3D[xL]...PXE
0030 53 4F 70 20 45 78 69 6C 65 00 41 6C 61 6E 00 00 SOp Exile.Alan..
0040 02 4E 42 32 57 00 .NB2W.
I know I have 4 friends.
Grab first byte, loop that many times through the remaining data grabbing each part at a time. It's not even close to being hard. Same way you extract the 4 bytes from a chat event for id, ping, flags, the remaining bytes for username, and text. Except in this case, you're looping X (where X is the amount of friends) amount of times
Quote from: UserLoser on February 27, 2005, 10:47 PM
Grab first byte, loop that many times through the remaining data grabbing each part at a time. It's not even close to being hard. Same way you extract the 4 bytes from a chat event for id, ping, flags, the remaining bytes for username, and text. Except in this case, you're looping X (where X is the amount of friends) amount of times
Ok, I loop through it 4 times (in mycase), but how do I know when to start at the top again? When I've found 5 items?
After going through X times, you should have exhausted the packet and you can quit parsing. There's no need to loop around.
K, I've gone through the packet X times, but I am obviouslyt seperating the info incorrectly.
This is "DATA"
Quote0000 FF 65 49 00 02 69 6C 6C 69 6E 69 6D 6F 6E 65 79 .eI..illinimoney
0010 31 33 00 00 02 50 58 45 53 42 72 6F 6F 64 20 57 13...PXESBrood W
0020 61 72 20 55 53 41 2D 31 00 68 65 6E 6B 79 31 39 ar USA-1.henky19
0030 39 32 00 00 02 50 58 45 53 42 72 6F 6F 64 20 57 92...PXESBrood W
0040 61 72 20 55 53 41 2D 31 00 ar USA-1.
This is how I parse "DATA"
Public Sub ParseFList(ByVal Data As String)
Dim d() As String, s As String, i As Byte, iPos As Integer
Dim Account As String, Status As Byte, Location As Byte, ProductID As Long, Channel As String
d = Split(Mid(Data, 6), Chr(0))
s = Mid(Data, 6)
If s = vbNullString Then Exit Sub
iPos = 1
For i = 0 To Asc(Mid(Data, 5, 1)) - 1
Account = BN.KillNull(Mid(s, iPos, InStr(iPos, s, Chr(0))))
iPos = iPos + Len(Account)
Status = Asc(Mid(s, iPos, 2))
iPos = iPos + Len(Status)
Location = Asc(Mid(s, iPos, 2))
iPos = iPos + Len(Location)
ProductID = BN.GetDWORD(Mid(s, iPos, 4))
iPos = iPos + Len(ProductID)
Channel = BN.KillNull(Mid(s, iPos, InStr(iPos, s, Chr(0))))
iPos = iPos + Len(Channel)
FN.Chat vbGreen, Account & " " & Status & " " & Location & " " & ProductID & " " & Channel
Next i
End Sub
This is what I get returned
Quote[10:57:01 PM] illinimoney13 0 0 1163415554 SBrood War USA-1
[10:57:02 PM] 0 104 2037083749 1992
I'm doing something wrong somewhere, but I'm not sure where, could anyone point it out to me?I JUST found something, I don't know why I was messing with it but I increased iPos by 1. Now I get the correct username, however I am missing the client.
Also, the large number is the ProductID, SHOULD it be like that?
Quote[11:01:12 PM] illinimoney13 0 0 1163415554 SBrood War USA-1
[11:01:12 PM] henky1992 0 0 1163415554 SBrood War USA-1
Somehow I've managed to almost make it work.
New problem is that when a user becomes offline, my parsing is thrown off
Quote0000: FF 65 5B 00 04 69 6C 6C 69 6E 69 6D 6F 6E 65 79 ÿe[.illinimoney
0010: 31 33 00 00 02 50 58 45 53 42 72 6F 6F 64 20 57 13..PXESBrood W
0020: 61 72 20 55 53 41 2D 31 00 68 65 6E 6B 79 31 39 ar USA-1.henky19
0030: 39 32 00 00 03 50 58 45 53 43 41 54 53 00 43 72 92..PXESCATS.Cr
0040: 61 7A 33 64 5B 78 6C 5D 00 00 00 00 00 00 00 00 az3d[xl]........
0050: 6A 69 6D 00 00 00 00 00 00 00 00 jim.............
[11:51:38 PM] illinimoney13 0 PXES Brood War USA-1
[11:51:38 PM] henky1992 0 PXES CATS
[11:51:38 PM] Craz3d[xl] 0
[11:51:38 PM] 0
For i = 0 To Asc(Mid(Data, 5, 1)) - 1
Account = BN.KillNull(Mid(s, iPos, InStr(iPos, s, Chr(0))))
iPos = iPos + Len(Account) + 1
Status = Asc(Mid(s, iPos, 2))
iPos = iPos + Len(Status)
Location = Asc(Mid(s, iPos, 2))
iPos = iPos + Len(Location)
ProductID = BN.KillNull(Mid(s, iPos, 4))
iPos = iPos + Len(ProductID)
Channel = BN.KillNull(Mid(s, iPos, InStr(iPos, s, Chr(0))))
iPos = iPos + Len(Channel)
iPos = iPos + 1
FN.Chat vbGreen, Account & " " & Str(Status) & " " & ProductID & " " & Channel
frmMain.lvFriends.ListItems.ADD , , Account, , FLIcon(StrReverse(ProductID), Status)
frmMain.lvFriends.ListItems(frmMain.lvFriends.ListItems.Count).Tag = "Logged on: " & GetClient(StrReverse(ProductID)) & vbCrLf & _
"Currently in: " & Channel & vbCrLf & "Status is currently: " & FLStatus(Status)
Next i
Quote....
Status = Asc(Mid(s, iPos, 2))
...
Location = Asc(Mid(s, iPos, 2))
.....
Byte = 1, Word = 2, it should be 1 not 2.
~-~(HDX)~-~
For i = 0 To Asc(Mid(Data, 5, 1)) - 1
Account = BN.KillNull(Mid(s, iPos, InStr(iPos, s, Chr(0)) - 1))
iPos = iPos + Len(Account) + 1
Status = Asc(Mid(s, iPos, 1))
iPos = iPos + Len(Status)
Location = Asc(Mid(s, iPos, 1))
iPos = iPos + Len(Location)
ProductID = BN.KillNull(Mid(s, iPos, 4))
iPos = iPos + 4
Channel = BN.KillNull(Mid(s, iPos, InStr(iPos, s, Chr(0)) - 1))
iPos = iPos + Len(Channel)
iPos = iPos + 1
Next i
That is what I ended up with. Thanks all, I'm thinking sleep helped, it took me less time to realize mistakes this morning.
Dim I As Byte
For I = 1 to m_Parse.ExtractByte
Username = m_Parse.ExtractString
Status = m_Parse.ExtractByte
Location = m_Parse.ExtractByte
Product = m_Parse.ExtractLong
Channel = m_Parse.ExtractString
'Todo: stuff
Next I
Hurm You could do that.. If you had those functions.
Witch I don't and nither does he i'm guessing. So. I'll write up some code and post it when I get home tonight.
~-~(HDX)~-~
Quote from: HdxBmx27 on February 28, 2005, 04:43 PM
Hurm You could do that.. If you had those functions.
Witch I don't and nither does he i'm guessing. So. I'll write up some code and post it when I get home tonight.
~-~(HDX)~-~
So then create those functions. I'm sure you don't have to because people have posted packet buffers on this forum before.
Quote from: UserLoser on February 28, 2005, 02:06 PM
Dim I As Byte
For I = 1 to m_Parse.ExtractByte
Username = m_Parse.ExtractString
Status = m_Parse.ExtractByte
Location = m_Parse.ExtractByte
Product = m_Parse.ExtractLong
Channel = m_Parse.ExtractString
'Todo: stuff
Next I
[off-topic] That code raises some interesting questions about VB in my mind. I'm not sure about the semantics of VB, but I noticed this:
For I = 1 to m_Parse.ExtractByte
I assume m_Parse is something that parses incoming data and then advances an internal indexer. Now, my question is this -- does VB evaluate the To expression only once, at the beginning of the loop, or at each iteration? If it evaluates the expression at each iteration, wouldn't that mess up the loop?
Quote from: MyndFyre on February 28, 2005, 05:40 PM
[off-topic] That code raises some interesting questions about VB in my mind. I'm not sure about the semantics of VB, but I noticed this:
For I = 1 to m_Parse.ExtractByte
I assume m_Parse is something that parses incoming data and then advances an internal indexer. Now, my question is this -- does VB evaluate the To expression only once, at the beginning of the loop, or at each iteration? If it evaluates the expression at each iteration, wouldn't that mess up the loop?
Here's your answer:
Public Sub Test()
Dim I As Integer
For I = 1 To GetMax()
Debug.Print ("I = " & I)
Next I
End Sub
Public Function GetMax() As Integer
Debug.Print ("GetMax()")
GetMax = 4
End Function
Outputs:
GetMax()
I = 1
I = 2
I = 3
I = 4
Most languages do this as
for-loops are for the most part simply syntactic sugar for
while-loops.
Quote from: dxoigmn on February 28, 2005, 05:45 PM
Quote from: MyndFyre on February 28, 2005, 05:40 PM
[off-topic] That code raises some interesting questions about VB in my mind. I'm not sure about the semantics of VB, but I noticed this:
For I = 1 to m_Parse.ExtractByte
I assume m_Parse is something that parses incoming data and then advances an internal indexer. Now, my question is this -- does VB evaluate the To expression only once, at the beginning of the loop, or at each iteration? If it evaluates the expression at each iteration, wouldn't that mess up the loop?
Here's your answer:
Public Sub Test()
Dim I As Integer
For I = 1 To GetMax()
Debug.Print ("I = " & I)
Next I
End Sub
Public Function GetMax() As Integer
Debug.Print ("GetMax()")
GetMax = 4
End Function
Outputs:
GetMax()
I = 1
I = 2
I = 3
I = 4
Most languages do this as for-loops are for the most part simply syntactic sugar for while-loops.
Okay, but what if there is a state change during the loop? I could see it if the function was declared const, but since it's VB.... I dunno. Thanks for the clarification though!
Option Explicit
Private strBuffer As String
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByRef destination As Any, ByRef Source As Any, ByVal numbytes As Long)
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Public Sub SetData(Data As String)
strBuffer = Data
End Sub
Public Function GetData() As String
GetData = strBuffer
End Function
Public Sub ClearData()
strBuffer = vbNullString
End Sub
Public Function removeFILETIME() As String
Dim strFT(1) As String
strFT = Split(removeNTString & Space(1), Space(1))
If strFT(0) > 2147483647 Then strFT(0) = (strFT(0) - 4294967296#)
If strFT(1) > 2147483647 Then strFT(1) = (strFT(1) - 4294967296#)
removeFILETIME = strFT(0) & Space(1) & strFT(1)
End Function
Public Function removeNonNTString() As String
removeNonNTString = Left(strBuffer, 4)
strBuffer = Mid(strBuffer, 5)
End Function
Public Function removeATString() As String
removeATString = Left(strBuffer, InStr(strBuffer, Chr(&HA)) - 1)
strBuffer = Mid(strBuffer, Len(removeATString) + 2)
End Function
Public Function removeNTString() As String
removeNTString = Left(strBuffer, InStr(strBuffer, Chr(&H0)) - 1)
strBuffer = Mid(strBuffer, Len(removeNTString) + 2)
End Function
Public Function removeDWORD() As Long
Dim lReturn As Long, strTmp As String
strTmp = Left(strBuffer, 4)
Call CopyMemory(lReturn, ByVal strTmp, 4)
removeDWORD = lReturn
strBuffer = Mid(strBuffer, 5)
End Function
Public Function removeWORD() As Long
Dim lReturn As Long, strTmp As String
strTmp = Left(strBuffer, 2)
Call CopyMemory(lReturn, ByVal strTmp, 2)
removeWORD = lReturn
strBuffer = Mid(strBuffer, 3)
End Function
Public Function removeBYTE() As Byte
removeBYTE = Asc(Left(strBuffer, 1))
strBuffer = Mid(strBuffer, 2)
End Function
Public Function removeVOID(Leng As Integer) As String
removeVOID = Left(strBuffer, Leng)
strBuffer = Mid(strBuffer, Leng + 1)
End Function
Hurm, thers a small class mod i wrote up real quick. Seems to work fine for 0x65.
Please post suggestions and comments, BUT ONLY if there helpfull, no "that code sucks" crap -.- its annoying.
~-~(HDX)~-~
Quote from: MyndFyre on February 28, 2005, 06:30 PM
Okay, but what if there is a state change during the loop? I could see it if the function was declared const, but since it's VB.... I dunno. Thanks for the clarification though!
You mean something like:
Public Sub Test()
Dim I as Integer
For I = 0 to 1
Debug.Print("I = " & I)
I = 0
Next I
End Sub
That would result in an infinite loop.
Changing your counter variables inside the loop can be dangerous if you don't know what you're doing.
But it's also a very common and useful feature of any half-way decent language.