Valhalla Legends Forums Archive | Java Programming | Buffer Help

AuthorMessageTime
Spilled[DW]
Hey guys i need help once again so heres my problem. i need to know if im doing the buffer wrong inside my InsertDWORD, InsertWORD, nt , nonnt all that wrong. Also im not converting the characters in the insertnonnt and nt string functions right cuz im getting 0x00... Also what outputStream would you guys recommend? I am currently using DataOutputStream ... Well heres the code any ideas would be very appreciated!

Connection.java -
[code]
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
public class Connection extends Thread {
private Socket wSock;
private byte[] buffer = new byte[0];
private int bufferpos = 0;
private MenuFrame menuFrame = null;
private DataOutputStream out = null;

/*
* new contructor that gets passed the right menu frame
*/
public Connection(MenuFrame aMenuFrame) {
menuFrame = aMenuFrame;
}

public void run()
{
//useast.battle.net = 63.240.202.129
//asia.battl.net = 211.233.0.80
String server = "211.233.0.80";
int port = 6112;
System.out.println("he dizzle");
/*
* move the calls to create the socket out of the loop
* so we only do it once.
* we also move the buffered reader so we dont keep
* re-assigning it
*/
BufferedInputStream inData;
try {
wSock = new Socket(server, port);
menuFrame.addChat("[wSock] - connected to " + wSock);
inData = new BufferedInputStream(wSock.getInputStream());
} catch(Exception e) {
menuFrame.addChat("Error connecting to host - " + e);
return;
}
try
{
out = new DataOutputStream(wSock.getOutputStream());
SendPacket0x50();
}catch(IOException e)
{
System.out.println("ERROR!");
}

while(true) {
try {
/*
* this will wait for the client to send data, or if they disconnect
* it will return -1
*/
int firstByte = inData.read();
if(firstByte == -1) {
/*
* this 'break' will exit our read 'while(true)' loop
*/
//g.drawString("die!", 60, 70);
menuFrame.addChat("connection lost");
break;
}else{
byte[] data = new byte[inData.available() + 1];
data[0] = (byte)firstByte;
inData.read(data, 1, data.length-1);
String strData = new String(data);
// g.drawString("battle.net sent [" + strData + "]", 60, 70);
menuFrame.addChat("got: " + strData);

/*
* here we have removed the close connection, and instead wait for
* the server to close the connection.
*/
//wSock.close();
}
} catch(Exception e) {
//g.drawString("Error: " + e, 100, 110);
menuFrame.addChat("Error: " + e);
break;
}
}
/*
* at this point the server has closed the connection
* or an error has occured and you can perform post-connection
* operations
*/
menuFrame.addChat("[wSock] - Connection lost...");
}

private void SendPacket0x50()
{
//InsertDWORD(0);
InsertNonNTString("68XIPXES"); // testing to see if works right first
//InsertBYTE((int)0xCD);
//InsertDWORD(0);
//InsertDWORD(0);
//InsertDWORD(0);
//InsertDWORD(0);
//InsertDWORD(0);
//InsertNTString("USA");
//InsertNTString("United States");
SendPacket(0x50);
}

private void InsertBYTE(int b)
{
buffer = new byte[bufferpos+1];
buffer[bufferpos++] = (byte)b;
}
private void InsertDWORD(int dword)
{
buffer = new byte[bufferpos+4];
buffer[bufferpos++] = (byte)((dword & 0x000000FF) >> 0);
buffer[bufferpos++] = (byte)((dword & 0x0000FF00) >> 8);
buffer[bufferpos++] = (byte)((dword & 0x00FF0000) >> 16);
buffer[bufferpos++] = (byte)((dword & 0xFF000000) >> 24);
}
private void InsertWORD(int word)
{
   buffer = new byte[bufferpos+2];
       buffer[bufferpos++] = (byte) ((word & 0x00FF) >> 0);
       buffer[bufferpos++] = (byte) ((word & 0xFF00) >> 8);
}
private void InsertNonNTString(String str)
{
buffer = new byte[bufferpos+str.length()];
int ascii = 0;
for(int i = 0; i < str.length(); i++)
{
ascii = (int)str.charAt(i);
buffer[bufferpos++] = (byte)ascii;
}
/*
char array[]={'a','b','c','d'}; // suppose this is our array of char
String str=new String(array);// converting char[] into string
byte barray[]=str.getBytes(); //converting string into byte
*/
}
private void InsertNTString(String str)
{
buffer = new byte[bufferpos+str.length()+1];
for(int i = 0; i < str.length(); i++)
{
buffer[bufferpos++] = (byte)str.charAt(i);
}
buffer[bufferpos++] = (byte) 0;
}
private void SendPacket(int PacketID)
{
byte[] header;
try
{
if(PacketID == 0x50)
{
/*header = new byte[buffer.length+5];
header[0] = (byte)0x01;
header[1] = (byte)0xFF;
header[2] = (byte)PacketID;
int he = buffer.length + 4;
header[3] = (byte)((he & 0x00FF) >> 0);
header[4] = (byte)((he & 0xFF00) >> 8);

for(int i = 5; i < buffer.length+5; i++)
{
int f = 0;
header[i] = buffer[f];
f++;
}

*/
out.write(buffer, 0, buffer.length); // just seeing if its inserting the string right.
}else{


header = new byte[buffer.length+4];
header[0] = (byte)0xFF;
header[1] = (byte)PacketID;
int he = buffer.length + 4;
header[2] = (byte)((he & 0x00FF) >> 0);
header[3] = (byte)((he & 0xFF00) >> 8);

for(int i = 4; i < buffer.length+4; i++)
{
int f = 0;
header[i] = buffer[f];
f++;
}
}

//out.write(header, 0, header.length);
}catch(IOException e)
{
menuFrame.addChat("[Error] - Error sending packet! - " + e);
}
}
}

[/code]

Thanks in advance!!
October 5, 2005, 6:12 AM
gameschild
For a start you are constantly erasing all your buffer with:
[code]
buffer = new byte[bufferpos+1];
[/code]

Anything that was in the old buffer is gone, and all the new data is stuck at the end.
If you do use this method look at using System.arraycopy() so you create the buffer, copy the old contents over, then add the new data.
October 5, 2005, 11:40 AM
Spilled[DW]
I am having more problems with recieving packets. When i send my 0x50 they send the 0x25 and the 0x50 Response together and was seeking some help in splitting them because the things i have tried were unsuccessfull.
Heres is my recieving code:

[code]
}else{
    byte[] data = new byte[inData.available() + 1];
    data[0] = (byte)firstByte;
    inData.read(data, 1, data.length-1);

  String strData = new String(data);
  PaRsEp(strData);
[/code]

Thanks in advance!
October 6, 2005, 8:04 PM
Dynobird
I think you're going about it the wrong way. It needs to be better organized =-p

Here's the way I did (and am doing) it:
You have a basic Packet class that defines methods for adding bytes, retrieving specific bytes, and retrieving the whole buffer.
This Packet class will have a data structure in it to hold all the bytes. It can be a Vector, ArrayList, LinkedList... whatever floats your boat... but make it a GROWABLE array that doesn't have a set size. Then, when you want to retrieve the Packet, you have a method that returns an array of bytes which represents your data structure. Note that these data structures take objects, so when you're turning them into bytes, you first have to cast them into Byte objects and then get then make a byte out of the Byte.

For your insertWORD and insertDWORD methods you can either put them in your Packet class or make a PacketBuffer class that extends/embeds Packet and has all these methods. This new class (or the Packet class if you're doing the former) will be using the Packet class's addByte method and also will have its own (if its a new class) method which can just return a method call of Packet's getPacket method in order to get the array of bytes.

Then all of the classes for your specific packets will either extend/embed the PacketBuffer/Packet class. These classes, lets take SID_AUTH_INFO (0x50) for example, will call all of the insertWORD, insertDWORD, insertString/NTString etc. methods in order to create their own Packet data. Then you return their respective array of bytes, and either send it in a main class or their own respective classes

This is not a new idea, but it's a good design pattern. I myself am thinking about making a PacketDebuffer class in which I can send it a Packet and then call methods which return a word or a dword given the specified interval in its array of bytes. I actually haven't gotten that far in making my battle.net bot I keep getting sidetracked by other fun things but for OSCAR protocol this is especially useful when you have to receive a SNAC ID and some other things like decryption keys.

Oh, and I'm not sure if you have to make each Packet a new thread from the class that you are sending it in... I did that for receiving/sending after I enter a channel (like, you could start these threads after you send SID_ENTERCHAT) but having a lot of threads eats up computer time even though it does allow your program to run parallel tasks. Also, when your sending your packets you're really only sending one at a time before SID_ENTERCHAT so there's no need to make new threads for the logon sequences IMO.
October 10, 2005, 12:27 AM

Search