Бот для кача и спойла. v1.2
Возможности
-сам качается
-ищет ближайшего моба
-спойлит\свипает (1.1)
-подбирает вещи
-садится при 45%хп, встает при 95%
-пьет банки при 30%хп (1.2)
-если во время боя напал другой моб, бьем его а не ближайшего (1.2)
-если долго не убили ни одного моба ищем следующего (1.1)
-лог в приват чат
-на пользовательской вкладке инвентарь, окрестные мобы и монитор хп/мп/цп
В разработке
-обход препятствий (ожидается в 1.3)
-атака агрессивных первыми (ожидается в 1.5)
-атака только одиночных мобов (ожидается в 1.5)
-движение по маршруту (ожидается в 1.4)
-покупка лечилок в городе (ожидается в 1.6)
-аутгейм режим (ожидается в 2.0)
-манор (ожидается в 1.3)
delphi Код:
{
Бот для кача и спойла. v1.2
Возможности
-сам качается
-ищет ближайшего моба
-спойлит\свипает (1.1)
-подбирает вещи
-садится при 45%хп, встает при 95%
-пьет банки при 30%хп (1.2)
-если во время боя напал другой моб, бьем его а не ближайшего (1.2)
-если долго не убили ни одного моба ищем следующего (1.1)
-лог в приват чат
-на пользовательской вкладке инвентарь, окрестные мобы и монитор хп/мп/цп
В разработке
-обход препятствий (ожидается в 1.3)
-атака агрессивных первыми (ожидается в 1.5)
-атака только одиночных мобов (ожидается в 1.5)
-движение по маршруту (ожидается в 1.4)
-покупка лечилок в городе (ожидается в 1.6)
-аутгейм режим (ожидается в 2.0)
-манор (ожидается в 1.3)
Ошибки
-атакет мобов под текстурами
-упирается в стены
-ошибка, если запустить после входа в мир
-ошибка если атаковать (или поднять) сидящего
-знает не всех мобов и вещи
-не ограничена область кача
-после смерти ничего не делает
Использование:
-на экране выбора чаров ставим галку на скрипт
-убираем галку "сохранять пакеты"
-входим в игру
-жмем Yes
}//******************************************//******************************************//служебные константы//******************************************//******************************************const
OID=0;
atk=1;
id=2;
x=3;
y=4;
z=5;
CHP=6;
MHP=7;
//******************************************//******************************************//переменные//******************************************//******************************************var
State, Log, Inv, Npc:TMemo;
Search, Avard:TTimer;
CurHP,CurMP, MaxHP, MaxMP, MaxCP, CurCP:Integer;
MyX,MyY,MyZ,MyID:Integer;
Name:String;
i:integer;
Inventory: Array[0..79,0..9] ofinteger; // инвентарь (itemType1, ObjectID, ItemID, count, itemType2, CustType1, isEquipped, BodyPart, EnchantLevel, CustType2)
Mob:Array [0..100,0..7] ofinteger;
target, lasttarget:integer;
sitting:boolean;
Battle:Array[0..11] ofinteger;
//******************************************//******************************************//служебные функции//******************************************//******************************************//******************************************//количество атакующих нас мобов//******************************************function BattleCount:integer;
var
i, count:integer;
begin
count:=0;
for i:=0to10dobeginifNOT(Battle[i]=0)then count:=count+1;
end;
Result:=count;
end;
//******************************************//удалить из списка атакующих//******************************************procedure DelBattle(id:integer);
var
i:integer;
beginfor i:=0to10dobeginif(Battle[i]=id)thenbegin
Battle[i]:=0;
exit;
end;
end;
end;
//******************************************//добавить в список атакующих//******************************************procedure AddBattle(id:integer);
var
i:integer;
beginfor i:=0to10dobeginif(Battle[i]=0)thenbegin
Battle[i]:=id;
exit;
end;
end;
end;
//******************************************//выбрать атакующего//******************************************function BattleSel:integer;
var
i, id:integer;
begin
id:=0;
for i:=0to10dobeginifNOT(Battle[i]=0)thenbegin
id:=Battle[i];
break;
end;
end;
Result:=id;
end;
//******************************************//атака//******************************************procedure Attack(id:integer);
beginif(id>-1)thenbegin
SendMsg('Бьем гада');
SendAction(id);
spoil;
SendAction(id);
end;
end;
//******************************************//сесть//******************************************procedure sit;
begin
buf:=#$45;
WriteD(0);
WriteD(0);
buf:=buf+#$00;
SendToServer;
sitting:=NOT sitting;
end;
//******************************************//споил//******************************************procedure spoil;
begin
buf:=#$2f;
WriteD(254);
WriteD(0);
buf:=buf+#$00;
SendToServer;
end;
//******************************************//свипер//******************************************procedure sweeper;
begin
buf:=#$2f;
WriteD(42);
WriteD(0);
buf:=buf+#$00;
SendToServer;
end;
//******************************************//сообщение в чат//******************************************procedure SendMsg(str:string);
begin
buf:=#$4A;
WriteD(0);
WriteD(2);
WriteS('BOT');
WriteS(str);
SendToClient;
end;
//******************************************//название вещи//******************************************function ItemName(id:integer):string;
varstr:string;
beginstr:=IntToStr(id);
case id of57: str:='Adena';
727: str:='Healing Potion';
1060: str:='Lesser Healing Potion';
1864: str:='Stem';
1865: str:='Varnish';
1866: str:='Suede';
1867: str:='Animal Skin';
1868: str:='Thread';
1869: str:='Iron Ore';
1870: str:='Coal';
1871: str:='Charcoal';
1872: str:='Animal Bone';
1873: str:='Silver Nugget';
1874: str:='Oriharukon Ore';
1875: str:='Stone of Purity';
1876: str:='Mithril Ore';
1877: str:='Adamantite Nugget';
1878: str:='Braided Hemp';
1879: str:='Cokes';
1880: str:='Steel';
1881: str:='Coarse Bone Powder';
1882: str:='Leather';
1883: str:='Steel Mold';
1884: str:='Cord';
1885: str:='High Grade Suede';
1886: str:='Silver Mold';
1887: str:='Varnish of Purity';
1888: str:='Synthetic Cokes';
1889: str:='Compound Braid';
1890: str:='Mithril Alloy';
1891: str:='Artisan Frame';
1892: str:='Blacksmiths Frame';
1893: str:='Oriharukon';
1894: str:='Crafted Leather';
1895: str:='Metallic Fiber';
end;
Result:=str;
end;
//******************************************//имя моба//******************************************function NpcName(id:integer):string;
varstr:string;
beginstr:=IntToStr(id);
case id of1000317: str:='Black Wolf';
1000327: str:='Goblin Snooper';
1000322: str:='Goblin Bridgand';
1000307: str:='Garum Werewolf';
1000447: str:='Utuku Orc Archer';
end;
Result:=str;
end;
//******************************************//получение мнформации о вещи//******************************************function GetInv(obj,up,down:integer): integer; // up и down не проверяютсяvar// 0-itemType1, 1-ObjectId, 2-ItemID, 3-count, 4-itemType2, 5-CustType1, 6-isEquipped, 7-BodyPart, 8-EnchantLevel, 9-CustType2
i: integer;
beginfor i:=0to79doif(Inventory[i,up]=obj)thenbegin
Result:=Inventory[i,down];
exit;
end;
Result:=-1;
end;
//******************************************//использовать вещь//******************************************procedure UseItem(ItemObjID,shift:integer);
begin
buf:=#$14;
WriteD(ItemObjID);
WriteD(shift);
SendToServer;
end;
//******************************************//поиск ближаишего к нам моба//******************************************function NearestMob:integer;
var
i, min:integer;
mdist,dist: Double;
begin
mdist:=3600000;
min:=-1;
for i:=0to100dobeginif(Mob[i,OID]>0)thenbeginif(Mob[i,Atk]=1)thenbegin
dist:=((Mob[i,x]-MyX)*(Mob[i,x]-MyX))+((Mob[i,y]-MyY)*(Mob[i,y]-MyY))+((Mob[i,z]-MyZ)*(Mob[i,z]-MyZ));
if(dist<mdist)thenbegin
mdist:=dist;
min:=i;
end;
end;
end;
end;
Result:=min;
end;
//******************************************//отправка пакета action(таргет атака и подбор вещи)//******************************************procedure SendAction(id:integer);
var
i:integer;
begin
buf:=#$04;
WriteD(id);
WriteD(MyX);
WriteD(MyY);
WriteD(MyZ);
buf:=buf+#$00;
SendToServer;
target:=-1;
for i:=0to100dobeginif(Mob[i,OID]=id)thenbegin
target:=i;
lasttarget:=id;
break;
end;
end;
StateShow;
end;
//******************************************//******************************************//таймеры//******************************************//******************************************//******************************************//основной таймер//******************************************procedure OnSearch;
var
id:int;
beginif((CurHP*100DIV MaxHP)<40)ANDNOT(sitting)AND Search.Enabledthenbegin
delay(100);
sit;
exit;
end;
Avard.Enabled:=false;
Avard.Enabled:=True;
SendMsg('Выбираем цель');
id:=NearestMob;
Attack(Mob[id,OID]);
Search.Enabled:=False;
end;
//******************************************//аварийный таймер, если долго ничего не происходило//******************************************procedure OnAvard;
begin
SendMsg('Долгая пауза!Рестарт скрипта!');
Search.Enabled:=true;
end;
//******************************************//******************************************//Инициализация и освобождение ресурсов//******************************************//******************************************procedure Init; //Вызывается при включении скриптаbegin
ShowTab;
State:=TMemo.Create(UserTab);
State.parent:=UserTab;
State.align:=alRight;
State.ReadOnly:=true;
State.ScrollBars:=2;
State.Width:=100;
State.Height:=100;
Inv:=TMemo.Create(UserTab);
Inv.parent:=UserTab;
Inv.align:=alLeft;
Inv.ReadOnly:=true;
Inv.ScrollBars:=2;
Inv.Width:=180;
Inv.Height:=100;
Npc:=TMemo.Create(UserTab);
Npc.parent:=UserTab;
Npc.align:=alLeft;
Npc.ReadOnly:=true;
Npc.ScrollBars:=2;
Npc.Width:=180;
Npc.Height:=100;
Log:=TMemo.Create(UserTab);
Log.parent:=UserTab;
Log.align:=alBottom;
Log.ReadOnly:=true;
Log.ScrollBars:=2;
Log.Width:=100;
Log.Height:=100;
Log.Lines.Add('...');
CurHP:=0;
CurMP:=0;
MaxHP:=0;
MaxMP:=0;
target:=-1;
sitting:=false;
StateShow;
Search:=TTimer.Create(nil); // создаем таймеры
Search.OnTimer:=@OnSearch;
Search.enabled:=false;
Search.Interval:=2000;
Avard:=TTimer.Create(nil); // создаем таймеры
Avard.OnTimer:=@OnAvard;
Avard.enabled:=false;
Avard.Interval:=50000;
for i:=0to100dobegin
mob[i,0]:=0;
end;
for i:=0to10dobegin
Battle[i]:=0;
end;
end;
procedure Free; //Вызывается при выключении скриптаbegin
HideTab;
State.Free;
Log.Free;
Inv.Free;
Npc.Free;
Search.Enabled:=False;
Search.Free;
Avard.Enabled:=false;
Avard.free;
end;
//******************************************//******************************************//Обработка пакетов//******************************************//******************************************procedure InitStats;
var
i: integer;
begin
MyID:=ReadD(18);
MyX:=ReadD(2);
MyY:=ReadD(6);
MyZ:=ReadD(10);
i:=22;
Name:=ReadS(i);
i:=i+44;
MaxHP:=ReadD(i);
CurHP:=ReadD(i);
MaxMP:=ReadD(i);
CurMP:=ReadD(i);
i:=i+363;
MaxCP:=ReadD(i);
CurCP:=ReadD(i);
end;
procedure StatsUpdate;
var
i: integer;
beginfor i:=0to ReadD(6)-1docase pck[i*8+10] of
#$09: CurHP:=ReadD(i*8+14);
#$0A: MaxHP:=ReadD(i*8+14);
#$0B: CurMP:=ReadD(i*8+14);
#$0C: MaxMP:=ReadD(i*8+14);
#$21: CurCP:=ReadD(i*8+14);
#$22: MaxCP:=ReadD(i*8+14);
end;
if((CurHP*100DIV MaxHP)>95)AND sitting thenbegin
sit;
Search.Enabled:=true;
end;
if((CurHP*100DIV MaxHP)<30)thenbegin
SendMsg('Пьем банку');
UseItem(GetInv(1060,2,1),0);
end;
StateShow;
end;
procedure CorsUpdate;
begin
MyX:=ReadD(2);
MyY:=ReadD(6);
MyZ:=ReadD(10);
StateShow;
end;
procedure InventoryCreate;
var
i,k: integer;
beginfor i:=0to79doif(i<ReadH(4))thenbegin
Inventory[i,0]:=ReadH(i*28+6); // itemType1
Inventory[i,1]:=ReadD(i*28+8); // ObjectId
Inventory[i,2]:=ReadD(i*28+12); // ItemID
Inventory[i,3]:=ReadD(i*28+16); // count
Inventory[i,4]:=ReadH(i*28+20); // itemType2
Inventory[i,5]:=ReadH(i*28+22); // CustType1
Inventory[i,6]:=ReadH(i*28+24); // isEquipped
Inventory[i,7]:=ReadD(i*28+26); // BodyPart
Inventory[i,8]:=ReadH(i*28+30); // EnchantLevel
Inventory[i,9]:=ReadH(i*28+32); // CustType2endelsefor k:=0to9do Inventory[i,k]:=0; // забиваем нулями
InvShow;
end;
procedure InventoryUpdate;
var
i,j,k: integer;
beginfor j:=0to(ReadH(2)-1)dobegincase pck[j*30+4] of
#$01: k:=0; // add item, запишет на пустую ячейку
#$02: k:=ReadD(j*30+8); // mod item
#$03: begin// remove item, обнулит ячейки удаленного предмета
k:=ReadD(j*30+8);
for i:=0to79doif(Inventory[i,0]=k)thenbeginfor k:=0to9do Inventory[i,k]:=0;
exit;
end;
end;
end;
for i:=0to79doif(Inventory[i,1]=k)thenbegin
Inventory[i,0]:=ReadH(j*30+6); // itemType1
Inventory[i,1]:=ReadD(j*30+8); // ObjectId
Inventory[i,2]:=ReadD(j*30+12); // ItemID
Inventory[i,3]:=ReadD(j*30+16); // count
Inventory[i,4]:=ReadH(j*30+20); // itemType2
Inventory[i,5]:=ReadH(j*30+22); // CustType1
Inventory[i,6]:=ReadH(j*30+24); // isEquipped
Inventory[i,7]:=ReadD(j*30+26); // BodyPart
Inventory[i,8]:=ReadH(j*30+30); // EnchantLevel
Inventory[i,9]:=ReadH(j*30+32); // CustType2break;
end;
end;
InvShow;
end;
procedure NpcInfo;
var
mid, matk, mx, my, mz, mtype:integer;
i:integer;
begin
i:=2;
mid:=ReadD(i);
mtype:=ReadD(i);
matk:=ReadD(i);
mx:=ReadD(i);
my:=ReadD(i);
mz:=ReadD(i);
for i:=0to100dobeginif(Mob[i,OID]=mid)thenbegin
Mob[i,OID]:=0;
{if(target=i) then begin
target:=-1;
end;}break;
end;
end;
for i:=0to100dobegin//if(mob[i,OID]=mid) then mob[i,OID]:=0;if(mob[i,OID]=0)thenbegin
mob[i,OID]:=mid;
mob[i,atk]:=matk;
mob[i,id]:=mtype;
mob[i,x]:=mx;
mob[i,y]:=my;
mob[i,z]:=mz;
mob[i,CHP]:=0;
mob[i,MHP]:=0;
break;
end;
end;
ShowNpc;
end;
procedure Action;
var
id:integer;
act:integer;
i:integer;
begin
id:=ReadD(2);
target:=-1;
for i:=0to100dobeginif(Mob[i,OID]=id)thenbegin
target:=i;
lasttarget:=id;
break;
end;
end;
StateShow;
end;
procedure DeleteObject;
var
i, id:integer;
begin
id:=ReadD(2);
DelBattle(id);
for i:=0to100dobeginif(Mob[i,OID]=id)thenbegin
Mob[i,OID]:=0;
if(target=i)thenbegin
target:=-1;
Search.Enabled:=true;
end;
break;
end;
ShowNpc;
end;
end;
procedure Die;
var
i, id:integer;
begin
id:=ReadD(2);
for i:=0to100dobeginif(Mob[i,OID]=id)thenbegin
Mob[i,Atk]:=-1;
if(lasttarget=id)thenbegin
SendMsg('Убили гада');
DelBattle(id);
Avard.Enabled:=false;
Avard.Enabled:=True;
delay(100);
sweeper;
SendMsg('Еще в битве:'+IntToStr(BattleCount));
if(BattleCount=0)then Search.Enabled:=trueelsebegin
Attack(BattleSel);
end;
end;
break;
end;
ShowNpc;
end;
end;
procedure MoveToLocation;
var
i, id, cx,cy,cz,dx,dy,dz:integer;
begin
i:=2;
id:=ReadD(i);
cx:=ReadD(i);
cy:=ReadD(i);
cz:=ReadD(i);
dx:=ReadD(i);
dy:=ReadD(i);
dz:=ReadD(i);
for i:=0to100dobeginif(Mob[i,OID]=id)thenbegin
Mob[i,x]:=dx;
Mob[i,y]:=dy;
Mob[i,z]:=dz;
break;
end;
//ShowNpc;end;
end;
procedure DropItem;
var
pid, iid,i:integer;
begin
i:=2;
pid:=ReadD(i);
iid:=ReadD(i);
if(lasttarget>-1)thenbegin//Log.Lines.Add(IntToStr(Mob[target,OID])+' '+IntToStr(pid));if(pid=lasttarget)thenbegin
Log.Lines.Add('Try pickup');
SendMsg('Выпала вещь');
delay(1000);
SendAction(iid);
Log.Lines.Add('Try pickup');
SendMsg('Пытаюсь поднять');
end;
end;
end;
procedure UnderAttack;
var
id, target,i:integer;
begin
i:=2;
id:=ReadD(i);
target:=ReadD(i);
if(target=MyID)thenbegin
DelBattle(id);
AddBattle(id);
end;
end;
//******************************************//******************************************//заготовка под аутгейм//******************************************//******************************************procedure ShowNpc;
var
i:integer;
str:string;
begin
Npc.Lines.Clear;
for i:=0to100dobeginifNOT(mob[i,OID]=0)thenbeginif(mob[i,Atk]=1)thenstr:=IntToStr(i)+'Mob:'elseif(mob[i,Atk]=-1)thenstr:=IntToStr(i)+'Corpse:'elsestr:=IntToStr(i)+'NPC:';
str:=str{+'ID:'}{+IntToStr(Mob[i,OID])+'Type:'}+NpcName(Mob[i,id]){+' On:('+IntToStr(Mob[i,x])+IntToStr(Mob[i,y])+IntToStr(Mob[i,z])+')'};
Npc.Lines.Add(str);
end;
end;
end;
procedure StateShow;
begin
State.Lines.Clear;
State.Lines.Add(Name);
State.Lines.Add('CP '+IntToStr(CurCP)+'/'+IntToStr(MaxCP));
State.Lines.Add('HP '+IntToStr(CurHP)+'/'+IntToStr(MaxHP));
State.Lines.Add('MP '+IntToStr(CurMP)+'/'+IntToStr(MaxMP));
State.Lines.Add('X '+IntToStr(MyX));
State.Lines.Add('Z '+IntToStr(MyY));
State.Lines.Add('Y '+IntToStr(MyZ));
if(target>-1)then
State.Lines.Add('Target:'+NpcName(Mob[target,id])+'('+IntToStr(target)+')')else
State.Lines.Add('Target:NO');
if(lasttarget>-1)then
State.Lines.Add('LastTarget:'+IntToStr(lasttarget));
end;
procedure InvShow;
var
i:integer;
begin
Inv.Lines.Clear;
for i:=0to79dobeginifNOT(Inventory[i,2]=0)then
Inv.Lines.Add('Item:'+ItemName(Inventory[i,2])+' Count:'+IntToStr(Inventory[i,3]));
end;
end;
//основная часть скрипта//вызывается при приходе каждого пакета если скрипт включенbegin//****************************************************************************//не обрабатываем пустые пакетыif pck=''thenexit;
if FromServer thenbegincase pck[1] of
#$04: begin
Log.Lines.Add('S>Пакет UserInfo #$04');
//пакет с инфой о моём чаре
InitStats;
end;
#$0E: begin
Log.Lines.Add('S>Пакет StatusUpdate #$0E');
if(MyID=ReadD(2))then StatsUpdate; //обновление информации о хпend;
#$1B: begin
Log.Lines.Add('S>Пакет InventoryCreate #$1B');
InventoryCreate;
end;
#$27:begin
Log.Lines.Add('S>Пакет InventoryUpdate #$27');
InventoryUpdate;
end;
#$16: begin
Log.Lines.Add('S>Пакет NpcInfo #$16');
NpcInfo;
end;
#$12: begin
Log.Lines.Add('S>Пакет DeleteObject #$12');
DeleteObject;
end;
#$06: begin
Log.Lines.Add('S>Пакет Die #$06');
Die;
end;
#$0C: begin
Log.Lines.Add('S>Пакет DropItem #$0C');
DropItem;
end;
#$01: begin
Log.Lines.Add('S>Пакет MoveToLocation #$01');
MoveToLocation;
end;
#$05: begin
Log.Lines.Add('S>Пакет Attack #$05');
UnderAttack;
end;
end;
endelsebegincase pck[1] of
#$48: begin
Log.Lines.Add('C>Пакет ValidateLocation #$48');
CorsUpdate;
end;
#$04:begin
Log.Lines.Add('C>Пакет Action #$04');
Action;
end;
#$1B: begin
Log.Lines.Add('S>Пакет SocialAction #$1B:'+IntToStr(ReadD(2)));
case ReadD(2)of6:begin//Log.Lines.Add('NearestTarget');
Log.Lines.Add('Start');
Search.Enabled:=True;
//SendAction(Mob[NearestMob,OID]);
pck:='';
end;
5:begin
sit;
pck:='';
end;
end;
end;
end;
end;
end.
Последний раз редактировалось finomen, 19.05.2008 в 21:13.
var
ItemsName: TStringList; //названия предметовprocedure Init;
begin
ItemsName:=TStringList.Create;
ItemsName.LoadFromFile('itemsid.ini'); //загрузка из файлаend;
function free;
begin
ItemsName.free;
end;
//******************************************//название вещи//******************************************function ItemName(id:integer):string;
begin
result:=ItemsName.Strings[ID];
end;
Последний раз редактировалось NLObP, 20.05.2008 в 00:05.
я про то что в массиве куча пустых будет....там не все id..хотя памяти много...можно попробовать))
ЗЫ никто не знает как переслать из пакетхака расшифрованные пакеты другому приложению? а то на С++ хотел бота написать....я с дельфи не очень....
finomen, ты уже думал на счёт аутгейма?аутгейм работает прекрасно если координаты не меняются перса вообще.если перс двигается то нужно посылать серваку validateposition с частым интервалом во время движения.у тебя какие на этот повод мысли?там ведь ещё координата Z кроме всего прочего..чтобы бот не палился более менее и если он не двигаетс явообще то я делал аутгейм и все прекрасно работает.просто ответ на пинг отсылает...скрипт в теме ОГ бот.+чтобы ваще ен палится можно былобы ещё сделать requestPledgeInfo этот пакет клиент шлёт если рядом появляется чувак который в клане , мне кажется это чтото связанно с картинкой клана