• Welcome to Valhalla Legends Archive.
 

[VB] Good Bot Programming Practices?

Started by Tontow, July 08, 2005, 05:23 PM

Previous topic - Next topic

ColT

Quote from: Sorc.Polgara on July 11, 2005, 08:43 PM
Not programming in VB.

(Dunno if someone already said this lol)

I agree!

Tontow

Microsoft may have screwed up,  but.....

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/veendf98/html/defbytedatatype.asp
QuoteByte data type
A data type used to hold positive integer numbers ranging from 0255. Byte variables are stored as single, unsigned 8-bit (1-byte) numbers.

Yet a string is different—(At least by Microsoft's definition):

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/veendf98/html/defstringdatatype.asp
QuoteString data type
A data type consisting of a sequence of contiguous characters that represent the characters themselves rather than their numeric values. A String can include letters, numbers, spaces, and punctuation. The String data type can store fixed-length strings ranging in length from 0 to approximately 63K characters and dynamic strings ranging in length from 0 to approximately 2 billion characters. The dollar sign ($) type-declaration character represents a String in Visual Basic.

And so the question is: Would I be better off a BYTE Array or a String/String Array? - I don't know if vbArray + vbString would be valid because only the BYTE Array type is documented on MSDN.

------------------------------------------------------------------------------------------------

What about:
Quote
PeekData Method

Similar to GetData except PeekData does not remove data from the input queue. This method works only for TCP connections.

Syntax

object.PeekData data, [type,] [maxLen]
???

The Beginning of every header is 0xFF (1 byte).  And then that is followed by the Message ID (1 byte). 
That is then followed by the Packet length which is a WORD (2 bytes. This tells me that I need to grab 4 bytes.

Quote from: rabbit on July 11, 2005, 11:25 AM
Although that may work, it's not recommended (if you have packet fragments, you might combine the end and beginning of two packets). You should read data, get the size from the header, wait for that much more - 4, then send that to the parser. Data after that will be another bundled packet, so just do the same thing.

Wait a sec.  If the objective is to keep from combining the end and beginning of two packets without losing data then wouldn't the following be better?

Keep in mind that:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mswnsk98/html/vbmthgetdatawinsock.asp
QuoteIt's common to use the GetData method with the DataArrival event, which includes the totalBytes argument. If you specify a maxlen that is less than the totalBytes argument, you will get the warning 10040 indicating that the remaining bytes will be lost.

Well, that's no good because I can't retrieve a single packet and remove that packet from the input queue without risking the loss of data, -- (PeekData wouldn't work either because of it doesn't remove the packet from the input queue) ; I think this is why you need to write your own receive buffer. 
And that receive buffer should have the equivalents to—(for ease of use)–: BytesReceived Property, PeekData Method, GetData Method and DataArrival Event. 
All I need from the Winsock buffer is GetData and trash the rest of the Winsock buffer and write my own buffer that lets me
Quote from: Kp on July 09, 2005, 12:22 AM
  • detect when a full message is ready
  • sanity check the message (i.e. not thousands of bytes long)
  • pass the byte stream to a handler
  • update the receive state to reflect that the message is no longer present.
  • goto 1;
with ease.

So I should:

Use my equivalent to object.BytesReceived to check and make shore that you have received the required 4 bytes of the header. – I'm thinking that you only need to go that far since you only need the packet length to get the rest of the packet.

If my equivalent to object.BytesReceived is greater than or equal to 4 then I use my equivalent  to object.PeekData to retrieve the Packet length. 
If my equivalent to object.BytesReceived is less than 4 then I just need to wait until my equivalent to object.BytesReceived is greater than or equal to 4.

Then once my equivalent to object.BytesReceived is greater than or equal to the Packet Length I would use my equivalent to GetData to retrieve that single packet,( and remove that packet from the my input queue without risking the loss of data),  and pass the packet to my data handler.  I should also do a sanity check on the message somewhere along the line as Kp suggested.


(PS: please excuse any grammar or spelling mistakes; it is late and has been a very long day.)

Dyndrilliac

Quote from: Kp on July 11, 2005, 08:22 PM
A correction to make. :)

So - no, BYTE is not defined to unsigned char in C or in C++. In fact, it isn't defined to anything at all! Perhaps you meant to tell him that Microsoft polluted the namespace with the identifier 'BYTE', which is typedef'd to unsigned char? This bit of pollution is in some sense commendable, because they actually got the name correct. Neither WORD nor DWORD are correctly named: WORD is a halfword, and DWORD is a word. Worse, a DWORD64 is actually a doubleword. :)

My apologies Kp. I should have mention I was referring to Win32 systems.
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.

R.a.B.B.i.T

Quote from: Tontow on July 12, 2005, 03:32 AM
The Beginning of every header is 0xFF (1 byte).  And then that is followed by the Message ID (1 byte). 
That is then followed by the Packet length which is a WORD (2 bytes. This tells me that I need to grab 4 bytes.

Quote from: rabbit on July 11, 2005, 11:25 AM
Although that may work, it's not recommended (if you have packet fragments, you might combine the end and beginning of two packets). You should read data, get the size from the header, wait for that much more - 4, then send that to the parser. Data after that will be another bundled packet, so just do the same thing.

Wait a sec.  If the objective is to keep from combining the end and beginning of two packets without losing data then wouldn't the following be better?
You know where a packet starts, so you can get the first header by looking for the first 0xff recieved.  The byte after that is the packet id, and then the next two bytes are the length.  If your current buffer length < 4, you don't have a header.  If it's >= 4, does it == packet length?  If yes, move it to the parser and remove it from the data buffer, and repeat.

Tontow

Quote from: rabbit on July 12, 2005, 05:20 PM

You know where a packet starts, so you can get the first header by looking for the first 0xff recieved.  The byte after that is the packet id, and then the next two bytes are the length.  If your current buffer length < 4, you don't have a header.  If it's >= 4, does it == packet length?  If yes, move it to the parser and remove it from the data buffer, and repeat.

Yes--(Isn't that what I said that I was going to use my equivalent to object.BytesReceived for?  Or at least close to it)--, but what I'm saying is that I can't use Winsock's socket.getdata to retreave a single packet because "If you specify a maxlen that is less than the totalBytes argument, you will get the warning 10040 indicating that the remaining bytes will be lost" ; and if i lose a few bytes form the header of the next packet then I'm screwed......

Kp

Quote from: Dyndrilliac on July 12, 2005, 05:14 AM
Quote from: Kp on July 11, 2005, 08:22 PMSo - no, BYTE is not defined to unsigned char in C or in C++. In fact, it isn't defined to anything at all! Perhaps you meant to tell him that Microsoft polluted the namespace with the identifier 'BYTE', which is typedef'd to unsigned char? This bit of pollution is in some sense commendable, because they actually got the name correct. Neither WORD nor DWORD are correctly named: WORD is a halfword, and DWORD is a word. Worse, a DWORD64 is actually a doubleword. :)
My apologies Kp. I should have mention I was referring to Win32 systems.

So was I.  That was output from a Windows system using MinGW special 20030804-1. :)

Tontow: are you certain that the item you quoted is related to TCP?  It's common for UDP sockets to lose the tail of a message if you recv with too small a buffer, but I've never heard of a TCP implementation that loses data like that.  Apparently I'm classified as a robot, so I cannot access the Microsoft documentation to verify/disprove what you quoted.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

R.a.B.B.i.T

Quote from: Tontow on July 12, 2005, 06:11 PM
Quote from: rabbit on July 12, 2005, 05:20 PM

You know where a packet starts, so you can get the first header by looking for the first 0xff recieved.  The byte after that is the packet id, and then the next two bytes are the length.  If your current buffer length < 4, you don't have a header.  If it's >= 4, does it == packet length?  If yes, move it to the parser and remove it from the data buffer, and repeat.

Yes--(Isn't that what I said that I was going to use my equivalent to object.BytesReceived for?  Or at least close to it)--, but what I'm saying is that I can't use Winsock's socket.getdata to retreave a single packet because "If you specify a maxlen that is less than the totalBytes argument, you will get the warning 10040 indicating that the remaining bytes will be lost" ; and if i lose a few bytes form the header of the next packet then I'm screwed......
You will only lose data if your implementation is wrong :P

Tontow

Quote from: rabbit on July 12, 2005, 11:24 PM
You will only lose data if your implementation is wrong :P
Quote from: Kp on July 12, 2005, 08:27 PM
Tontow: are you certain that the item you quoted is related to TCP?  It's common for UDP sockets to lose the tail of a message if you recv with too small a buffer, but I've never heard of a TCP implementation that loses data like that.  Apparently I'm classified as a robot, so I cannot access the Microsoft documentation to verify/disprove what you quoted.

Ok, here is a quote of the full page (via Ctrl+A, Ctrl+V):

Quote
   MSDN Home >  MSDN Library >  Development Tools and Languages >  Visual Studio 6.0 >  Visual Basic 6.0 >  Reference >   
Visual Basic: Winsock Control

GetData Method (WinSock Control)
See Also    Example    Applies To

Retrieves the current block of data and stores it in a variable of type variant.

Return Value

Void

Syntax

object.GetData data, [type,] [maxLen]

The GetData method syntax has these parts:

Part  Description
object An object expression that evaluates to an object in the Applies To list.
data Where retrieved data will be stored after the method returns successfully. If there is not enough data available for requested type, data will be set to Empty.
type Optional. Type of data to be retrieved, as shown in Settings.
maxLen Optional. Specifies the desired size when receiving a byte array or a string. If this parameter is missing for byte array or string, all available data will be retrieved. If provided for data types other than byte array and string, this parameter is ignored.


Settings

The settings for type are:

Description Constant
Byte vbByte
Integer vbInteger
Long vbLong
Single vbSingle
Double vbDouble
Currency vbCurrency
Date vbDate
Boolean vbBoolean
SCODE vbError
String vbString
Byte Array vbArray + vbByte


Remarks

It's common to use the GetData method with the DataArrival event, which includes the totalBytes argument. If you specify a maxlen that is less than the totalBytes argument, you will get the warning 10040 indicating that the remaining bytes will be lost.


Manage Your Profile |Legal |Contact Us |MSDN Flash Newsletter
© 2005 Microsoft Corporation. All rights reserved. Terms of Use |Trademarks |Privacy Statement 
 


Dyndrilliac

Why not create a secondary buffer for the data to be lost? Place it in there and access it when you need it.
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.

Tontow

#24
Quote from: Dyndrilliac on July 13, 2005, 07:34 AM
Why not create a secondary buffer for the data to be lost? Place it in there and access it when you need it.

Please take the time to read reply #16 carfully.........

Kp

Tontow: based on all the things you've posted, I don't see the problem.  If you specify a max length argument, then no more than that can be returned.  So why specify the max length?  Leave it blank and let the system return as much data as it can!
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Tontow

But wouldn't it be better/faster if I eliminate the need for a secondary buffer?  Why double buff when you can avoid it?

TheMinistered

Well, first and foremost I always like to throw a little code out here and there:


    'string
    Dim strData As String
    wsSocket.GetData strData, vbString, bytesTotal

    'byte array
    Dim bytData() As Byte
    wsSocket.GetData bytData, vbArray, bytesTotal


The obvious improvement would be memory usage.  A byte array to hold the data is going to be twice as effecient when it comes to storage.

As for speed and other reasons why?  You figure that out? :P

Kp

Quote from: Tontow on July 14, 2005, 11:03 PMBut wouldn't it be better/faster if I eliminate the need for a secondary buffer?  Why double buff when you can avoid it?

I find it absolutely hilarious that someone determined to do this in VB cares about speed.  VB is meant to be written quickly and run slowly.  If you care about performance, use a real language.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Warrior

Nothing wrong with using vb to the max while you're programming in it ;)
Quote from: effect on March 09, 2006, 11:52 PM
Islam is a steaming pile of fucking dog shit. Everything about it is flawed, anybody who believes in it is a terrorist, if you disagree with me, then im sorry your wrong.

Quote from: Rule on May 07, 2006, 01:30 PM
Why don't you stop being American and start acting like a decent human?

|