• Welcome to Valhalla Legends Archive.
 

A question about the Warcraft III Clan System

Started by Arthas, September 29, 2003, 11:15 PM

Previous topic - Next topic

Banana fanna fo fanna


Arthas

Race condition? BTW, DebugOutput didnt do anything for me

UserLoser

Quote from: Arthas on October 04, 2003, 11:49 PM
Race condition? BTW, DebugOutput didnt do anything for me

If you just put that on your DataArrival/Recieve, you won't need a packet logger, and you'll see all incoming data to your bot

Adron

If it's that function grok or someone posted, you'll have to print it too. It's really just bin2hexdump.

Arthas

I fixed it, I found out wtf was going on.....................

Thanks for the help all, but I once again, am full of questions!

BNet splits a packet in 2 if it is to big, eg, a clan packet. How do I merge the two together?


Arthas

Still, I'm stumped as to WHY I'd have to pause my entire program for the packets to merge by themselves... o_O

Zakath

When a Windows socket receives data, it's placed into an internal buffer. When you (or the built-in Winsock controller VB uses) issue a recv call on the socket, whatever data is there is copied into the buffer you supply (so you can manipulate it). If you always call recv the instant new data arrives, you'll always receive packets that get cut into pieces as they are: in pieces. By sleeping, I would guess you're causing your program to wait long enough before issuing the recv that both halves of the packet are received and buffered internally, so then the subsequent call can grab the whole packet at once.

However, you generally do want to issue recv as soon as data is received, so...you need to add support for constructing packets when they get split in pieces. :)
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

Arthas

#38
Call me a newb, but this works quite well...

In my Data Arrival function:

       lngLen = Val("&H" & StrToHex(StrReverse(Mid(strBuffer, 3, 2))))
       If Not Mid(StrToHex(strBuffer), 1, 2) = "FF" Then
           strBuffer = p1 + strBuffer
           p1 = ""
           Parse (Left(strBuffer, lngLen))
       End If
       
       If Len(strBuffer) < lngLen Then
           p1 = strBuffer
           Exit Sub
       End If


It just waits until I recieve the last parts of the packet, then constructs them, think that should do the trick for everything I'll encounter regarding Bnet?

Arta

No. I'm not a VB programmer but if I understand your post properly, it's demonstrating a fundamental lack of understanding about data, how it's stored, represented and used - you should read up on it. For example, the first line looks like it's taking the (numeric) length field of a packet, converting it into a string, concatenating it with "&H", and converting it back into a number - that's silly. Perhaps you're suffering from a common misconception: data is not sent as 'hex'. Data is just that - data - a bunch of bytes. Hex (Or more rightly, hexadecimal) is just a way of formatting that data to make it easier to read. Converting a length field - or any other numeric field - to it's hex representation and then back to a number is silly because the data is already a number to begin with.

Checking to see if the first byte of the buffer is FF is a good idea, and something that most people do, but your code here doesn't look very robust. What happens when new data arrives if the buffer contains a half-packet? Is it put onto the end of the buffer? If so, where are you storing the length of the buffer? How are you updating the buffer after you process a packet so that the packet you dealt with is removed properly? What happens when you get two packets in one go? Will it process the first one and then ignore the second? Without seeing the rest of your code I can't tell but there are probably quite a few improvements you could make.


HTH.

Arthas

#40
How do I get bytes from a string?

EG: ÿh to bytes

I always dealt with my common misconception as fact for my bot, though now this should help me much if you could tell me...

Arta

They're bytes already. AFAIK, you can just use Mid() to extract a string. I don't know about numbers - As I said, I'm not a VB programmer. If no one who is feels like replying on this thread, I'd suggest finding an open source packet buffer (I think BotDev has one). You should be able to read through the source and figure out what functions like GetDWORD() (or equivalent) do. Incidentally, it's a great deal easier, in my experience, to use a packet class that provides easy methods for retrieving data from packets. It simplifies your packet processing functions and makes your code much more readable.

If you find something in there you can't make sense of, post it here and I'll do my best to help.

Soul Taker

I use CopyMemory to change such things to a long (check MSDN).

Adron

Quote from: Arta[vL] on October 06, 2003, 06:52 AM
They're bytes already. AFAIK, you can just use Mid() to extract a string. I don't know about numbers - As I said, I'm not a VB programmer. If no one who is feels like replying on this thread, I'd suggest finding an open source packet buffer (I think BotDev has one). You should be able to read through the source and figure out what functions like GetDWORD() (or equivalent) do. Incidentally, it's a great deal easier, in my experience, to use a packet class that provides easy methods for retrieving data from packets. It simplifies your packet processing functions and makes your code much more readable.

If you find something in there you can't make sense of, post it here and I'll do my best to help.


Typically, the GetDWORD function will do pretty much what he did. Could also turn his


lngLen = Val("&H" & StrToHex(StrReverse(Mid(strBuffer, 3, 2))))


into


lngLen = Asc(Mid(strBuffer, 3, 1)) + Asc(Mid(strBuffer, 4, 1)) * 256


Banana fanna fo fanna

Let me explain in pseudo:

Define two procedures:
on_data: called when raw data is received. This procedure should store it in a global/instance buffer. Basically, just append the data on the end of it. Then, call dispatch_message.

dispatch_message: this procedure is responsible for dispatching packets to their appropriate handler method. You should follow this algorithm:

1. If length of buffer is less than 4, return
2. If buffer doesn't start with 0xff, throw error
3. If we've made it to here, it looks like a complete battle.net packet header. Grab the 2nd byte in the buffer. We'll call it cmd
4. Convert the 3rd and 4th bytes in the buffer to a little-endian dword (n).
5. If length of buffer is less than n, return, we didn't get a full packet.
6. Otherwise, take the first n bytes from the front of the buffer (msg) and remove them from the buffer.
7. Using a select case/switch/cond/etc logic structure, decide what procedure should handle data for packet type cmd.
8. Pass msg to cmd
9. Go back to step one. You can use a goto, loop, or recursive call. Recursive call is easiest but does have a very very slight risk of a call stack overflow if someone spams the hell out of you

This could be optimized by saving the length of the buffer in a variable so we don't have to count it each time. Could also cache the 3rd and 4th byte dword.

I hope you enjoyed today's algorithm. Stay tuned.

Wait a minute, you probably didn't even read this post. Why did I even bother typing it?

|