• Welcome to Valhalla Legends Archive.
 

Optimal BNLS procedure?

Started by Don Cullen, February 04, 2007, 12:42 PM

Previous topic - Next topic

Don Cullen

I used to use local hashing for my bot, until Blizzard implemented lockdown.

So now I'm switching to BNLS. What's the most optimal procedure? I did a search on the forums, and so far the most optimal one I found was by Hdx:

BNCS C->S Protocol Byte: 0x01
BNCS C->S 0x50
BNCS S->C 0x50
If Client.protocol == NLS
  BNLS C->S 0x0D
  BNLS S->C 0x0D
End If
BNCS S->C 0x25
BNCS C->S 0x25
BNLS C->S 0x1A
BNLS S->C 0x1A
BNLS C->S 0x0C
BNLS C->S 0x51
If Client.protocol != NLS
  BNLS C->S 0x0B
  BNLS S->C 0x0B
  BNCS C->S 0x3A
  BNCS S->C 0x3A
Else
  BNLS C->S 0x02
  BNLS S->C 0x02
  BNCS C->S 0x53
  BNCS S->C 0x53
  BNLS C->S 0x03
  BNLS S->C 0x03
  BNCS C->S 0x53
  BNCS S->C 0x53
  BNCS S->C 0x45
End If
If Client.UDPGames == True
  BNCS C->S UDP 0x09
  BNCS S->C UDP 0x09
  BNCS C->S 0x14
End If
BNCS C->S 0x0A
BNCS C->S 0x0B
BNCS C->S 0x0C


What do you think? Is that the most optimal way to go? I apologize for being new to using BNLS. Thanks in advance for any assistance/tips given.
Regards,
Don
-------

Don't wonder why people suddenly are hostile when you treat them the way they shouldn't be- it's called 'Mutual Respect'.

warz

you are not allowed to be new at anything.

Hdx

For use with BNLS, that is a good method to take.
Which is why I posted it.
Now take note: Thats for games that actually use the SID_AUTH system. For the legacy client's you have to do a little more work.
~Hdx

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Skywing

BNLS_CHOOSENLSREVISION is obsolete.  You should implement a client-side cache and retry system based on the data given to you in BNLS_VERSIONCHECKEX2.

Hdx

Seince when is ChooseNLSRevision Obsolete?
As far sI hae seen, it still defaults to NLSv1 if its no sent.
And notice how I didnt put REQUESTVERSIONBYE in there.
~~(HDX)~-~

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Don Cullen

#5
In my experimenting with BNLS, it seems to be failing. I've been mainly just focusing on getting the bot to partially use BNLS to see if I can get the bot to work, and if it's successful, I'll rewrite the entire connection code so the bot uses BNLS.

The way my bot works is:

Send 0x01  (Protocol byte)
Send 0x50  (SID_AUTH_INFO)
Recieve 0x50  (SID_AUTH_INFO)

At this point, BNET returns an error saying invalid game version. So I figured it was because of the verbyte, in which case my bot does this:

BNLS.Connect "bnls.valhallalegends.com", "9367"

Then when BNLS accepts the connection, this sub fires:

Private Sub BNLS_Connect()
    'BNLS_REQUESTVERSIONBYTE (0x10)
    If DebugDisplay = True Then AddC "Sending BNLS_REQUESTVERSIONBYTE (0x10)..."
    With PB
        .Clear
        .InsertDWORD PRODUCT_BROODWAR&
        .SendPacket DMBot.BNET, &H10
        .Clear
    End With
    If DebugDisplay = True Then AddC "BNLS_REQUESTVERSIONBYTE (0x10) packet sent."
    DoEvents
End Sub


Half-assed code, I know. Then sole intention was to mainly to get the bot working albeit in a half-assed way. Once I was sure it worked, I was going to overhaul the entire connection method to BNLS and eliminate hashing.

The code used to process incoming data from BNLS is:

Private Sub BNLS_DataArrival(ByVal bytesTotal As Long)
    Static PktBuff As String 'Packet Buffer
    Dim Incoming As String
    BNLS.GetData Incoming, vbString, bytesTotal
    PktBuff = PktBuff & Incoming
    Dim Pkt As BNCSPKT
    While Len(PktBuff) > 3
        Pkt.intPktLen = GetWord(Mid$(PktBuff, 3, 2))
        If Len(PktBuff) < Pkt.intPktLen Then Exit Sub
        ParseBNLSPacket (Left(PktBuff, Pkt.intPktLen))
        PktBuff = Mid(PktBuff, Pkt.intPktLen + 1)
    Wend
End Sub


And the ParseBNLSPacket sub:

Public Sub ParseBNLSPacket(ByVal PacketData As String)
    Dim PacketID As Byte
    'PacketID = Asc(Mid(PacketData, 2, 1))
    PktDeBuf.SetData (PacketData)
    PacketID = PktDeBuf.StripHeader
    Select Case PacketID
        Case &H10   'BNLS_REQUESTVERSIONBYTE
            If DebugDisplay = True Then AddC "BNLS: Here's the new version byte."
            Dim Trash As Long
            Trash = PktDeBuf.rDWORD 'Product ID
            VerByte = PktDeBuf.rDWORD
            frmOptions.WriteConfig  'Update config.ini with new VerByte
            If DebugDisplay = True Then AddC "DMBot: Thanks!"
            'Now retry the bnet connection
            Call DMBot.BNET.Connect(BNETServer, BNETPort)
        Case Else
            AddC "Unrecognized Packet ID: 0x" & IIf(Len(Hex(PacketID)) = 1, "0" & Hex(PacketID), Hex(PacketID)) & " (" & GetPacketName(PacketID) & ")"
            DumpPacket (PacketData)
    End Select
    PktDeBuf.ClearData
End Sub


This entire connection method makes use of DarkMinion's PacketBuffer class.

Now, the problem here is; I'm not getting a response from BNLS. I'm sure I just did something stupid and missed something of paramount importance -- is anyone willing to enlighten me?
Regards,
Don
-------

Don't wonder why people suddenly are hostile when you treat them the way they shouldn't be- it's called 'Mutual Respect'.

Barabajagal

DMBot.BNET ? maybe use DMBot.BNLS ?

Don Cullen

#7
D'oh.

[edit]

Thanks for pointing that out, replaced that part. Still no response:

Quote[4:47:49 PM]    DMBot activated.
[4:47:49 PM]    Config.ini loaded.
[4:47:49 PM]    Ready.
[4:47:54 PM]    Debugging enabled.
[4:47:54 PM]    You're not connected to BNET!
[4:48:00 PM]    Connecting to port 6112 at the uswest.battle.net server...
[4:48:00 PM]    Connected!
[4:48:00 PM]    Initating packetage...
[4:48:00 PM]    Notifying server of emulation...
[4:48:00 PM]    0x01 protocol packet sent.
[4:48:00 PM]    Server notification done.
[4:48:00 PM]    Assembling 0x50 Protocol packet...
[4:48:00 PM]    0x50 SID_AUTH_INFO packet sent.
[4:48:00 PM]    BNET: Ping?
[4:48:00 PM]    Assembling 0x25 SID_PING Packet...
[4:48:00 PM]    0x25 SID_PING packet sent.
[4:48:00 PM]    DMBot: Pong!
[4:48:00 PM]    BNET: Gimme your cdkey.
[4:48:00 PM]    Assembling 0x51 SID_AUTH_CHECK Packet...
[4:48:00 PM]    0x51 SID_AUTH_CHECK packet sent.
[4:48:00 PM]    DMBot: Blah blah. There ya go. Happy?
[4:48:00 PM]    BNET: Well...
[4:48:00 PM]    BNET: Nope. Invalid game version. Bye.
[4:48:00 PM]    Server aborted connection!
[4:48:00 PM]    Sending BNLS_REQUESTVERSIONBYTE (0x10)...
[4:48:00 PM]    BNLS_REQUESTVERSIONBYTE (0x10) packet sent.

Hrmmm... I'm going to do some more research, see what I'm doing wrong or what needs to be updated.

[edit]

I just read up on the 0x51 packet (C->S) at BNetDocs and from IIRC, the lockdown affected the 0x51 since it no longer uses the files for hashing. I'm going to read up on the BNLS specs and see if there's an alternative to local hashing.

For now, any idea why BNLS isn't responding? Is there an appropriate connection procedure I have to perform prior to making any requests from BNLS?

[edit]

Yes, I know. Alot of edits. Anyway, I'm such an idiot. I just realized that the VerByte hasn't changed -- and that the game version has absolutely nothing to do with the VerByte (if the problem was the VerByte, bnet'd have said so IE (game needs to be upgraded, or invalid verbyte). Sooo.... Back to researching.
Regards,
Don
-------

Don't wonder why people suddenly are hostile when you treat them the way they shouldn't be- it's called 'Mutual Respect'.

Hdx

For one thing, you're not sending BNLS_VERSIONCHECKEX2 like you should, and once again REQUESTVERSIONBYTE is not needed, you get it in VERIONCHECKEX2
Why don't you try following the protocol that you quoted in the 1st post?
Also, BNLS headers != BNET Headers. So you will need to change the SendPacket function.
~-~(HDX)~-~

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Don Cullen

What the- they aren't the same? Damn, I need to do alot of research. Okay, I just looked over the bnetdocs, and found the header information for BNLS:

QuoteBNLS Headers
BNLS is the Battle.Net Logon Server, and can be used by bot authors to perform some of the computational tasks required during a Battle.net logon. It also allows bot authors to obtain useful information such as the current version byte for a game client, and has provisions for BNCS server emulator authors. It has the following headers:

(WORD)      Message Length, including this header
(BYTE)      Message ID
(VOID)      Message Data

By message length, does it start from the message length all the way to the end of the message data? Is the BNLS protocol same for both sending and receiving?

[Edit]

Instead of asking like a newbie, I'll just do it and find out if it works or not. Quick question though, will BNLS ban me for malformed packets, or requesting packets out of order?
Regards,
Don
-------

Don't wonder why people suddenly are hostile when you treat them the way they shouldn't be- it's called 'Mutual Respect'.

Barabajagal

#10
They aren't the same, no. The message length is the whole message length, just like the length in a BNCS packet. An easy way to do it is the Length of the data + 3 (2 for the word, 1 for the byte). Same protocol both ways, always.

Edit: BNLS will just disconnect you.

Don Cullen

Regards,
Don
-------

Don't wonder why people suddenly are hostile when you treat them the way they shouldn't be- it's called 'Mutual Respect'.

Don Cullen

Okay, I'm still getting stuck. I've re-coded it to be compatiable with BNLS, and yet it keeps failing. This is the console output:

QuoteReady.
Username set.
Password set.
GameCode set to SEXP.
CDKey set.
Missing VerByte, now accquiring new VerByte.
Connecting to BNLS...
Connected to BNLS.
0x10 BNLS_REQUESTVERSIONBYTE packet sent.
Sockets closed.
Disconnected.

This is my On BNLS Connect sub:

Private Sub sckBNLS_Connect()
    RaiseEvent DebugOutput("Connected to BNLS.")
    If m_VerByte = "" Then
        'missing verbyte
        BNLS_REQUESTVERSIONBYTE
    End If
End Sub


This is the BNLS_REQUESTVERSIONBYTE sub:

Public Sub BNLS_REQUESTVERSIONBYTE() '0x10

    Dim ProductID As Long
   
    Select Case UCase(GameCode)
        Case "SEXP"
            ProductID = PRODUCT_BROODWAR&
        Case "STAR"
            ProductID = PRODUCT_STARCRAFT&
        Case "D2DV"
            ProductID = PRODUCT_DIABLO2&
        Case "D2XP"
            ProductID = PRODUCT_LORDOFDESTRUCTION&
        Case "WAR3"
            ProductID = PRODUCT_WARCRAFT3&
        Case "W3XP"
            ProductID = PRODUCT_FROZENTHRONE&
        Case Else
            RaiseEvent sError("Unsupported game type.")
            Disconnect
            Exit Sub
    End Select
   
    With PacketBuf
        .Clear
        .InsertDWORD ProductID  'Product ID
        .SendBNLSPacket sckBNET, &H10    'Send 0x10 packet
        .Clear
    End With
    RaiseEvent DebugOutput("0x10 BNLS_REQUESTVERSIONBYTE packet sent.")
End Sub


This is my BNLS DataArrival sub:

Private Sub sckBNLS_DataArrival(ByVal bytesTotal As Long)
    Static PktBuff As String 'Packet Buffer
    Dim Incoming As String
    sckBNLS.GetData Incoming, vbString, bytesTotal
    PktBuff = PktBuff & Incoming
    Dim Pkt As BNCSPKT
    While Len(PktBuff) > 3
        Pkt.intPktLen = GetWord(Mid$(PktBuff, 0, 2))
        If Len(PktBuff) < Pkt.intPktLen Then Exit Sub
        ParseBNLSPacket (Left(PktBuff, Pkt.intPktLen))
        PktBuff = Mid(PktBuff, Pkt.intPktLen + 1)
    Wend
End Sub


This is my BNLS parser sub:

Public Sub ParseBNLSPacket(ByVal PacketData As String)
    Dim PacketID As Byte
    Dim PacketLen As Long
    PktDeBuf.SetData (PacketData)
    PacketLen = PktDeBuf.rWORD()
    PacketID = PktDeBuf.rBYTE()
    Select Case PacketID
        Case &H10   'BNLS_REQUESTVERSIONBYTE
            RaiseEvent DebugOutput("Recieved new VerByte from BNLS.")
            Dim Trash As Long
            Trash = PktDeBuf.rDWORD 'Product ID
            VerByte = PktDeBuf.rDWORD
            RaiseEvent DebugOutput(HexToString(VerByte))
            'Now retry the bnet connection
            'Call DMBot.BNET.Connect(BNETServer, BNETPort)
        Case Else
            AddC "Unrecognized Packet ID: 0x" & IIf(Len(Hex(PacketID)) = 1, "0" & Hex(PacketID), Hex(PacketID)) & " (" & GetPacketName(PacketID) & ")"
            DumpPacket (PacketData)
    End Select
    PktDeBuf.ClearData
End Sub


The intended goal was to get the program to raise the Event DebugOutput while passing along the verbyte as a string. For example, if CD was the verbyte, it'd change that from hex to string, so it'd display as "CD". But from what it looks like, it sends the 0x10 packet, then fails after that point. I think I screwed up somewhere, but I can't find the problem. Any ideas?
Regards,
Don
-------

Don't wonder why people suddenly are hostile when you treat them the way they shouldn't be- it's called 'Mutual Respect'.

l2k-Shadow

#13

Pkt.intPktLen = GetWord(Mid$(PktBuff, 0, 2))


Mid$() starts at 1, not 0, consider using:

Pkt.intPktLen = GetWord(Left$(PktBuff, 2))
Quote from: replaced on November 04, 2006, 11:54 AM
I dunno wat it means, someone tell me whats ix86 and pmac?
Can someone send me a working bot source (with bnls support) to my email?  Then help me copy and paste it to my bot? ;D
Já jsem byl určenej abych tady žil,
Dával si ovar, křen a k tomu pivo pil.
Tam by ses povídaj jak prase v žitě měl,
Já nechci před nikym sednout si na prdel.

Já nejsem z USA, já nejsem z USA, já vážně nejsem z USA... a snad se proto na mě nezloběj.

Don Cullen

Thanks for the tip. Tried it. I still don't see any incoming data...

I did some debugging, and from what it appears, the BNLS data arrival sub isn't even being run. I'd say that seems to indicate that I'm not getting a response from the BNLS server.

Maybe my 0x10 packet is malformed?

Or maybe BNLS requires a specific sequence of packets before I can send any other packets? Or is it possible to just connect to BNLS and immediately request verbyte without doing any other packets?
Regards,
Don
-------

Don't wonder why people suddenly are hostile when you treat them the way they shouldn't be- it's called 'Mutual Respect'.