Valhalla Legends Forums Archive | .NET Platform | [VB.NET] PacketBuffer

AuthorMessageTime
Fr0z3N
[code]
Public Class PacketBuffer

Dim Socket As CraftEngine.SocketClass
Private Buffer As String
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDst As IntPtr, ByVal pSrc As String, ByVal ByteLen As Long)

Public Function InsertDWORDArray(ByVal Data() As Long)
Dim i As Integer
For i = LBound(Data) To UBound(Data) Step 1
Buffer = Buffer & MakeDWORD(Data(i))
Next i
End Function

Public Function InsertDWORD(ByVal Data As Long)
Buffer = Buffer & MakeDWORD(Data)
End Function

Public Function InsertData(ByVal Data As String)
Buffer = Buffer & Data
End Function

Public Function InsertWORD(ByVal Data As Integer)
Buffer = Buffer & MakeWORD(Data)
End Function

Public Function InsertBYTE(ByVal Data As Integer)
Buffer = Buffer & Chr(Data)
End Function

Public Sub InsertBytes(ByVal Data As String)
Dim i As Long, Enqueueer As String
For i = 1 To Len(Data) Step 3
Enqueueer = Enqueueer & Chr(Val("&h0" & Mid(Data, i, 2)))
Next i
Buffer = Buffer & Enqueueer
End Sub

Public Function InsertNTString(ByVal Data As String)
Buffer = Buffer & Data & Chr(0)
End Function

Public Function InsertNonNTString(ByVal Data As String)
Buffer = Buffer & Data
End Function

Function MakeDWORD(ByVal Value As Long) As String
Dim Dst As IntPtr, Result As String
CopyMemory(Dst, Value, 4)
MakeDWORD = Result
End Function

Function MakeWORD(ByVal Value As Integer) As String
Dim Dst As IntPtr, Result As String
CopyMemory(Dst, Value, 2)
MakeWORD = Result
End Function

Public Function Clear()
Buffer = ""
End Function

Public Function SendPacket(ByVal PacketID As Byte)
Dim PacketData As String, Packet As String
If Socket.ReceiveSocket.Connected Then
Socket.Send(Chr(&HFF) & Chr(PacketID) & MakeWORD(Len(Buffer) + 4) & Buffer)
Clear()
End If
End Function


End Class
[/code]

Just wrote that, if anyone wants they can use it.
May 18, 2004, 11:36 AM
Myndfyr
[quote author=Fr0z3N link=board=37;threadid=6860;start=0#msg60634 date=1084880160]
[code]
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDst As IntPtr, ByVal pSrc As String, ByVal ByteLen As Long)
[/code]

Just wrote that, if anyone wants they can use it.
[/quote]

Eww @ using RtlMoveMemory. Use the BitConverter class instead. It's managed, so no costly P/Invoke calls.

Also, eww @ using a String buffer. Here's why:

.NET strings are Unicode, which means that each character within the strings is two bytes wide. It doesn't affect the representation of characters, but for a simple English text string, you have this in memory:

[code]
52 00 6F 00 62 00 00 00 R.o.b...
[/code]

Whereas by storing it in a byte array:

[code]
52 6F 62 00 Rob.
[/code]

Not only is it double your memory consumption, but also not what you want to send to Battle.net. See all the NULLs in there? Not a good idea.

It looks less like you "just wrote it" than took an existing Visual Basic PacketBuffer class, changed the types to match VB.NET, and send, "here you go."

Also, your Socket.Send(ByVal data As String) does not work. System.Net.Sockets.Socket requires a Byte() to be passed as data. So, your final lines should look like (assuming you upgrade your buffer to be a Byte() rather than a String):

[code]
Dim outArray(buffer.Length + 4) As Byte
outArray(0) = &HFF
outArray(1) = packetId
Array.Copy(BitConverter.GetBytes(CType(buffer.Length, Short)), 0, outArray, 2, 2)
Array.Copy(buffer, 0, outArray, 4, buffer.Length)
socket.Send(outArray)
[/code]

Why you would use the CraftEngine.SocketClass type is beyond me -- you want to use the simple .NET plain old Socket. You also don't want to associate a Socket with a particular PacketBuffer instance -- you should either use the PacketBuffer as a Shared class (so that all of its functions are Shared and belong to the class rather than an object), or use the Socket in an external class that just uses instances of PacketBuffer as needed. Placing the Socket within the PacketBuffer is bad object-oriented programming practices -- what does a connection have to do with a buffer? No, the connection belongs to the object or objects that made the connection.

Lastly, the Long type represents an 8-byte (64-bit) integer, a Quad-Word, not a Double-Word (DWORD). Check your "MakeDWORD(ByVal val As Long)" function.

If you want a model, my abstract C# Packet class should be able to be found on the BotDev forum. It could be easily converted to VB. Note that since the time I wrote it, I am no longer using an ArrayList as the buffer (as the byte values would require boxing and unboxing, which is costly), but a typed ArrayList meant specifically for byte values.

Cheers
May 18, 2004, 5:21 PM
Fr0z3N
I basically did just put a vb packetbuffer in there and get it to work get vb.net, I figured the WORD and DWORD and also the copymemory was wrong but I figured someone would point it out so I could fix it. CraftEngine.SocketClass is my socket class (where all my socket shit is).

(I've only been programming in VB.NET for the past 24 hours)

Thanks for your help, I'll correct it when I get home then post the correction.
May 18, 2004, 5:53 PM
Null
Dude , all this is , is DM's Pbuffer class...., i doubt u even wrote it out.
May 19, 2004, 5:23 AM
Grok
hehe ... man.
May 19, 2004, 11:18 AM
TheMinistered
Perhaps someone might consider extending the NetworkStream/StreamReader/StreamWriter for ease of sending packets?
May 23, 2004, 10:47 AM
Myndfyr
[quote author=TheMinistered link=board=37;threadid=6860;start=0#msg61331 date=1085309253]
Perhaps someone might consider extending the NetworkStream/StreamReader/StreamWriter for ease of sending packets?
[/quote]

I've thought about it, and also about using TcpClient rather than Socket. In the end, though, I decided against it. No particular reason, but I like the fact that I have a base Packet class that implements a ByteArrayList (I can't wait until generics!), and I've already made a class that uses a byte[] as a buffer to a single-direction read-only stream. I just don't need it. ^_^
May 23, 2004, 8:18 PM
Grok
[quote author=Myndfyre link=board=37;threadid=6860;start=0#msg61403 date=1085343519]
[quote author=TheMinistered link=board=37;threadid=6860;start=0#msg61331 date=1085309253]
Perhaps someone might consider extending the NetworkStream/StreamReader/StreamWriter for ease of sending packets?
[/quote]

I've thought about it, and also about using TcpClient rather than Socket. In the end, though, I decided against it. No particular reason, but I like the fact that I have a base Packet class that implements a ByteArrayList (I can't wait until generics!), and I've already made a class that uses a byte[] as a buffer to a single-direction read-only stream. I just don't need it. ^_^
[/quote]

But -- you could write the new CSB.NET for everyone! Then everyone could be a L33T.NET bot developer by including your assembly in their solution.

</sarcasm> please dont ;)
May 24, 2004, 1:16 AM
Myndfyr
[quote author=Grok link=board=37;threadid=6860;start=0#msg61455 date=1085361363]
[quote author=Myndfyre link=board=37;threadid=6860;start=0#msg61403 date=1085343519]
[quote author=TheMinistered link=board=37;threadid=6860;start=0#msg61331 date=1085309253]
Perhaps someone might consider extending the NetworkStream/StreamReader/StreamWriter for ease of sending packets?
[/quote]

I've thought about it, and also about using TcpClient rather than Socket. In the end, though, I decided against it. No particular reason, but I like the fact that I have a base Packet class that implements a ByteArrayList (I can't wait until generics!), and I've already made a class that uses a byte[] as a buffer to a single-direction read-only stream. I just don't need it. ^_^
[/quote]

But -- you could write the new CSB.NET for everyone! Then everyone could be a L33T.NET bot developer by including your assembly in their solution.

</sarcasm> please dont ;)
[/quote]

You know, Grok, I know we've discussed this before, and honestly I'm at a bit of an impasse. One of the goals of my bot was to use an appropriate encapsulation method so that modules each contained an appropriate, logical structure. One of the first things I did, then, was to separate off the connection API, data API, and plugin API into separate assemblies that could be included into other applications.

I suppose I could apply some code-access attributes to prevent assemblies other than my own from accessing the API without a certain private key.

Just for shits and giggles, I decided to make a bot based on my connection API in VB .NET. It's not complete, because I had to stop work on it to go to work, but a basic chat client (binary support) took about two hours of coding, and I'm not a VB developer.

Would there be an appropriate place to put a poll up? I think I might on BotDev.....
May 24, 2004, 5:10 PM
Grok
Ah, this is what you were talking about. Come on, don't let anyone unduly influence you. We may laugh at CSB users, but I wouldn't think of telling CupHead to not write or release it, if that's what he wants to do. I might beg and plead, but that's another story for the hidden adult forum! j/k

Do what YOU want to do. Keep it legal ;)
May 24, 2004, 10:02 PM

Search