Author Topic: [Java] Buffer Problems (Again)  (Read 4042 times)

0 Members and 1 Guest are viewing this topic.

Offline Lance

  • Full Member
  • ***
  • Posts: 129
    • View Profile
[Java] Buffer Problems (Again)
« on: July 17, 2008, 11:02:53 pm »
I have JavaOP2 receive packets (non-battle.net ones). I am currently modifying the core to meet my needs.

This works:
Code: [Select]
byte []packet = new byte[127];
                    input.read(packet);
but I have to specify the size which is completely inaccurate and it throws off my data by adding lots of 0x00's. I need a solution to this problem ;(

The traditional
Code: [Select]
int len1 = (input.read() & 0x000000FF);
                    int len2 = (input.read() & 0x000000FF) << 8;

int length = len1 | len2;

byte []packet = new byte[length];

for(int i = 0; i < packet.length; i++)
                        packet[i] = (byte)input.read();
results in my incoming packets not processing for some reason.

Ron said something about looping through each byte but I am still pretty new to java :p

Thanks :)
« Last Edit: June 22, 2010, 09:28:38 am by Lance »
Quote from: Joe
[23:55:31] [william@enterprise ~/Documents/Programming/javaop2]$ svn commit -m 'Tried to fix StayConnected. Again.'
Committed revision 63.
StayConnected strikes back!

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: [Java] Buffer Problems (Again)
« Reply #1 on: July 18, 2008, 01:38:03 am »
You should really be using a packet buffer for both incoming and outgoing packets. I already posted links to a detailed example of how I do it in my bot, so go check that out.

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline Lance

  • Full Member
  • ***
  • Posts: 129
    • View Profile
Re: [Java] Buffer Problems (Again)
« Reply #2 on: July 18, 2008, 05:45:32 pm »
Link to the links please? I searched through BNUBot support forums and your recent posts ;;
Quote from: Joe
[23:55:31] [william@enterprise ~/Documents/Programming/javaop2]$ svn commit -m 'Tried to fix StayConnected. Again.'
Committed revision 63.
StayConnected strikes back!

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: [Java] Buffer Problems (Again)
« Reply #3 on: July 19, 2008, 01:16:35 am »
It's one of the top two or three threads in this forum, and it isn't this one.

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline Lance

  • Full Member
  • ***
  • Posts: 129
    • View Profile
Re: [Java] Buffer Problems (Again)
« Reply #4 on: July 19, 2008, 10:24:26 am »
Quote from: Camel!
You can't use a Writer for binary data. Writers are to Streams as Strings are to byte arrays. You need to use byte arrays for binary data; if you Strings, you can be guaranteed that your code will work inconsistently in different environments.

Even if you use a Stream, Print* is still inappropriate for sockets (but not because it won't work). You should use a packet buffer to construct your packets and convert them to a byte[], and then write() that directly to the socket's OutputStream, thus making the write operation atomic, fault-resistant, and thread-safe.
That's it, right? :p

I have the Buffer class from JavaOP2 available but I have no idea how to use it for input streams :p
Quote from: Joe
[23:55:31] [william@enterprise ~/Documents/Programming/javaop2]$ svn commit -m 'Tried to fix StayConnected. Again.'
Committed revision 63.
StayConnected strikes back!

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: [Java] Buffer Problems (Again)
« Reply #5 on: July 20, 2008, 10:28:24 pm »
Here's how I do it; I'm not familiar with the JavaOp structure, but I assume it's similar since this is a pretty standard approach to the problem.

First, create a decorated class for input/output that can read/write the data types you're using. These are the ones I wrote: BNetInputStream, and BNetOutputStream.

Then, create packet buffers that operate on these streams: BNCSPacket, BNCSPacketReader. You can think of the former as BNCSPacketWriter; I simply never got around to refactoring it.

Finally, tie it all together with a socket: BNCSConnection.
« Last Edit: July 20, 2008, 10:31:19 pm by Camel »

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline Lance

  • Full Member
  • ***
  • Posts: 129
    • View Profile
Re: [Java] Buffer Problems (Again)
« Reply #6 on: July 21, 2008, 01:02:57 pm »
That's alot of extra code ;;
There isn't a shorter way to do this?
Quote from: Joe
[23:55:31] [william@enterprise ~/Documents/Programming/javaop2]$ svn commit -m 'Tried to fix StayConnected. Again.'
Committed revision 63.
StayConnected strikes back!

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: [Java] Buffer Problems (Again)
« Reply #7 on: July 21, 2008, 02:05:02 pm »
The whole point of those classes is so that you don't have to implement those methods inline, thus decreasing the size of your codebase overall by increasing reuse. Those BNet*Stream classes are extremely reusable; they're not bnet-specific, they're really just packet buffers. The BNCSPacket* classes are specifically built for BNCS, but can be easily modified for other binary protocols.

If you're referring to the BNCSConnection class, that's a complete implementation of BNCS, which necessitates hugeness. You will not need to use anything from there; I only provided it for reference as to how I use the other four classes. Reading and writing packets is extremely simple once you've built the boilerplate code; here's an excerpt from BNCSConnection:
Code: [Select]
p = new BNCSPacket(BNCSPacketId.SID_AUTH_INFO);
p.writeDWord(0); // Protocol ID (0)
p.writeDWord(PlatformIDs.PLATFORM_IX86); // Platform ID (IX86)
p.writeDWord(productID.getDword()); // Product ID
p.writeDWord(verByte); // Version byte
p.writeDWord(prodLang); // Product language
p.writeDWord(0); // Local IP
p.writeDWord(tzBias); // TZ bias
p.writeDWord(0x409); // Locale ID
p.writeDWord(0x409); // Language ID
p.writeNTString(loc.getISO3Country()); // Country abreviation
p.writeNTString(loc.getDisplayCountry()); // Country
p.SendPacket(bncsOutputStream);

Another example, this one reads SID_PING and replies with the same DWORD:
Code: [Select]
case SID_PING: {
BNCSPacket p = new BNCSPacket(BNCSPacketId.SID_PING);
p.writeDWord(is.readDWord());
p.SendPacket(bncsOutputStream);
break;
}
« Last Edit: July 21, 2008, 02:09:12 pm by Camel »

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline Lance

  • Full Member
  • ***
  • Posts: 129
    • View Profile
Re: [Java] Buffer Problems (Again)
« Reply #8 on: July 21, 2008, 04:55:58 pm »
I just want to get the raw byte data  :'(. Nothing more nothing less.
This isn't for BNet packets so, would a modified BNCSConnection excerpt still work properly?
Quote from: Joe
[23:55:31] [william@enterprise ~/Documents/Programming/javaop2]$ svn commit -m 'Tried to fix StayConnected. Again.'
Committed revision 63.
StayConnected strikes back!

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: [Java] Buffer Problems (Again)
« Reply #9 on: July 21, 2008, 07:30:24 pm »
The packet buffers exist because you can't determine how long the packet is going to be until you've finished writing it, yet the length word is at the beginning of the packet.

The decorated I/O streams are for reading/writing various types. The base InputStream and OutputStream provide methods for reading/writing a single byte already.

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!