News:

Who uses forums anymore?

Main Menu

[java] Sample w2bn login sequence

Started by chuck, September 17, 2006, 07:44:06 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

chuck

I'm trying to make a w2bn bot, but i dont know much about the login sequence.

I've tryed reading http://bnetdocs.valhallalegends.com/sequence.php, but it didn't help me out much.

Can anyone here post an example login sequence (In a easy-to-read format) here?

So far, my Connection class:


package connection;

import java.net.*;
import java.io.*;

public class Connection implements Runnable {
   
    protected Socket _socket;
    protected DataInputStream _in;
    protected DataOutputStream _out;
   
    protected String _server;
    protected int _port;
   
    protected boolean connected = false;
   
    public Connection(String server, int port) throws Exception {
        this._server = _server;
        this._port = _port;
       
        connect();
    }
   
    public void connect() throws Exception {
        _socket = new Socket(_server, _port);
        _in = new DataInputStream(_socket.getInputStream());
        _out = new DataOutputStream(_socket.getOutputStream());
       
        connected = true;
       
        run();
    }
   
    public void run() {
        try {
            login();
            while (connected && _in.readLine() != null) {
                String line = _in.readLine();
               
                print(_server + ":" + _port + ">> " + line);
            }
           
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
   
    public void login() {
        if (connected) {
            try {
                send((byte) 0x1E); // is this what i do?
               
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
   
    public void print(String text) {
        System.out.println(text);
    }
   
    public void send(byte b) throws IOException {
        _out.write(b);
    }
   
    public void killSock() {
        try {
            _socket.close();
            _in.close();
            _out.close();
            connected = false;
        } catch(IOException e) {
            System.out.println(e);
        }
    }
   
}
Chucks Blog
JavaOp2 Plugins

Quote
Error, keyboard not connected. Press F1 to continue.

Joe

Quote from: Camel on June 09, 2009, 04:12:23 PMI'd personally do as Joe suggests

Quote from: AntiVirus on October 19, 2010, 02:36:52 PM
You might be right about that, Joe.


chuck

Quote from: Joex86] link=topic=7385.msg91937#msg91937 date=1158537404]
BnetDocs is your best friend, specifically this article.
It confused the shit outta me.

Oh, and please excuse the typo:

this._server = _server;
this._port = _port;
Chucks Blog
JavaOp2 Plugins

Quote
Error, keyboard not connected. Press F1 to continue.

chuck

Hmm... This makes bnet not kick me off... As if its waiting for more data...


send((byte) 0x01);


Can someone atleast give me an example of SID_CLIENTID using my send method? I should be able to zoom along after that.
Chucks Blog
JavaOp2 Plugins

Quote
Error, keyboard not connected. Press F1 to continue.

Chavo


Blaze

Quote from: unTactical on September 17, 2006, 10:34:37 PM
IIRC W2BN doesn't use SID_CLIENTID

That doesn't matter to the battle.net server.  :)

You can login to the battle.net server (as of right now, and a long time before now) using the 0x50 system.  That saves a lot of handling if you want to do all the legacy clients.
And like a fool I believed myself, and thought I was somebody else...

chuck

Ok... after a bit of reading, and downloading a packet buffer from javaop1, i made this code, and am partialy confused. If anyone could give me some corrections.


package connection;

import java.net.*;
import java.io.*;

import util.Buffer;

public class Connection implements Runnable {
   
    protected Socket _socket;
    protected DataInputStream _in;
    protected DataOutputStream _out;
   
    protected String _server;
    protected int _port;
   
    protected boolean connected = false;
   
    public Connection(String server, int port) throws Exception {
        this._server = server;
        this._port = port;
       
        connect();
    }
   
    public void connect() throws Exception {
        _socket = new Socket(_server, _port);
        _in = new DataInputStream(_socket.getInputStream());
        _out = new DataOutputStream(_socket.getOutputStream());
       
        connected = true;
       
        run();
    }
   
    public void run() {
        try {
            login();
            while (connected && _in.readLine() != null) {
                String line = _in.readLine();
               
                print(_server + ":" + _port + ">> " + line);
            }
           
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
   
    public void login() {
        if (connected) {
            try {
                send((byte)0x01, null); // Send login thingy
               
                Buffer login = new Buffer();
                login.addDWord(0);
                login.addString("68XI");
                login.addString("W2BN");
                login.addDWord(0x4F);
                login.addDWord(0);
                login.addDWord(0);
                login.addDWord(0);
                login.addDWord(0);
                login.addDWord(0);
                login.addString("CAN");
                login.addDWord(0);
                send((byte)0x50, login.getBuffer());
               
               
               
               
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
   
    public void print(String text) {
        System.out.println(text);
    }
   
    public void send(byte code, byte[] b) throws IOException {
        _out.write(code);
       
        if (b != null)
            _out.write(b);
    }
   
   
    public void sendText(String text) throws IOException {
        _out.write(text.getBytes());
    }
   
    public void killSock() {
        try {
            _socket.close();
            _in.close();
            _out.close();
            connected = false;
        } catch(IOException e) {
            System.out.println(e);
        }
    }
   
}
Chucks Blog
JavaOp2 Plugins

Quote
Error, keyboard not connected. Press F1 to continue.

Joe

Feel free to take a look at (and use pieces from) my project CCGBot. The way I implemented multiple protocols was nasty, but it worked. Most of the version checking code (in fact, all if it) is iago's, as well as the XSHA1 implementation. Other than that I think I wrote the rest and released it under the BSD license, and the rest is public domain.

EDIT -
W2BN isn't implemented in CCGBot yet (oops) but it shows other protocols though.
Quote from: Camel on June 09, 2009, 04:12:23 PMI'd personally do as Joe suggests

Quote from: AntiVirus on October 19, 2010, 02:36:52 PM
You might be right about that, Joe.


chuck

Its alright, i just found out how to get over the first hurdle.

Source code below for others

package connection;

import java.net.*;
import java.io.*;

import util.BNetBuffer;

public class Connection implements Runnable {
   
    protected Socket _socket;
    protected InputStream _in;
    protected OutputStream _out;
   
    protected String _server;
    protected int _port;
   
    protected boolean connected = false;
   
    public Connection(String server, int port) throws Exception {
        this._server = server;
        this._port = port;
       
        connect();
    }
   
    public void connect() throws Exception {
        connected = true;
        _socket = new Socket(_server, _port);
        run();
    }
   
    public void run() {
        try {
            _in = _socket.getInputStream();
            _out = _socket.getOutputStream();
           
            login();
            print("Logged in.");
           
            int line;
            while (true) {
                line = _in.read();
               
                print("" + line);
            }
           
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
   
    public void login() {
        if (connected) {
            try {
                send((byte)0x01); // Send login thingy
               
                BNetBuffer authinfo = new BNetBuffer();
                authinfo.setCode((byte) 0x50);
               
                authinfo.add(0x00000000);
                authinfo.add(0x49583836);
                authinfo.add(getGameCode());
                authinfo.add(0x4F);
               
                // These can just be nulled-out
                authinfo.add((int) 0x00000000); // product language
                authinfo.add((int) 0x00000000); // Local ip
                authinfo.add((int) 0x00000000); // Timezone bias
                authinfo.add((int) 0x00000000); // Locale Id
                authinfo.add((int) 0x00000000); // Language Id
               
                authinfo.addNTString("CAN");
                authinfo.addNTString("Canada");
               
                sendNow(authinfo);
               
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
   
    public void send(byte b) throws IOException {
        _out.write(b);
       
        _out.flush();
    }
   
    public int getGameCode() {
        return 'W' << 24 |
                '2' << 16 |
                'B' <<  8 |
                'N' <<  0;
    }
   
    public void print(String text) {
        System.out.println(text);
    }
   
    public void sendNow(util.Buffer data) throws IOException {
        _out.write(data.getBuffer());
    }
   
   
    public void killSock() {
        try {
            _socket.close();
            _in.close();
            _out.close();
            connected = false;
        } catch(IOException e) {
            System.out.println(e);
        }
    }
   
}

Chucks Blog
JavaOp2 Plugins

Quote
Error, keyboard not connected. Press F1 to continue.

Chavo

A few things (don't take this the wrong way, I think you are doing quite well):


   public void connect() throws Exception {
        connected = true;
        _socket = new Socket(_server, _port);
        run();
    }


You are setting connected to true, but you don't appear to know why because you only check it once :)
It would be more appropriate to have your while loop check this boolean rather than loop until an Exception occurs.


                authinfo.add((int) 0x00000000); // product language
                authinfo.add((int) 0x00000000); // Local ip
                authinfo.add((int) 0x00000000); // Timezone bias
                authinfo.add((int) 0x00000000); // Locale Id
                authinfo.add((int) 0x00000000); // Language Id


You don't need to cast an integer to an integer! :)  authinfo.add(0); would work for any of those but if you prefer the full hex dword notation thats fine too.

    public void sendNow(util.Buffer data) throws IOException {
        _out.write(data.getBuffer());
    }


Don't forget to flush!

    public void killSock() {
        try {
            _socket.close();
            _in.close();
            _out.close();
            connected = false;
        } catch(IOException e) {
            System.out.println(e);
        }
    }


Those 3 close methods are pretty likely to throw an IOException before all of them finish executing (especially since you are closing the streams after they should already be closed since you closed the socket).  While probably a minor issue, that could easily cause connected to not be changed.  I would change it first or change it outside the try{} block.

chuck

Quote from: unTactical on September 18, 2006, 10:03:26 AM
A few things (don't take this the wrong way, I think you are doing quite well):


   public void connect() throws Exception {
        connected = true;
        _socket = new Socket(_server, _port);
        run();
    }


You are setting connected to true, but you don't appear to know why because you only check it once :)
It would be more appropriate to have your while loop check this boolean rather than loop until an Exception occurs.

The connected boolean is reserved for future use.
Quote from: unTactical on September 18, 2006, 10:03:26 AM

                authinfo.add((int) 0x00000000); // product language
                authinfo.add((int) 0x00000000); // Local ip
                authinfo.add((int) 0x00000000); // Timezone bias
                authinfo.add((int) 0x00000000); // Locale Id
                authinfo.add((int) 0x00000000); // Language Id


You don't need to cast an integer to an integer! :)  authinfo.add(0); would work for any of those but if you prefer the full hex dword notation thats fine too.
I copyed that stuff from javaop1. Blame iago. :)

Quote from: unTactical on September 18, 2006, 10:03:26 AM
    public void sendNow(util.Buffer data) throws IOException {
        _out.write(data.getBuffer());
    }


Don't forget to flush!

    public void killSock() {
        try {
            _socket.close();
            _in.close();
            _out.close();
            connected = false;
        } catch(IOException e) {
            System.out.println(e);
        }
    }


Those 3 close methods are pretty likely to throw an IOException before all of them finish executing (especially since you are closing the streams after they should already be closed since you closed the socket).  While probably a minor issue, that could easily cause connected to not be changed.  I would change it first or change it outside the try{} block.
Hmm... should do flush();... otherwise i get a stinky socket :)
And yah, never realy looked much at killsock(). Thanks for ponting that out

Thnx for the help. Now i just need to identify packets (Yay?) and make them trigger events.
Chucks Blog
JavaOp2 Plugins

Quote
Error, keyboard not connected. Press F1 to continue.

Chavo

Quote from: chuck on September 18, 2006, 11:09:59 AM
The connected boolean is reserved for future use.

Thats fine, but I still think an infinite loop with the only escape possibility being an exception is bad practice.

Quote from: chuck on September 18, 2006, 11:09:59 AM
Quote from: unTactical on September 18, 2006, 10:03:26 AM

                authinfo.add((int) 0x00000000); // product language
                authinfo.add((int) 0x00000000); // Local ip
                authinfo.add((int) 0x00000000); // Timezone bias
                authinfo.add((int) 0x00000000); // Locale Id
                authinfo.add((int) 0x00000000); // Language Id


You don't need to cast an integer to an integer! :)  authinfo.add(0); would work for any of those but if you prefer the full hex dword notation thats fine too.
I copyed that stuff from javaop1. Blame iago. :)
* unTactical yells at iago

Quote from: chuck on September 18, 2006, 11:09:59 AM
Thnx for the help. Now i just need to identify packets (Yay?) and make them trigger events.
No problem, you'll probably what a constants class for identifying the packets, mine is more up to date than iagos and any that I've seen on VL. 
Feel free to use it: http://clanhiim.com/sheriff/src/constants/PacketConstants.class

Hdx

Quote            while (true) {
                line = _in.read();
               
                print("" + line);
            }
Thats where connected should be used.
Also, you're reading a byte not a line.
Quote    public int getGameCode() {
        return 'W' << 24 |
                '2' << 16 |
                'B' <<  8 |
                'N' <<  0;
    }
Its more efficient jsut to store the result fo that, insted of figuring it out every time.
private static final PROD_W2BN = 0x5732424E //W2BN

Quote
            login();
            print("Logged in.");
!! OMG YOU SENT ONE PACKET AND POOF YOU'RE LOGGED IN!!!
Just had to rag on you about your naming.
Quote    public void login() {
        if (connected) {
            try {
                send((byte)0x01); // Send login thingy
                /*
                   code
                */
                sendNow(authinfo);
               
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

1st, The 'Login thingy' is called the protocol byte. It tells the server what you want to do!
2nd, You have sendNow throw a IOException.. that okay, but then you have login() handle that! So you are sjtu going to go along as if no exception was thrown? Bad boy.

And seriously, don't be lazy, use the correct protocol!

QuoteIts alright, i just found out how to get over the first hurdle.
QuoteI copyed that stuff from javaop1.
Obviously not...
Learn what that 'stuff' is before you continue.

~-~(HDX)~-~
http://img140.exs.cx/img140/6720/hdxnew6lb.gif
09/08/05 - Clan SBs @ USEast
[19:59:04.000] <DeadHelp> We don't like customers.
[19:59:05.922] <DeadHelp> They're assholes
[19:59:08.094] <DeadHelp> And they're never right.

Chavo

He is doing fine, I doubt you wrote a packet buffer from scratch the first time you created a socket based program ;)

While you are right in all your points above, the efficiency thing is less important than him understanding it, so I made a point to not mention it.

Hdx

Quote from: unTactical on September 18, 2006, 11:42:50 AM
He is doing fine, I doubt you wrote a packet buffer from scratch the first time you created a socket based program ;)

While you are right in all your points above, the efficiency thing is less important than him understanding it, so I made a point to not mention it.
Not the 1st time, but after like 3 hrs of doing
wsClient.Send(Chr$(0))
* HdxBmx27 shudders at those days
I decided to write a crappy buffer yes.

Also I assumed he understood it if he could write such a function. (But now I see he jsut stole it from ron)

I prefer people do things right (AE: following the protocol correctly.)
Also, 'OLS' is harder then 'OOLS' (SID_AUTH* vs non.)
~-~(HDX)~-~
http://img140.exs.cx/img140/6720/hdxnew6lb.gif
09/08/05 - Clan SBs @ USEast
[19:59:04.000] <DeadHelp> We don't like customers.
[19:59:05.922] <DeadHelp> They're assholes
[19:59:08.094] <DeadHelp> And they're never right.