Valhalla Legends Forums Archive | Battle.net Bot Development | Good place to start

AuthorMessageTime
RyanIdium
Hello. Im sure you get alot of these, but now you get another!
Im begining to see how some of these bots work (without cleanslatebot). Im just wondering what a good way to send these packets to a server in Delphi. I am currently using TClientSocket and its SendText function, adding what i need with chr($47) or whatnot.
Thanks in advance.
December 7, 2003, 11:14 PM
Arta
Have some free code (aren't I nice). gogo Delphi programmers!

This is a multipurpose packet buffer I wrote a long time ago. I have no idea what weird strange things might be in there. The GetPacket() function returns a string you can pass to SendText(). I'd suggest removing the things specific to botnet or MCP until you need them.

[code]
unit TPacketBufferUnit;

interface

uses windows, dialogs, sysutils;

type
TPacketBuffer = class
public
procedure AddByte(Data: byte);
procedure AddWord(Data: word);
procedure AddDword(Data: int64);
procedure AddString(Data: string; nullterm: boolean = true);
procedure ClearBuffer;
procedure Print;
function GetPacket(ID: byte; magicbyte: byte=1): string;

constructor create(usebotnet: boolean=false; bnProtocol: byte=0; inagame: boolean=false; Realm: boolean=false);

private
Buffer: string;
protocol: byte;
onbotnet, OnRealm, ingame: boolean;
end;

implementation
uses MainUnit, TBotnetUnit;


constructor TPacketBuffer.create(usebotnet: boolean=false; bnProtocol: byte=0; inagame: boolean=false; Realm: boolean=false);
begin
Buffer:='';
protocol:=bnProtocol;
onbotnet:=usebotnet;
ingame:=inagame;
OnRealm:=realm;
end;

procedure TPacketBuffer.Print;
var i: integer;
bytestream: string;
begin
bytestream:=#9;
for i:=1 to length(buffer) do
begin
bytestream:=bytestream+inttohex(byte(buffer[i]), 2)+#32;
if (i mod 16)=0 then bytestream:=bytestream+#13#10#9;
end;

main.Display(SENDER_BNET, 'Displaying Current Packet: '#13#10+bytestream, bnWhite);
end;

procedure TPacketBuffer.AddByte(Data: byte);
begin
Buffer:=Buffer+char(Data);
end;

procedure TPacketBuffer.AddWord(Data: word);
var tmp: string[2];
begin
tmp:=char( Data and $00FF ) + char((Data and $FF00) shr 8);
// showmessage(inttohex(byte(tmp[1]), 2)+' '+inttohex(byte(tmp[2]), 2));
Buffer:=Buffer+Tmp;
end;

procedure TPacketBuffer.AddDword(Data: int64);
var tmp: string[4];
begin
tmp:=char( Data and $FF ) + char((Data and $FF00) shr 8) + char( (Data and $FF0000) shr 16) + char( (Data and $FF000000) shr 24);
Buffer:=Buffer+Tmp;
end;

procedure TPacketBuffer.AddString(Data: string; nullterm: boolean = true);
begin
Buffer:=Buffer+Data;
if nullterm then Buffer:=Buffer+#0;
end;

procedure TPacketBuffer.ClearBuffer;
begin
Buffer:='';
end;

function TPacketBuffer.GetPacket(ID: byte; magicbyte: byte=1): string;
var PacketLen: word;
tmp: string[2];
begin

if ingame then
begin
PacketLen:=length(Buffer)+2;
tmp:=char( PacketLen and $FF ) + char((PacketLen and $FF00) shl 8);
result:=tmp+Buffer
end
else if onbotnet then
begin
PacketLen:=length(Buffer)+4;
tmp:=char( PacketLen and $FF ) + char((PacketLen and $FF00) shl 8);

result:=char(magicbyte)+char(ID)+tmp+Buffer
end
else if OnRealm then
begin
PacketLen:=length(Buffer)+3;
tmp:=char( PacketLen and $FF ) + char((PacketLen and $FF00) shl 8);
result:=tmp+char(ID)+Buffer
end
else
begin
PacketLen:=length(Buffer)+4;
tmp:=char( PacketLen and $FF ) + char((PacketLen and $FF00) shl 8);
result:=#$FF+char(ID)+tmp+Buffer;
end;

// BotNet.DisplayPacketStr(result);

ClearBuffer;
end;

end.
[/code]

You'll probably run into problems when you need functions such as HashData and CheckRevision. To my knowledge, no one has translated these to Delphi except me, and if they have, I'm fairly sure they haven't been publicly released. Assuming you're not a total beginner and that you know some C, it shouldn't be too hard to translate code that is available.
December 8, 2003, 4:35 AM
Arta
...and this is a receive buffer. When you get data on your socket, call AddData. CheckPacket returns true when a complete packet is available. GetPacket can be used to remove it from the buffer for processing. Again, this is multipurpose - you might want to remove the non-BNCS stuff.

[code]
unit TRecieveBufferUnit;

interface

uses SysUtils, Dialogs, MiscFuncs;

type



TRecieveBuffer = class
public
Buffer, RealmBuffer: string;

procedure AddData(Data: string);
function CheckBuffer: boolean;
function GetPacket: Packet;

procedure AddRealmData(Data: string);
function CheckRealmBuffer: boolean;
function GetRealmPacket: Packet;

constructor create(useProtocol: byte);


private

protocol: byte;

end;

implementation

constructor TRecieveBuffer.create(useProtocol: byte);
begin
Buffer:='';
RealmBuffer:='';
protocol:=useProtocol;
end;

procedure TRecieveBuffer.AddData(Data: string);
begin
Buffer:=Buffer+Data;
end;

function TRecieveBuffer.CheckBuffer: boolean;
var PacketLen: word;
begin
Result:=false;
if (length(Buffer)>0) and (Buffer[1]=char(protocol)) then
begin
PacketLen:=byte(Buffer[3])+( (byte(Buffer[4]) and $FF00) shl 8);
if length(Buffer) >= PacketLen then result:=true;
end;
end;

function TRecieveBuffer.GetPacket: Packet;
begin
if Buffer[1]=char(protocol) then
begin
result.header:=copy(Buffer, 1, 4);
result.ID:=byte(Buffer[2]);
result.Length:=(byte(Buffer[4]) shl 8) + byte(Buffer[3]);
result.data:=copy(Buffer, 5, result.length-4);

Delete(Buffer, 1, result.length);
end
else
result.ID:=-1;
end;

function TRecieveBuffer.CheckRealmBuffer: boolean;
var PacketLen: word;
begin
Result:=false;
if (length(RealmBuffer)>0) then
begin
PacketLen:=byte(RealmBuffer[2])+( (byte(RealmBuffer[3]) and $FF00) shl 8);
if length(RealmBuffer) >= PacketLen then result:=true;
end;
end;

procedure TRecieveBuffer.AddRealmData(Data: string);
begin
RealmBuffer:=RealmBuffer+Data;
end;

function TRecieveBuffer.GetRealmPacket: Packet;
begin
result.header:=copy(RealmBuffer, 1, 3);
result.ID:=byte(RealmBuffer[3]);
result.Length:=(byte(RealmBuffer[2]) shl 8) + byte(RealmBuffer[1]);

if result.length>length(RealmBuffer) then
begin
result.id:=-1;
Delete(RealmBuffer, 1, Result.Length);
exit;
end;

result.data:=copy(RealmBuffer, 4, result.length-3);

Delete(RealmBuffer, 1, result.length);
end;

end.
[/code]
December 8, 2003, 4:38 AM
CrAzY
[quote author=RyanIdium link=board=17;threadid=4135;start=0#msg34189 date=1070838868]
chr($47)
[/quote]

Weird... String with a Int Name...
December 8, 2003, 8:29 PM
St0rm.iD
[quote][black]Just trying to get a rise out of you.[/black][/quote]

Maybe because it's fucking delphi, douchbag.
December 8, 2003, 8:34 PM
RyanIdium
Thanks! i wont rip you off (and just take it), but ill look at it a bit and figure out what your getting at.
December 8, 2003, 10:23 PM
Arta
good :)
December 9, 2003, 2:12 AM
RyanIdium
There is one thing i have a question about though. It has to deal with the addition of a DWord. Now i think i know what it is (an un-allocated(sp?) integer), but im kindof confused on the rest of the code.

[code]
procedure TPacketBuffer.AddDWord(data : int64);
var tmp: string[4];
begin
tmp:=char( Data and $FF ) + char((Data and $FF00) shr 8) + char( (Data and $FF0000) shr 16) + char( (Data and $FF000000) shr 24);
Buffer:=Buffer+Tmp;
end;
[/code]
now lets see here..

tmp = stores the string version of DWord.
char() = converts hex to ascii
and $FF = your using $FF with data (can you use + also?)
shr = shift hex right, not clear on why its needed though :-/
buffer = cant be the buffer! :P
December 9, 2003, 3:31 AM
Arta
The shifting and anding converts it to the correct byte ordering.
char() takes a number and returns the ascii equivalent.
I had to make data an int64 to avoid some annoying error (lazy fix)

I'm not sure what your question is! You said you didn't understand and then explained it :P
December 10, 2003, 3:42 AM
RyanIdium
[quote author=Arta[vL] link=board=17;threadid=4135;start=0#msg34556 date=1071027746]
The shifting and anding converts it to the correct byte ordering.
char() takes a number and returns the ascii equivalent.
I had to make data an int64 to avoid some annoying error (lazy fix)

I'm not sure what your question is! You said you didn't understand and then explained it :P
[/quote]
what i thought i did was tell (or try to) what i 'think' i know. guess i should have said that :P

thanks again! (hopefully i wont have to ask anymore questions)
December 10, 2003, 9:26 PM

Search