Valhalla Legends Archive

Programming => Battle.net Bot Development => Topic started by: Sorc.Polgara on August 18, 2004, 07:39 PM

Title: I made my first class today
Post by: Sorc.Polgara on August 18, 2004, 07:39 PM
I made my first class today!

I decided to make a class that kind of did the opposite of DarkMinion's PacketBuffer class which creates a buffer and sends it.

I made a class to help me take/extract parts (BYTE, DWORD, WORD etc.) out of a packet.

I didn't quite know what to call it, but I figured that since DarkMinion's packet buffer class is name "PacketBuffer".  I named my class "PacketDebuffer".  Sounds stupid and stuff but that is what I called it.

Here it is:

'===============================
'PacketDebuffer Class
'By Bethra, aka. Sorc.Polgara =)
'===============================

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal numBytes As Long)

Private Debuffer As String      '// Debuffering string

'Sets the Debuffer string
Public Function DebuffPacket(PacketData As String)
   Debuffer = PacketData
End Function

'Resets/clears the Debuffer
Public Function Clear()
   Debuffer = vbNullString
End Function

'=======================================================
'Public Functions that debuffer a part from the Debuffer
'=======================================================

'Debuffers a DWORD from the Debuffer
Public Function DebuffDWORD()
   Dim DWORD As String * 4
   DWORD = GetDWORD
   RemoveDWORD
   DebuffDWORD = DWORD
End Function

'Debuffers a WORD from the Debuffer
Public Function DebuffWORD()
   Dim WORD As String * 2
   WORD = GetWORD
   RemoveWORD
   DebuffWORD = WORD
End Function

'Debuffers a BYTE from the Debuffer
Public Function DebuffBYTE()
   Dim PBYTE As String
   PBYTE = GetBYTE
   RemoveBYTE
   DebuffBYTE = PBYTE
End Function

'Debuffers a FILETIME from the Debuffer
Public Function DebuffFILETIME()
   Dim FILETIME As String * 8
   FILETIME = GetFILETIME
   RemoveFILETIME
   DebuffFILETIME = FILETIME
End Function

'Debuffers a null-terminating string from the Debuffer
Public Function DebuffNTString()
   Dim NTString As String
   NTString = GetNTString
   RemoveNTString
   DebuffNTString = NTString
End Function

'=====================================================
'Public Functions that remove a part from the Debuffer
'=====================================================

'Removes a BYTE from the Debuffer
Public Function RemoveBYTE()
   Debuffer = Mid(Debuffer, 2)
End Function

'Removes a WORD from the Debuffer
Public Function RemoveWORD()
   Debuffer = Mid(Debuffer, 3)
End Function

'Removes a DWORD from the Debuffer
Public Function RemoveDWORD()
   Debuffer = Mid(Debuffer, 5)
End Function

'Removes a FILETIME structure from the Debuffer
Public Function RemoveFILETIME()
   Debuffer = Mid(Debuffer, 9)
End Function

'Removes a null-terminating string from the Debuffer
Public Function RemoveNTString()
   Dim Pos As Integer
   Pos = InStr(1, Debuffer, Chr(0), vbBinaryCompare)
   Debuffer = Mid(Debuffer, Pos + 1)
End Function

'=======================================================
'Functions that get parts from the front of the Debuffer
'=======================================================

'Gets a BYTE from the Debuffer
Function GetBYTE() As String
   Dim PBYTE As String
   PBYTE = Mid(Debuffer, 1, 1)
   GetBYTE = PBYTE
End Function

'Gets a WORD from the Debuffer
Function GetWORD() As String
   Dim WORD As String * 2
   CopyMemory WORD, Debuffer, 2
   GetWORD = WORD
End Function

'Gets a DWORD from the Debuffer
Function GetDWORD() As String
   Dim DWORD As String * 4
   CopyMemory DWORD, Debuffer, 4
   GetDWORD = DWORD
End Function

'Gets a FILETIME from the Debuffer
Function GetFILETIME() As String
   Dim FILETIME As String * 8
   CopyMemory FILETIME, Debuffer, 8
   GetFILETIME = FILETIME
End Function

'Gets a null-terminating string from the Debuffer
Function GetNTString() As String
   Dim NTString As String
   Dim Pos As Integer
   Pos = InStr(1, Debuffer, Chr(0), vbBinaryCompare)
   NTString = Mid(Debuffer, 1, Pos)
   GetNTString = NTString
End Function


'=====================Credits============================
'DarkMinion for using his PacketBuffer class as a guide,
'this is the first class I have ever made =)
'-----------------
'Bot Developement Forum members who helped me understand
'some stuff that I need to know inorder to make this =)
'=======================================================


Here is an example of usage:

   Dim PArray(0 To 6) As String
   Dim PDebuf As PacketDebuffer
   Set PDebuf = New PacketDebuffer
   
   With PDebuf
       .DebuffPacket sIn
       PArray(0) = .DebuffDWORD
       PArray(1) = .DebuffDWORD
       PArray(2) = .DebuffDWORD
       PArray(3) = .DebuffDWORD
       PArray(4) = .DebuffFILETIME
       PArray(5) = .DebuffNTString
       PArray(6) = .DebuffNTString
   End With
   
   For i = 0 To 6
       lstDebug2.AddItem DebugOutput(PArray(i))
   Next

This takes SID_AUTH_INFO packet that is returned by the server and stores the parts in an array.

I like to use comments so I put alot of comments in my code.
I also put some information about it in the class module itself.

I wanted to post this and try to see if I can get some constructive critism and/or advice on my class.  Since it is my first class it is probably very n00bish so please no flames or bashing =\.  Thanks
Title: Re:I made my first class today
Post by: UserLoser. on August 18, 2004, 07:41 PM
Quote
Gets a non-terminating string from the Debuffer

The term NTString has been accepted as Null-terminated string, atleast, for many others and I.  The FILETIME struct isn't a string either, should make it appropriately copy the right values into the struct :)
Title: Re:I made my first class today
Post by: MyndFyre on August 18, 2004, 08:31 PM
Outstanding!  Great for you, insert-non-gender-specific-pronoun-as-pointed-out-to-me-by-Zakath!

For those of you who find yourself having trouble frequently, or come here for help all the time, this is something that you can learn from.

Now, Chr0nic is doing pretty well nowadays, but I'm still going to use him as an example.

A while back, he was having trouble parsing the packet that has your binary friends list.  I was trying to talk him through it, but I wasn't very sure of myself with respect to Visual Basic (I'm still not really), and I really couldn't relate, because I had set up a similar class in C# (http://forum.valhallalegends.com/phpbbs/index.php?board=17;action=display;threadid=5042;start=msg42358#msg42358) to the one that this guy had made.  It acted like a stream, automatically advancing when I'd read data.

This class should *REALLY REALLY* help you guys who are constantly fiddling with bizarre Mid$() functions and variables.  I would recommend testing it, and then posting it on BotDev Reference.
Title: Re:I made my first class today
Post by: Sorc.Polgara on August 18, 2004, 08:58 PM
Quote from: UserLoser. on August 18, 2004, 07:41 PM
Quote
Gets a non-terminating string from the Debuffer

The term NTString has been accepted as Null-terminated string, atleast, for many others and I.  The FILETIME struct isn't a string either, should make it appropriately copy the right values into the struct :)

Heh, yeah that is what I meant by "non-terminating".  Just mispelled it :D

Yeah, ok, changing the FILETIME thing should be easy enough.  Fix it tomarrow, sleepy
Title: Re:I made my first class today
Post by: Zakath on August 18, 2004, 11:25 PM
Quote from: MyndFyre on August 18, 2004, 08:31 PM
Outstanding!  Great for you, man!

Polgara is a girl's name (comes from the same source as my own). So, unless it's a guy using it for some wierd reason, saying "man" is probably not quite right. :P
Title: Re:I made my first class today
Post by: Sorc.Polgara on August 19, 2004, 08:43 AM
@Zakath
I'm a male w/ a female SC...umm I'm straight.  Yeah Eddings series is the first fantasy series I've read (other than LotR).


Concerning the microsoft FILETIME Structure, its total size is 8-bytes (64-bits).  The structure, dwLowDateTime and dwHighDateTime each are 4-bytes (DWORD).  here is the MSDN description link

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/filetime_str.asp

Now what I basically have in my code is just extracting a 8-byte string, meaning it takes both DWORDs out as one.

What do you suggest that I do instead?

I mean, it takes out the whole FILETIME DWORD[2].  Shouldn't that be enough?

Or when I extract the FILETIME, should I take each individual DWORD separately?

I haven't really looked into this yet, but what would the best way extracting this FILETIME structure?  Using the TYPE keyword?
Title: Re:I made my first class today
Post by: Arta on August 19, 2004, 09:36 AM
I'd use copymemory for them all. Treating everything as strings is yucky... Then again, I'm not sure if VB makes that any nicer :)
Title: Re:I made my first class today
Post by: Zakath on August 19, 2004, 06:27 PM
Yes, VB is just icky for that sort of thing. In C++ all you have to do is offset a pointer and use a typecast. :)
Title: Re:I made my first class today
Post by: Eli_1 on August 19, 2004, 07:36 PM
Quote from: Zakath on August 19, 2004, 06:27 PM
In C++ all you have to do is offset a pointer . . .

Can you show me an example of how you would do that?

00 00 00 00  01 01 01 01  02 02 02 02

The only way I know how to parse the values from this would be with strncpy() and pointer arithmetic.


Title: Re:I made my first class today
Post by: Kp on August 19, 2004, 11:48 PM
Quote from: Eli_1 on August 19, 2004, 07:36 PMCan you show me an example of how you would do that?
00 00 00 00  01 01 01 01  02 02 02 02
The only way I know how to parse the values from this would be with strncpy() and pointer arithmetic.

Do what, exactly?  Your question isn't clear, and there's not enough quoted material to indicate what you want either.
Title: Re:I made my first class today
Post by: K on August 20, 2004, 11:39 AM
Quote from: Eli_1 on August 19, 2004, 07:36 PM
Quote from: Zakath on August 19, 2004, 06:27 PM
In C++ all you have to do is offset a pointer . . .

Can you show me an example of how you would do that?

00 00 00 00  01 01 01 01  02 02 02 02

The only way I know how to parse the values from this would be with strncpy() and pointer arithmetic.


class Packet
{
protected:
   BYTE* _buffer;
   BYTE* _cur;
public:
   Packet()
   {
      // initialize _buffer,
      // _cur points to _buffer
   }
   // where
   // _cur is a byte pointer to the current location we want to read from
   // note that this clever templated code will not work for
   // types like strings, etc.
   template <typename _T> _T Read()
   {
      // interpret the byte* to the current location
      // as a pointer to a _T type
      _T* val = reinterpret_cast<_T*>(_cur);
      // increment the _cur pointer by the size of a _T in bytes
      _cur += sizeof(_T);
      // dereference and return val
      return *val;
   }
};

// .... you need to put data into _buffer (12 bytes, at least)
Packet p;
int i = p.Read<int>();
cout << hex << i << endl;
__int64 i64 = p.Read<__int64>();
cout << hex << i64 << endl;
Title: Re:I made my first class today
Post by: tA-Kane on August 20, 2004, 09:34 PM
Long ago (close to a year and a half ago), I made a BinaryBuffer class for REALbasic. It's got both reading and writing functions. It's cool.

I made it after I wrote most of my packet parser, so I never really gave it much use except in file usage.

I should redo my sockets to use it though. It would be a lot cleaner, codewise.

I wish REALbasic could directly typecast one object into another without creating stupid "IllegalCast" exceptions. I know what the fuck I'm doing. The objects have essentially the same data. Damnit. So C rocks in that way.

But if REALbasic could directly typecast, I'd typecast the data into a BnetPacket object, then if it turns out to be an event, typecast that data (minus the packet header) into a BnetEvent object. It would be so much easier than having to create a new object three or even four times, and copying the data just as many times.

Really lame.

In my spare time, I'll be moving code to C. It'll be a lot better.

What about VB? Can VB typecast?

...
Back to my origional thoughts: why create a separate class? Just modify DM's PacketBuffer to have reading functions as well as writing functions. Then you could write a string and read as a DWORD, or vice versa.  ;)
Title: Re:I made my first class today
Post by: shadypalm88 on August 20, 2004, 09:51 PM
Quote from: tA-Kane on August 20, 2004, 09:34 PMWhat about VB? Can VB typecast?
I don't think so.  You can use the RtlMoveMemory (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/memory/base/movememory.asp) to copy memory from a var of one type to one of a different type, but there's no direct corollary.