Hm, just to warn you, this will be a long post ::)
As the title said, I send 0x50 to bnet and get bs back. The "bs" is "-1-1-1-1" ... and on when I print the data out as ints, and "?????????" ... when I print it out as chars. I'm trying to narrow down what could be wrong. First of all, here is my 0x50 packet:
public class SidAuthInfo extends PacketBuffer {
public SidAuthInfo() {
super((byte) 0x50);
insertDword((byte) 0x00); // protocol id
insertNonNTString("IX86"); // platform ID
insertNonNTString("PXES"); // product ID
insertDword((byte) 0x00); // product language
insertDword((byte) 0x00); // local ip
insertDword((byte) 0x00); // time zone bias
insertDword((byte) 0x00); // locale id
insertDword((byte) 0x00); // language id
insertNTString("USA"); // country abbrev.
insertNTString("United States"); // country name
}
}
Is there anything wrong with this? Secondly, here are my packet buffer and packet classes:
public class PacketBuffer extends Packet {
public PacketBuffer() {}
public PacketBuffer(byte packetheader) {
super(packetheader);
}
public PacketBuffer(Packet data) {
super(data);
}
public PacketBuffer(byte[] rawdata) {
super(rawdata);
}
public void insertWord(int value) {
insertByte((byte) ((value >> 8) & 0xFF));
insertByte((byte) (value & 0xFF));
}
public void insertDword(int value) {
insertByte((byte) ((value >> 24) & 0xFF));
insertByte((byte) ((value >> 16) & 0xFF));
insertByte((byte) ((value >> 8) & 0xFF));
insertByte((byte) (value & 0xFF));
}
public void insertNonNTString(String str) {
byte[] strbytes = str.getBytes();
insertBytes(strbytes);
}
public void insertNTString(String str) {
byte[] strbytes = str.getBytes();
insertBytes(strbytes);
insertByte((byte) 0x00);
}
}
public class Packet {
private Vector buffer = new Vector();
protected static final int WORD = 2;
protected static final int DWORD = 4;
private byte packetheader;
public Packet() {}
public Packet(byte packetheader) {
this.packetheader = packetheader;
}
public Packet(Packet data) {
insertBytes(data.getRawData());
}
public Packet(byte[] rawdata) {
insertBytes(rawdata);
}
public void insertByte(byte element) {
buffer.add(new Byte(element));
}
public void insertBytes(byte[] elements) {
for (int i = 0; i < elements.length; i++)
buffer.add(new Byte(elements[i]));
}
public byte getByteAt(int index) {
Byte temp = (Byte)buffer.get(index);
byte returnbyte = temp.byteValue();
return returnbyte;
}
public byte[] getRawData() {
byte[] packet = new byte[buffer.size()];
for (int i = 0; i < buffer.size(); i++) {
Byte temp = (Byte)buffer.get(i);
packet[i] = temp.byteValue();
}
return packet;
}
public byte getPacketHeader() {
return packetheader;
}
}
Thirdly here is the class I created to test all this out. (Warning: long).
public class Login {
// Packets
Packet sidAuthInfoSnd;
Packet sidPing;
Packet sidAuthInfoRcv;
// IO stuff
private BufferedReader reader;
private Socket sock;
private InputStream in;
private OutputStream out;
// command stuff
private char trigger = '/';
private enum Commands { CONNECT, DISC, QUIT }
public Login() {
Packet buff = new PacketBuffer();
reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println
("COMMANDS:" + "\n" +
"/CONNECT to connect" + "\n" +
"/DISC to disc" + "\n" +
"/QUIT to exit program" );
while (true) {
String text = null;
try {
text = reader.readLine();
}
catch (IOException e) {
System.out.println("ERROR!");
}
if (text != null && text.charAt(0) == trigger && text.toCharArray().length > 2) {
char[] chars = text.toCharArray();
char[] temp = new char[chars.length - 1];
for (int i = 0; i < temp.length; i++) {
temp[i] = chars[i + 1];
}
String cmd = new String(temp);
switch(Commands.valueOf(cmd.toUpperCase())) {
case CONNECT:
System.out.println("Connecting...");
connect();
break;
case DISC:
System.out.println("Disconnecting...");
disc();
break;
case QUIT:
disc();
System.exit(0);
default:
System.out.println("No Command.");
}
}
}
}
private void connect() {
// create IO objects
try {
sock = new Socket("useast.battle.net", 6112);
in = sock.getInputStream();
out = sock.getOutputStream();
}
catch(IOException e) {
System.out.println(e.toString());
}
sidAuthInfoSnd = new SidAuthInfo();
try {
out.write(sidAuthInfoSnd.getRawData());
}
catch (IOException e) {
System.out.println(e.toString());
}
sidPing = rcvPing();
byte[] ping = sidPing.getRawData();
for (int i : new int[ping.length]) {
System.out.print(ping[i]);
}
System.out.print("\n");
seeRcvAuthInfo();
}
private void disc() {
}
private Packet rcvPing() {
Packet buff = new PacketBuffer((byte) 0x25);
for (int i = 0; i < 4; i++) {
try {
buff.insertByte((byte)in.read());
}
catch (IOException e) {
System.out.println(e.toString());
}
}
return buff;
}
private void seeRcvAuthInfo() {
Thread t = new Thread(new Runnable() {
public void run() {
//-------
// after not rcving for 5 secs I seal packet
try {
sock.setSoTimeout(5000);
}
catch (SocketException e) {
System.out.println(e.toString());
}
//-----
//place the stuff I rcv into packet
Packet buff = new PacketBuffer((byte) 0x50);
boolean rcving = true;
while (rcving) {
try {
byte input = (byte) in.read();
buff.insertByte(input);
System.out.print((char)input); // just to see what i'm rcving as i'm rcving it
}
catch (SocketTimeoutException timeout) {
System.out.println("TIMEOUT!");
rcving = false;
}
catch (IOException e) {
System.out.println("ERROR RECEIVING SidAuthInfo");
break;
}
}
//---------
//disable timeout
try {
sock.setSoTimeout(0);
}
catch (SocketException e) {
System.out.println(e.toString());
}
//-------
//print out packet
byte[] data = buff.getRawData();
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]);
}
}
});
t.start();
}
/**
* @param args
*/
public static void main(String[] args) {
new Login();
}
}
First, your SID_AUTH_INFO packet format is incorrect.
Quote(DWORD) Protocol ID (0)
(DWORD) Platform ID
(DWORD) Product ID
(DWORD) Version Byte
(DWORD) Product language
(DWORD) Local IP for NAT compatibility*
(DWORD) Time zone bias*
(DWORD) Locale ID*
(DWORD) Language ID*
(STRING) Country abreviation
(STRING) Country
You have forgotten the version byte. The current one is 0xCD
Second:
Quote insertNonNTString("IX86"); // platform ID
Should be:
Quote insertNonNTString("68XI"); // platform ID
But you should really be handling them as the DWORDs they are.
~-~(HDX)~-~
The -1's that you're receving are indications that there were errors on the socket.
Hdx, thanks for the corrections, I realize you are right about those things. I'm still getting -1-1-1-1 from bnet when I print it out as ints. I implemented the packet header, btw, and the game protocol ID at the start. Here are the revisions to my Login and SidAuthInfo classes:
public class Login {
// Packets
private Packet sidAuthInfoSnd;
private Packet sidPing;
private Packet sidAuthInfoRcv;
// IO stuff
private BufferedReader reader;
private Socket sock;
private InputStream in;
private OutputStream out;
// command stuff
private char trigger = '/';
private enum Commands { CONNECT, DISC, QUIT }
public Login() {
Packet buff = new PacketBuffer();
reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println
("COMMANDS:" + "\n" +
"/CONNECT to connect" + "\n" +
"/DISC to disc" + "\n" +
"/QUIT to exit program" );
while (true) {
String text = null;
try {
text = reader.readLine();
}
catch (IOException e) {
System.out.println("ERROR!");
}
if (text != null && text.charAt(0) == trigger && text.toCharArray().length > 2) {
char[] chars = text.toCharArray();
char[] temp = new char[chars.length - 1];
for (int i = 0; i < temp.length; i++) {
temp[i] = chars[i + 1];
}
String cmd = new String(temp);
switch(Commands.valueOf(cmd.toUpperCase())) {
case CONNECT:
System.out.println("Connecting...");
connect();
break;
case DISC:
System.out.println("Disconnecting...");
disc();
break;
case QUIT:
disc();
System.exit(0);
default:
System.out.println("No Command.");
}
}
}
}
private void connect() {
// create IO objects
try {
sock = new Socket("useast.battle.net", 6112);
in = sock.getInputStream();
out = sock.getOutputStream();
}
catch(IOException e) {
System.out.println(e.toString());
return; // don't try to connect if there are no IO objects
}
//------
// Send protocol ID (0x01 = game protocol)
try {
out.write((byte) 0x01);
}
catch (IOException e) {
System.out.println("Unable to send protocol ID");
}
sidAuthInfoSnd = new SidAuthInfo();
try {
out.write(sidAuthInfoSnd.getRawData());
}
catch (IOException e) {
System.out.println(e.toString());
}
sidPing = rcvPing();
byte[] ping = sidPing.getRawData();
for (int i : new int[ping.length]) {
System.out.print(ping[i]);
}
System.out.print("\n");
seeRcvAuthInfo();
}
private void disc() {
}
private Packet rcvPing() {
Packet buff = new PacketBuffer((byte) 0x25, (byte) 4);
for (int i = 0; i < 4; i++) {
try {
buff.insertByte((byte)in.read());
}
catch (IOException e) {
System.out.println(e.toString());
}
}
return buff;
}
private void seeRcvAuthInfo() {
Thread t = new Thread(new Runnable() {
public void run() {
//-------
// after not rcving for 5 secs I seal packet
try {
sock.setSoTimeout(5000);
}
catch (SocketException e) {
System.out.println(e.toString());
}
//-----
//place the stuff I rcv into packet
Packet buff = new PacketBuffer();
boolean rcving = true;
while (rcving) {
try {
byte input = (byte) in.read();
buff.insertByte(input);
System.out.print((char)input); // just to see what i'm rcving as i'm rcving it
}
catch (SocketTimeoutException timeout) {
System.out.println("TIMEOUT!");
rcving = false;
}
catch (IOException e) {
System.out.println("ERROR RECEIVING SidAuthInfo");
break;
}
}
//---------
//disable timeout
try {
sock.setSoTimeout(0);
}
catch (SocketException e) {
System.out.println(e.toString());
}
//-------
//print out packet
byte[] data = buff.getRawData();
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]);
}
}
});
t.start();
}
/**
* @param args
*/
public static void main(String[] args) {
new Login();
}
}
public class SidAuthInfo extends PacketBuffer {
public SidAuthInfo() {
super((byte) 0x50); // message ID
insertDword((byte) 0x00); // protocol id
insertNonNTString("68XI"); // platform ID
insertNonNTString("PXES"); // product ID
insertDword(0xCD); // version byte
insertDword(0x00); // product language
insertDword(0x00); // local ip
insertDword(0x00); // time zone bias
insertDword(0x00); // locale id
insertDword(0x00); // language id
insertNTString("USA"); // country abbrev.
insertNTString("United States"); // country name
}
}
Nevermind, issue resolved. Thanks for your help guys.