• Welcome to Valhalla Legends Archive.
 

VB8 - Packet Buffer (annoying you yet?)

Started by Joe[x86], June 28, 2006, 10:57 PM

Previous topic - Next topic

Joe[x86]

Alright. I make an array list and add stuff to it. When it comes time, I make an array list, add sanity, add the ID, add the length, and add the other array list. Then I want to cast it to a byte array but noooo, VB wants to make it an Object array. When I try casting each Object to a byte, it yells at me. Obviously someone has figured it out but I've failed to find ANY way to do it, so if you'd enlighten me, it'd be appreciated.

Public Class clsPacketBuffer

    Private myBuffer As New ArrayList()

    Public Sub add_uint8(ByVal uint8 As Byte)
        myBuffer.Add(uint8)
    End Sub

    Private Sub add_uint8array(ByVal uint8() As Byte)
        Dim b As Byte
        For Each b In uint8
            add_uint8(b)
        Next
    End Sub

    Public Sub add_uint16(ByVal uint16 As Short)
        add_uint8array(BitConverter.GetBytes(uint16))
    End Sub

    Public Sub add_uint32(ByVal uint32 As Integer)
        add_uint8array(BitConverter.GetBytes(uint32))
    End Sub

    Public Sub add_cstring(ByVal cstring As String)
        myBuffer.Add(cstring)
        add_uint8(0)
    End Sub

    Public Sub add_pstring(ByVal pstring As String)
        add_uint8(CType(Len(pstring), Byte))
        myBuffer.Add(pstring)
    End Sub

    Public Sub add_void(ByVal void As String)
        myBuffer.Add(void)
    End Sub

    Public Function GetPacket(ByVal PacketID As Byte) As Byte()
        Dim Packet As New ArrayList
        Packet.Add(CType(&HFF, Byte))
        Packet.Add(CType(PacketID, Byte))
        Packet.Add(CType(myBuffer.Count + 4, Short))
        Packet.Add(myBuffer)
        modFunctions.AddChat(Color.Blue, "[DEBUG] " + BitConverter.ToString(ObjectArrayToByteArray(Packet.ToArray)))
        GetPacket = ObjectArrayToByteArray(Packet.ToArray)
        myBuffer.Clear()
    End Function

    Private Function ObjectArrayToByteArray(ByVal O As Object()) As Byte()
        Dim B(0 To UBound(O)) As Byte, I As Integer
        For I = LBound(O) To UBound(O)
            B(I) = CType(O(I), Byte)
        Next I
        ObjectArrayToByteArray = B
    End Function

End Class
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

MyndFyre

QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

K

Since you're using VB Express, which should be .NET 2.0, you might want to just go ahead and use a List<byte>, or whatever the stupid VB notation is, like List Of Type Byte or whatever.

MyndFyre

Eww!  List<byte> is SO much more memory-intensive than a MemoryStream (System.IO in mscorlib). 
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Joe[x86]

I've already (kind of) ported MyndFyre's DataBuffer as well as the GetData from BnetPacket(?).

Imports System
Imports System.IO
Imports System.Text
Imports System.Runtime.InteropServices

Public Class PacketBuffer
    Private m_ms As MemoryStream = New MemoryStream
    Private m_len As Integer = 0

    Public Sub Insert_BOOL(ByVal b As Boolean)
        If b Then
            Insert_DWORD(1)
        Else
            Insert_DWORD(0)
        End If
    End Sub

    Public Sub Insert_BYTE(ByVal b As Byte)
        m_ms.WriteByte(b)
        m_len += 1
    End Sub

    Public Sub Insert_WORD(ByVal w As UShort)
        m_ms.Write(BitConverter.GetBytes(w), 0, 2)
        m_len += 2
    End Sub

    Public Sub Insert_DWORD(ByVal d As UInteger)
        m_ms.Write(BitConverter.GetBytes(d), 0, 4)
        m_len += 4
    End Sub

    Public Sub Insert_QWORD(ByVal q As ULong)
        m_ms.Write(BitConverter.GetBytes(q), 0, 8)
        m_len += 8
    End Sub

    Public Sub Insert_CSTR(ByVal s As String)
        Dim B As Byte
        For Each B In Encoding.ASCII.GetBytes(s)
            Insert_BYTE(B)
        Next
        Insert_BYTE(0)
    End Sub

    Public Sub Insert_PSTR(ByVal s As String)
        If s.Length < 256 Then
            Insert_BYTE(s.Length & &HFF)
            Dim B As Byte
            For Each B In Encoding.ASCII.GetBytes(s)
                Insert_BYTE(B)
            Next
        End If
    End Sub

    Public Sub Insert_PWSTR(ByVal s As String)
        If s.Length < 65536 Then
            Insert_WORD(s.Length & &HFFFFFF)
            Dim B As Byte
            For Each B In Encoding.ASCII.GetBytes(s)
                Insert_BYTE(B)
            Next
        End If
    End Sub

    Public Sub Insert_VOID(ByVal v As String)
        Dim B As Byte
        For Each B In Encoding.ASCII.GetBytes(v)
            Insert_BYTE(B)
        Next
    End Sub

    Public Function GetData(ByVal PacketID As Byte) As Byte()
        Dim baseData() As Byte = GetData()
        Dim ret(Count + 3) As Byte
        ret(0) = &HFF
        ret(1) = PacketID
        Dim len() As Byte = BitConverter.GetBytes(CType((Count + 4 & &HFFFF), UShort))
        ret(2) = len(0)
        ret(3) = len(1)
        Buffer.BlockCopy(baseData, 0, ret, 4, baseData.Length)
        Return ret
    End Function

    Public Function GetData() As Byte()
        Dim ret(m_len) As Byte
        Buffer.BlockCopy(m_ms.GetBuffer(), 0, ret, 0, m_len)
        Return ret
    End Function

    Public ReadOnly Property Count() As Integer
        Get
            Return m_len
        End Get
    End Property

End Class
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

Dyndrilliac

#5
Edit: I feel kind of stupid. Nevermind. I realize now I had a "::" operator where a "->" operator should have been.

I'm converting the above code to C++.NET, and I'm having a bit of trouble with the Insert_CSTR method. I'm using the following namespaces:using namespace System;
using namespace System::Data;
using namespace System::IO;
using namespace System::Text;
using namespace System::Runtime::InteropServices;
Here's my code:Void __inline Insert_CSTR(String^ cstring) {
array<Byte>^ByteArray = Encoding::ASCII->GetBytes(cstring);
for (UInt16 i = 0; i < ByteArray->GetLength(); i++) {
Insert_BYTE(ByteArray[i]);
}
Insert_BYTE(0);
}
Here's the error:f:\backup\public\source code\c++.net\personal projects\dyslexicchat v2\clsPacketBuffer.h(59) : error C2039: 'GetBytes' : is not a member of 'System::Text::Encoding::ASCII'
        f:\backup\public\source code\c++.net\personal projects\dyslexicchat v2\clsPacketBuffer.h(59) : see declaration of 'System::Text::Encoding::ASCII'
f:\backup\public\source code\c++.net\personal projects\dyslexicchat v2\clsPacketBuffer.h(59) : error C3861: 'GetBytes': identifier not found
I'm wondering where the GetBytes() method that the code shows is located; I'm using the .NET Framework v2.0.
Quote from: Edsger W. DijkstraIt is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.

TheMinistered

#6
Uhm, the very first thing I wanted to point out is that you use 'AddVoid'.  The identifier void is associated with no data type.  I guess you could coin it as a string datatype, but that totally defies the definition of VOID.  If you wanted to associate any data type in .NET with void it would have to be OBJECT (my best guess).  Although, I personally wouldn't associate any data type in vb with void.

Then you implement CString and other weird STRING formats.  I don't see the neccesity of this.  You should stick with one string format, if possible, and comply to it through out your whole project -- otherwise things get real confusing and messy.  just a tip

MyndFyre

Quote from: TheMinistered on September 22, 2006, 01:29 PM
Uhm, the very first thing I wanted to point out is that you use 'AddVoid'.  The identifier void is associated with no data type.  I guess you could coin it as a string datatype, but that totally defies the definition of VOID.  If you wanted to associate any data type in .NET with void it would have to be OBJECT (my best guess).  Although, I personally wouldn't associate any data type in vb with void.

Then you implement CString and other weird STRING formats.  I don't see the neccesity of this.  You should stick with one string format, if possible, and comply to it through out your whole project -- otherwise things get real confusing and messy.  just a tip

I implemented the InsertCString, InsertPascalString, and InsertWidePascalString methods in a generalized packet buffer that I used in a networking project in the past.  They're the three most common string formats, and when you include overloads to specify Encoding instances, they become incredibly flexible.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.