Author | Message | Time |
---|---|---|
LockesRabb | 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: [code]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[/code] 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. | February 4, 2007, 6:42 PM |
warz | you are not allowed to be new at anything. | February 4, 2007, 7:23 PM |
HdxBmx27 | 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 | February 4, 2007, 8:48 PM |
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. | February 4, 2007, 10:02 PM |
HdxBmx27 | 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)~-~ | February 4, 2007, 10:11 PM |
LockesRabb | 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: [code]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[/code] 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: [code]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[/code] And the ParseBNLSPacket sub: [code]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[/code] 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? | February 5, 2007, 12:32 AM |
Barabajagal | DMBot.BNET ? maybe use DMBot.BNLS ? | February 5, 2007, 12:35 AM |
LockesRabb | 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.[/quote] 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. | February 5, 2007, 12:45 AM |
HdxBmx27 | 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)~-~ | February 5, 2007, 12:58 AM |
LockesRabb | 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: [quote]BNLS 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[/quote] 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? | February 5, 2007, 1:03 AM |
Barabajagal | 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. | February 5, 2007, 1:06 AM |
LockesRabb | Good to hear. Thanks. | February 5, 2007, 1:12 AM |
LockesRabb | 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: [quote]Ready. 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.[/quote] This is my On BNLS Connect sub: [code]Private Sub sckBNLS_Connect() RaiseEvent DebugOutput("Connected to BNLS.") If m_VerByte = "" Then 'missing verbyte BNLS_REQUESTVERSIONBYTE End If End Sub[/code] This is the BNLS_REQUESTVERSIONBYTE sub: [code]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[/code] This is my BNLS DataArrival sub: [code]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[/code] This is my BNLS parser sub: [code]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[/code] 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? | February 10, 2007, 10:01 PM |
l2k-Shadow | [code] Pkt.intPktLen = GetWord(Mid$(PktBuff, 0, 2)) [/code] Mid$() starts at 1, not 0, consider using: [code] Pkt.intPktLen = GetWord(Left$(PktBuff, 2)) [/code] | February 10, 2007, 10:20 PM |
LockesRabb | 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? | February 10, 2007, 10:56 PM |
Barabajagal | BNLS has absolutely no packet order requirements. post a packet log of your send to bnls? | February 10, 2007, 11:01 PM |
MyStiCaL | [quote author=Kyro link=topic=16245.msg164498#msg164498 date=1171144908] 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: This is my On BNLS Connect sub: [code]Private Sub sckBNLS_Connect() RaiseEvent DebugOutput("Connected to BNLS.") If m_VerByte = "" Then 'missing verbyte BNLS_REQUESTVERSIONBYTE End If End Sub[/code] [/quote] Just wondering why Verbyte is treated as a string and not a long? | February 11, 2007, 3:04 AM |
Barabajagal | [quote author=Mystical link=topic=16245.msg164527#msg164527 date=1171163065] [quote author=Kyro link=topic=16245.msg164498#msg164498 date=1171144908] 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: This is my On BNLS Connect sub: [code]Private Sub sckBNLS_Connect() RaiseEvent DebugOutput("Connected to BNLS.") If m_VerByte = "" Then 'missing verbyte BNLS_REQUESTVERSIONBYTE End If End Sub[/code] [/quote] Just wondering why Verbyte is treated as a string and not a long? [/quote] why would it be a long... it's a verBYTE. a byte value. | February 11, 2007, 3:37 AM |
FrostWraith | Kinda stupid but what do your constants looks like? | February 11, 2007, 3:47 AM |
LockesRabb | My bot allows the user to give a string value, which in turn will be converted into a long value. See below. It should answer your question. [code]Public Sub SID_AUTH_INFO() '0x50 If Ready = False Then RaiseEvent sError("Error! Missing data!") RaiseEvent sError("Connection aborted locally.") Disconnect Else With PacketBuf .Clear .InsertDWORD &H0 'BNET Protocol ID (Currently zero.) .InsertDWORD CLng("&H" & Replace(StrToHex("IX86"), " ", vbNullString)) 'IX86 .InsertDWORD CLng("&H" & Replace(StrToHex(m_GameCode), " ", vbNullString)) 'SEXP .InsertDWORD CLng("&H" & m_VerByte) 'Verbyte, changes with product upgrade. .InsertDWORD CLng("&H" & Replace(StrToHex("enUS"), " ", vbNullString)) 'Product Language .InsertDWORD CLng("&H" & Replace(StrToHex(IP2NBO(sckBNET.LocalIP)), " ", vbNullString)) 'Local IP for NAT compatibility .InsertDWORD GetTimeZoneBias 'Time Zone bias .InsertDWORD GetUserDefaultLCID() 'Locale ID .InsertDWORD GetUserDefaultLangID 'Language ID .InsertNTString GetInfo(LOCALE_SABBREVCTRYNAME) 'Abbrev. of country .InsertNTString GetInfo(LOCALE_SENGCOUNTRY) 'Name of country .SendPacket sckBNET, &H50 'Send 0x50 packet .Clear .InsertDWORD &H0 '0ms ping. .SendPacket DMBot.BNET, &H25 'Send 0x25 packet .Clear End With RaiseEvent DebugOutput("0x50 SID_AUTH_INFO packet sent.") End If End Sub[/code] Edit: As for the constants, here... [code]' PacketID Constants for Visual Basic ' Generated by BnetDocs on 10/02/07 02:13:14 ' BnetDocs software written by Arta ' Content compiled by Arta & Skywing ' Visit us on Battle.net in channel Op [vL] Public Const PRODUCT_STARCRAFT& = &H1 Public Const PRODUCT_BROODWAR& = &H2 Public Const PRODUCT_WAR2BNE& = &H3 Public Const PRODUCT_DIABLO2& = &H4 Public Const PRODUCT_LORDOFDESTRUCTION& = &H5 Public Const PRODUCT_JAPANSTARCRAFT& = &H6 Public Const PRODUCT_WARCRAFT3& = &H7 Public Const PRODUCT_FROZENTHRONE& = &H8[/code] | February 11, 2007, 4:16 AM |
l2k-Shadow | post a packet log.. | February 11, 2007, 4:29 AM |
LockesRabb | I will as soon as I can figure out how to get WireShark to packet log. I'm a newbie to packet logging. I just installed it, and haven't the foggest idea as to how to configure it to only display BNLS and BNET packets... Tried searching for a tutorial for specificially BNLS/BNET packet logging pertaining to WireShark/Etheral, no such luck... | February 11, 2007, 5:14 AM |
Barabajagal | why not just use WPE...? it makes quick things like that a lot easier... linky if ya need it (note that some anti-viruses think the dll is a trojan, since it sniffs packets... it's not a trojan, nor really a false positive, since it does sniff packets. you just happen to be the one that sees the packets.) | February 11, 2007, 5:17 AM |
LockesRabb | Hrmmmm... I'm having the same problems as Etheral/Wireshark, and Commview. Which is: it seems to be logging nothing. Let me compile it as an exe, and try again. Hmm... That's strange, nothing. So that seems to imply there is nothing being sent... wtf... I'm going to look at my code and see why this innate drivel isn't working. -------- Edit: I just looked at my code. This is the 0x10 sub: [code]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[/code] And this is the SendBNLSPacket sub in the PacketBuffer class: [code]Public Function SendBNLSPacket(sck As Winsock, Optional PacketID As Long) As Boolean If sck.State = sckConnected Then sck.SendData MakeWORD(Len(Buffer) + 4) & Chr(PacketID) & Buffer End If Clear End Function[/code] And the name of the socket for BNLS is sckBNLS... | February 11, 2007, 5:50 AM |
Barabajagal | erm... the length is +3, not +4. A word is 2 bytes, plus 1 byte for the ID. | February 11, 2007, 5:59 AM |
LockesRabb | Oops, thanks for pointing that out. Corrected that one. But that still doesn't solve the fact the program isn't transmitting data. I mean, consider: In order for BNLS to be sending me data, it must first recieve data. I've been able to confirm that the program successfully connects to BNLS, but beyond that, the program seems to fail in transmitting data to BNLS. I don't understand why it's not sending -- all of the code seems intact... | February 11, 2007, 6:05 AM |
Barabajagal | second problem .SendBNLSPacket sckBNET, &H10 'Send 0x10 packet shouldn't you be using sckBNLS? you really need to keep track of things like this better. | February 11, 2007, 6:08 AM |
LockesRabb | Finally. It works. Thanks RealityRipple, and everyone else who helped. I appreciate it. Jeez. I'm blind. I could've swore I typed BNLS, not BNET. You're right, I really need to pay attention to what I'm typing and where it goes... Any idea how I can take a byte variable and display it as a string? For instance, if I get 0x10 from BNLS, it comes in vb as &H10. Is there a way I can take this hex and convert it directly into a string ("0x10")? I tried this: [code]RaiseEvent DebugOutput("Identified as: " & CStr(PacketID))[/code] But it came out as 16, not 10. Any tips? | February 11, 2007, 6:18 AM |
Barabajagal | "Identified as 0x" & Hex$(PacketID) | February 11, 2007, 6:21 AM |
LockesRabb | Ah, simple. Works like a charm: [quote]Ready. 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. Receiving incoming data... Parsing BNLS packet... Identified as 0x10 Recieved new VerByte from BNLS. VerByte set: CF Sockets closed. Disconnected.[/quote] Many thanks. :-) | February 11, 2007, 6:28 AM |
Myndfyr | [quote author=[RealityRipple] link=topic=16245.msg164528#msg164528 date=1171165054] why would it be a long... it's a verBYTE. a byte value. [/quote] Because the Battle.net protocol sends it as a 32-bit value, not an 8-bit value. This is most likely due to greater efficiency in reading and writing data that is aligned to the native word size of the processor. | February 11, 2007, 6:33 AM |
Barabajagal | That's why you do CLng(Config.VerByte). You define the variable as a byte because it's more efficient to have a byte variable than a long variable. Then when you need to send it, you send it as a long. | February 11, 2007, 6:37 AM |
Ringo | [quote author=[RealityRipple] link=topic=16245.msg164549#msg164549 date=1171175857] That's why you do CLng(Config.VerByte). You define the variable as a byte because it's more efficient to have a byte variable than a long variable. Then when you need to send it, you send it as a long. [/quote] Until a version byte exceeds 0xFF, and your program hits a problem ;) | February 11, 2007, 6:57 AM |
Barabajagal | oh noes, i'll have to set it to an int and release an update. how terrible. everyone else will also have to stop calling them verbytes then, too. | February 11, 2007, 7:49 AM |
MyStiCaL | I think you just like to argue with people, but wouldn't you mean CByte(Config.Verbyte) if you want it to be a byte? CLong() would be converting it to a long? CLng Function: [code] CLng(expression) Converts the value of expression to a Long data type. The argument expression must be a numeric value from -2,147,483,648 to 2,147,483,647. Fractions are rounded. [/code] Cbyte Function: [code] CByte(expression) Converts the value of expression to a Byte data type. The argument expression must be a numeric value between 0 and 255. [/code] | February 11, 2007, 8:01 AM |
Barabajagal | that's the point... Config.VerByte is defined as a byte for less memory usage. the InsertDWORD requires a long, so you do CLng(Config.VerByte). and yes, I have a VERY argumentative nature. | February 11, 2007, 8:04 AM |
rabbit | Or if you're using an even half-decent packet buffer you call your uint_32 insertion on the Config.VerByte and the procedure automatically converts it. | February 11, 2007, 12:39 PM |