Valhalla Legends Forums Archive | Battle.net Bot Development | BNLS and Bnet Login Troubles

AuthorMessageTime
Myndfyr
Hi all,

I wrote a while back that I wanted to start working on a bot... some suggested I work on a changelog and the like, and I incorporated that suggestion.

Right now, I'm having issues with the connection process. I'm programming the bot in C# (Visual Studio 7), and I think the major problem I'm having is the way that .NET handles strings (as Unicode) rather than as 8-byte character arrays. I've tried a few things, including wrapping the VB 6 Winsock OCX control, but thus far, have had little success. Here's what I've tried, in total:

1.) Convert the SoupBot implementation of the VB6 PacketBuffer to VB7. Didn't work; I never got any data back.
2.) Use the wrapped System.Net.Sockets.Socket class through .NET. This could theoretically work (more below)
3.) Wrap the VB6 Winsock OCX completely and use that to connect. That didn't work; I can connect, but I can't send or receive data. I'm sure my event wireups are correct, though.

Ideally, I'd like to use #2, because it's enough hassle to have to also include another Winsock OCX wrapper DLL _and_ the Interop proxy DLL _and_ the actualy mswinsck.ocx file. Also using that socket, I'm guaranteed to have the strings and such transfer correctly (I can encode strings in UTF8 or ASCII and simply use a byte[] to send them.)

My issue with the Socket class is that it is not event-driven like the Winsock OCX is, and it only *truly* supports one-way communication at a time. So, if I set up my socket to connect to the BNLS server, I can send data, and I want to be able to see data immediately as it arrives. If I want to listen on the socket, and have an asynchronous method called as soon as I get some data, I can set up an asyncrhonous callback:

[code]
public void SetupSocket() {
// assuming sckBnls is a Socket and is already set up...
sckBnls.Connect();
// I have a byte[] buffer in the class that is 1024 in length.
sckBnls.BeginReceive(myBuf, 0, 1024, SocketFlags.None, new AsyncCallback(this.Receive_Done), sckBnls);
// the method call is:
// object.BeginReceive(byte[], int, int, SocketFlags, AsyncCallback, object);
// note that this AsyncCallback is type void(IAsyncResult)
}

public void Receive_Done(IAsyncResult iar) {
Socket sck = (Socket)iar.AsyncState;
int dataLength = sck.EndReceive();
// get the data out of the socket...
}
[/code]

What happens, though, if I try to set up the socket to receive asynchronously but need to send a message while waiting for it to receive, it stops receiving and calls my async callback with a data length of 0, and doesn't resume receiving after I send. I've tried setting up the asyncrhonous callback so that after it's done sending it resumes, but it just gets into an infinite loop (which I determined by tracing the method calls).

If anyone has any experience with these sockets, I'd really appreciate the help.

Here's my changelog thus far (it doesn't always occur to me to make changes):

[code]
v0.0.20
Kills current database access routines to move to a Dbase.dll file through which all data transactions occur. Dbase.dll takes high-level methods and translates them into appropriate SQL commands. It also translates data replacements (SQL commands with Access can't contain apostrophes, and so the apostrophe is replaced with a less offensive character).
Uses the Windows Platform SDK function SendMessage to scroll the rich text window.
Creates single pluggable Connection class that connects to both BNLS and Battle.net. Incomplete, but uses a high-level event interface so that it'd be easy to use to develop a bot.

v0.0.15
Database design created
Channel join affects database
EventHost created and wired

v0.0.12
Resizing now works
Demo of adding people dynamically to user list
Incorporates [slightly modified] XHTML RichTextBox control for .NET 1.0 by Eric Voreis from the GotDotNet user area, www.gotdotnet.com

v0.0.10
High level design, no business objects
Incorporates interface elements by Crownwood Consulting Ltd., www.dotnetmagic.com
[/code]

Basically, the interface layout is demo'd, but I don't want to work on the interface until I see for sure how Bnet connects. I also walked through the code (not during execution, but traced through all the method calls) of SoupBot and figured out the bnet connection algorithm, which I have stored in another text file.

Any help would be great! Thanks in advance,

--Rob

EDIT: Just a note, the reason I used P/Invoke to access the SendMessage function of the Windows API is that the RichTextBox didn't automatically scroll when I added text to it. The SendMessage function is considered "unsafe," but oh well... it worked =) As far as the Dbase.dll file - it will just be another assembly that basically will contain canned data access routines, such as AddUser(string username, PrivilegeLevel level, string addedBy) etc. That way, the interface can be consumed by another developer who may want to experiment with MSDE/SQL Server or MySql, etc. That setup is pretty much complete. It contains all the core business objects (User, PrivilegeLevel, etc.) so that people who want to develop plugins for the bot or use the bot's interfaces can. I'll probably end up adding some kind of license or SecurityContext requirement so that people have to at least let me know if they are using my binaries.
September 4, 2003, 5:25 PM
DaRk-FeAnOr
Am I missing something, but you said you are programming in C#:
[quote]I'm programming the bot in C# (Visual Studio 7)[/quote]
Why would you be converting Visual Basic 6 to Visual Basic 7, if you are programming in a C language?
September 4, 2003, 10:37 PM
Camel
[quote author=DaRk-FeAnOr link=board=17;threadid=2582;start=0#msg20190 date=1062715054]
Am I missing something, but you said you are programming in C#:
[quote]I'm programming the bot in C# (Visual Studio 7)[/quote]
Why would you be converting Visual Basic 6 to Visual Basic 7, if you are programming in a C language?
[/quote]

C# == (C_Syntax)VB.Net
September 4, 2003, 11:41 PM
Myndfyr
[quote author=DaRk-FeAnOr link=board=17;threadid=2582;start=0#msg20190 date=1062715054]
Am I missing something, but you said you are programming in C#:

Why would you be converting Visual Basic 6 to Visual Basic 7, if you are programming in a C language?
[/quote]

No, you're right. One of the perks of using .NET is that I can interoperate very easily... so I just converted the pre-packaged PacketBuffer from SoupBot, keeping it in VB. I then just referenced that DLL whenever I wanted to use the PacketBuffer class. The .NET runtime takes care of going between C# and VB7 at compile-time, because the compiler emits something similar to Java bytecode (called Intermediary Language or MSIL), which looks very similar to assembly. That as a low-level language is compiled at runtime by a just-in-time compiler, and the resultant machine code is stored in a global cache so that it doesn't need to be compiled again. That's what makes .NET language-agnostic.

I hope I answered your question....
September 4, 2003, 11:44 PM
Myndfyr
[quote]
C# == (C_Syntax)VB.Net
[/quote]

Heh, true, true...
September 4, 2003, 11:45 PM
Camel
[quote author=Myndfyre link=board=17;threadid=2582;start=0#msg20210 date=1062719072]The .NET runtime takes care of going between C# and VB7 at compile-time, because the compiler emits something similar to Java bytecode (called Intermediary Language or MSIL), which looks very similar to assembly. That as a low-level language is compiled at runtime by a just-in-time compiler, and the resultant machine code is stored in a global cache so that it doesn't need to be compiled again. That's what makes .NET language-agnostic.[/quote]

Ok, you lost me somewhere around 'runtime'...
I like my explanation better.
September 4, 2003, 11:52 PM

Search