Перейти к содержанию

Учимся писать скрипты для бота Adrenaline


Рекомендуемые сообщения

И так мой друг приветствую тебя на плоскости программирования. :ph34r:

Я постараюсь описать все максимально понятно, не использую суперсложных слов.

Прежде чем писать свой очередной-мегакрутой скрипт, убедись в своих силах.

Ты можешь прочитать элементарную литературу на языке Delphi 

http://cybern.ru/category/delphilessons/begin

Но конечно тебе не нужно это, поэтому изучим необходимые тебе знания при написании скриптов, предназначенных для фарма-ребафа(либо выехал коньками вперед)-фарма

И так мы начали, задаем вопрос. Что нужно, чтобы бот проверял. Правильно, наличие бафа и того, что он не по дороге в вальгалу.

Проще, любые проверки, и вообще отдельные части действия писать в процедурах и функциях, поэтому брат мой по адаму(ну или сестра держи)

Процедура проверки.



procedure Check;
var
obj: TL2NPC;
buff:TL2buff;
begin
    if User.Dead then begin
        Engine.FaceControl(0,false);
        Print('Уехал в вальгаллу');
        Delay(1000);
        Engine.GOHome;  
        Delay(3000);
     end;
     if not User.Buffs.ById(1204, Obj)  then begin 
        Engine.FaceControl(0,false);
        print('Ohh.. Fuck Бать мой баф закончился');
        engine.unstuck;    
        Delay(30000);
     end;
end;

А теперь поясняем за скрипт, процедура(procedure) это отдельная программа(подпрограмма).

Она выполнит действия которые находятся в ней.

А есть функция, она подходит тогда, когда нужно, чтобы в 1 строке умещалось целая процедура.

Рассмотрим на примере опять, же проверок на баф или смерть(Мы пацаны только учимся же)

function CheckBuff:boolean;
var
obj: TL2NPC;
buff:TL2buff;
begin
     if not User.Buffs.ById(1204, Obj) then result:= true
    else result:= false;
end;


function CheckDeath:boolean;
begin
    if User.Dead then result:= true
    else result:= false;
end;

if-(если) not-(нет) then-(то) else-(если не то, то это)

Благодаря этому, если написать if (CheckBuff=true) then Engine.Unstuck.

То персонаж, если не под бафом 1204(Wind Walk), то анстакнется.

Так, мы научились выстраивать проверки, мы красавцы. Осталось написать только движения до спота, и включение интерфейса. Но появляется вопрос, как же сделать так, чтобы бот понимал, что он на фарме. Ответ в простом созданим переменную тип boolean, c любым названием(у меня будет War).

И тогда пусть после того как бот пришел к споту War присваивается(ровно) true, а когда анстакнулся( либо к прадедам ушел), присваивается false.

Благодаря этому, мы еще оптимизируем наш скрипт.(Чтобы жрало меньше ресурсов пк).

И так как записывать маршрут мы знаем, красный кружочек адреналина, доводим его до ГК. И вот мы стоим у гк, нам нужно получить баф.

А получим мы его вот такой вот процедурой( да да, ты это проходил чувак). Возьмем в таргет-> подбежим-> Откроем диалог-> Бафнемся

Для этого на в шапке в uses нужно будет указать RegExpr, и вставить 2 процедуры(не вдавайся в подробности). Просто скопируй и вставь куда нужно.

uses SysUtils, Classes, RegExpr;
procedure PrintAllTags();   // распечатать все конструкции с bypass'ами
var RegExp: TRegExpr; 
begin  
  RegExp:= TRegExpr.Create;
  RegExp.Expression:= '(<a *(.+?)</a>)|(<button *(.+?)>)';   
  if RegExp.Exec(Engine.DlgText) then 
    repeat Print(RegExp.Match[0]);
    until (not RegExp.ExecNext);  
  RegExp.Free;
end;

function Bypass(dlg: string): boolean;   // найти и отправить байпасс по названию диалога
var
  RegExp: TRegExpr;
  SL: TStringList;
  i: integer;
  bps: string;
begin
  Result:= true;                                            // задаем результат по умолчанию
  RegExp:= TRegExpr.Create;                                 // инициализируем объекты для дальнейшей работы
  SL:= TStringList.Create;
  
  RegExp.Expression:= '(<a *(.+?)</a>)|(<button *(.+?)>)';  // задаем регэксп на поиск всех возможных bypass'ов 
  if RegExp.Exec(Engine.DlgText) then                       // если нашлелся нужный шаблон, то
    repeat SL.Add(RegExp.Match[0]);                         // заполняем наш список такими совпадениями
    until (not RegExp.ExecNext);                            // пока не закончатся шаблоны

  for i:= 0 to SL.Count-1 do begin                          // теперь пробегаемся по нашему списку
    if (Pos(dlg, SL[i]) > 0) then begin                     // если в i-ой строке нашелся искомый текст, то
      RegExp.Expression:= '"bypass -h *(.+?)"';             // ищем шаблон текста c bypass'ом
      if RegExp.Exec(SL[i]) then                            // и если нашли, то копирем из него интересующий нас кусок
        bps:= TrimLeft(Copy(RegExp.Match[0], 12, Length(RegExp.Match[0])-12));
    end;
  end;
  
  Print(bps);                                               // распечатываем конечный вариант bypass'а
  if (Length(bps) > 0) then Engine.BypassToServer(bps);     // если его длина > 0, то отправляем на сервер
  
  RegExp.Free;                                              // не забываем освобождать память
  SL.Free;
end;

PrintAllTags предназначен, для вывода в чат бота всех байпасов с диалогового окна в окно бота.Если вызвать ее в скрипте. Можете удалить если мешает.

 PrintAllTags()

Вот так

А теперь саму процедуру бафа сделаем.

procedure rebuff;
begin
  Engine.SetTarget(35639);
  Engine.MoveToTarget(-20);
  delay(1500);
  Engine.DlgOpen();
  delay(1500);
  Bypass('Чародей');
  delay(3000);
end;

SetTarget берет в таргет по ID это бафер на данном сервере

MoveToTarget(-20) бежит к таргету на расстояние 20

DlgOpen() открывает диалог

Bypass вызывает фукнцию по названию(Можете написать Атакующий как данном сервере, он бафнет этот набор, ну что написано, то и тыкнет).

И так у нас получилось бафнуться, осталось подойти к гк, придти на спот, включить интерфейс.

procedure tpTospot;
begin
  Engine.SetTarget(30059);
  Engine.MoveToTarget(-20);
  delay(1500);
  Engine.DlgOpen;
  delay(1500);
  Engine.DlgSel(1);//стройка где написано телепорт
  delay(1500);
  Engine.DlgSel(10);//номер строки куда нужно тп
  delay(15000);
end;

Аналог предыдущего, но при этом мы используем DlgSel-выбирает номер строки.

Осталось придти на спот и включить интерфейс.

procedure roadToSpot;
begin
  Engine.MoveTo(15976, 114136, -3576);
  Engine.MoveTo(15256, 114136, -3576);
  Engine.MoveTo(14776, 114104, -3584);
  Engine.MoveTo(14184, 114120, -3616);
  Engine.MoveTo(13912, 114120, -3632);
  War:=true;
  Engine.FaceControl(0,true);
end;

Не забывайте про War(либо, свою переменную для обозначения состояние(фармит, или нет)) впишите в процедуру ребафа, и смерти ее с присвоением false.

И так осталось дело за самим управлением, и мы ake Шумахер справляемся с ним очень легко.

Возьмем с учетом, того что в процедуре GoGK вы вписали маршрут до ГК в городе фарма(скомуниздили с форума, че еще нам норм пацанам)

begin
	while 1<>2 do begin
		if war=true then begin//когда мы на войне
    		check;
			delay(150);
		end;
		if war=false then begin//когда мы не на войне
			GoGK;
			rebuff;
			tpTospot;
			roadTospot;
            delay(150);
		end;
	end;
end.

И так ты обучился самому элементарному, в программирование очень много интересного, это кажется теперь легко. А потом написать скрипт на ПВП, или ГВЕ покажется тоже простотой. Самое главное перед написанием, расписать ( на листке, у себя в голове) логическую цепочку действий, что бы ты сам делал будь ты ботом.

И так у нас получился вот такой скрипт.

uses SysUtils, Classes, RegExpr;
var
War:Boolean;
procedure PrintAllTags();   // распечатать все конструкции с bypass'ами
var RegExp: TRegExpr; 
begin  
  RegExp:= TRegExpr.Create;
  RegExp.Expression:= '(<a *(.+?)</a>)|(<button *(.+?)>)';   
  if RegExp.Exec(Engine.DlgText) then 
    repeat Print(RegExp.Match[0]);
    until (not RegExp.ExecNext);  
  RegExp.Free;
end;

function Bypass(dlg: string): boolean;   // найти и отправить байпасс по названию диалога
var
  RegExp: TRegExpr;
  SL: TStringList;
  i: integer;
  bps: string;
begin
  Result:= true;                                            // задаем результат по умолчанию
  RegExp:= TRegExpr.Create;                                 // инициализируем объекты для дальнейшей работы
  SL:= TStringList.Create;
  
  RegExp.Expression:= '(<a *(.+?)</a>)|(<button *(.+?)>)';  // задаем регэксп на поиск всех возможных bypass'ов 
  if RegExp.Exec(Engine.DlgText) then                       // если нашлелся нужный шаблон, то
    repeat SL.Add(RegExp.Match[0]);                         // заполняем наш список такими совпадениями
    until (not RegExp.ExecNext);                            // пока не закончатся шаблоны

  for i:= 0 to SL.Count-1 do begin                          // теперь пробегаемся по нашему списку
    if (Pos(dlg, SL[i]) > 0) then begin                     // если в i-ой строке нашелся искомый текст, то
      RegExp.Expression:= '"bypass -h *(.+?)"';             // ищем шаблон текста c bypass'ом
      if RegExp.Exec(SL[i]) then                            // и если нашли, то копирем из него интересующий нас кусок
        bps:= TrimLeft(Copy(RegExp.Match[0], 12, Length(RegExp.Match[0])-12));
    end;
  end;
  
  Print(bps);                                               // распечатываем конечный вариант bypass'а
  if (Length(bps) > 0) then Engine.BypassToServer(bps);     // если его длина > 0, то отправляем на сервер
  
  RegExp.Free;                                              // не забываем освобождать память
  SL.Free;
end;

procedure Check;
var
obj: TL2NPC;
buff:TL2buff;
begin
    if User.Dead then begin
        Engine.FaceControl(0,false);
        Print('Уехал в вальгаллу');
        Delay(1000);
        Engine.GOHome;  
        Delay(3000);
     end;
     if not User.Buffs.ById(1204, Obj)  then begin 
        Engine.FaceControl(0,false);
        print('Ohh.. Fuck Бать мой баф закончился');
        engine.unstuck;    
        Delay(30000);
     end;
end;

procedure rebuff;
begin
  Engine.SetTarget(35639);
  Engine.MoveToTarget(-20);
  delay(1500);
  Engine.DlgOpen();
  delay(1500);
  Bypass('Чародей');
  delay(3000);
end;

procedure tpTospot;
begin
  Engine.SetTarget(30059);
  Engine.MoveToTarget(-20);
  delay(1500);
  Engine.DlgOpen;
  delay(1500);
  Engine.DlgSel(1);//стройка где написано телепорт
  delay(1500);
  Engine.DlgSel(10);//номер строки куда нужно тп
  delay(15000);
end;
procedure roadToSpot;
begin
  Engine.MoveTo(15976, 114136, -3576);
  Engine.MoveTo(15256, 114136, -3576);
  Engine.MoveTo(14776, 114104, -3584);
  Engine.MoveTo(14184, 114120, -3616);
  Engine.MoveTo(13912, 114120, -3632);
  War:=true;
  Engine.FaceControl(0,true);
end;

procedure GoGK;
begin
//тут подводка к гк
end;

begin
	while 1<>2 do begin
		if war=true then begin//когда мы на войне
    		check;
			delay(150);
		end;
		if war=false then begin//когда мы не на войне
			GoGK;
			rebuff;
			tpTospot;
			roadTospot;
            delay(150);
		end;
	end;
end.

 

 

Повтор выбора диалогов окнами за основным персонажем

Скрипт будет управлять вторичными окнами, повторяя ими выбор всех диалогов вслед за мейном.

 

Скрипт нужно запускать запускать на главном окне. Не забудьте изменить ники персонажей, которыми нужно управлять.

const
  DialogRepeatEnable: boolean = true; // повтор диалогов, true(да) / false(нет)
  // список ников персонажей, которые должны повторять за основным окном
  DialogRepeatPlayerList: array of string = ['Krickt1338', 'Krickt1339', 'Vasya'];
  OpcodeStr = '23';  // для Interlude заменить на '21'
  OpcodeHex = $23;  // для Interlude заменить на $21

procedure OnCliPacket(ID1, ID2: Cardinal; Data: Pointer; Size: Word);   // обработчик исходящих пакетов (C->S)
begin
  if (DialogRepeatEnable) and (ID1 = OpcodeHex) then   // если повтор включен, и id пакета совпадает с выбором диалога, то
    DialogRepeat(MemToHex(Data^, Size));               // вызываем функцию, которая повторит выбор диалога указанным окнам
end;

procedure DialogRepeat(PacketData: string);
var 
  E: TL2Control;
  i: integer;
begin
  for i:= 0 to Length(DialogRepeatPlayerList)-1 do begin         // проходим по списку чаров, которыми нужно повторять диалоги
    E:= nil;
    E:= GetControl(DialogRepeatPlayerList[i]);                   // получаем Engine нужного окна
    if (E <> nil) then E.SendToServer(OpcodeStr + PacketData);   // если Engine получен, то отправляем пакет выбора диалога
  end;
end;

procedure DialogOpen(E: TL2Control);    // берет в таргет и открывает диалог с нужным NPC другим окном
begin
  E.SetTarget(User.Target.ID);
  E.DlgOpen;
end;

procedure DialogOpenThread();           // основной поток, выполняющий всю логику
var
  p1, p2: integer;
  i: integer;
  E: TL2Control;
  LastTargetID: cardinal;               // тут мы храним ID последнего нашего таргета
  LastDlgText: string;                  // тут будет храниться текст последнего диалога
begin
  Engine.SendActID(1);                        // активируем перевхат C->S пакетов 
  while (true) do begin                       // запускаем бесконечный цикл
    Engine.WaitAction([laDlg], p1, p2);       // ждем события "открытие диалога"
    while (User.Target.ID = LastTargetID) and (Engine.DlgText <> LastDlgText) do delay(10);
    for i:= 0 to Length(DialogRepeatPlayerList)-1 do begin   // для каждого ника из списка персонажей
      E:= nil;
      E:= GetControl(DialogRepeatPlayerList[i]);             // получаем его Engine
      if (E <> nil) then                                     // и если Engine получен, то 
        Script.NewThread(@DialogOpen(E));                    // запускаем для его поток, который откроет диалог с нужным NPC
    end;
    LastTargetID:= User.Target.ID;                           // перезаписываем ID поеледнего цели
    LastDlgText:= Engine.DlgText;                            // и текст последнего диалога
  end;
end;

begin
  if (DialogRepeatEnable) then              // если повтор включен, то
    Script.NewThread(@DialogOpenThread);    // запускаем поток, который будет делать все необходимое

  // code ...    
    
  Delay(-1);
end.
  • Like 1
Ссылка на сообщение
Поделиться на другие сайты
  • 1 год спустя...
2 hours ago, Andrey_ said:

А где можно подсмотреть все методы класа Engine и иже с ним?

На офф сайте адрика есть подробная документация по всем классам

  • Like 1
Ссылка на сообщение
Поделиться на другие сайты
  • 2 месяца спустя...

Подскажите пожалуйста, по вашему шаблону, после смерти, или при отсутствии баффа, скрип постоянно циклирует /Unstuck не баффается и не возвращается на спот

Ссылка на сообщение
Поделиться на другие сайты
  • 2 месяца спустя...

И так у нас получился вот такой скрипт.

uses SysUtils, Classes, RegExpr;
var
War:Boolean;
procedure PrintAllTags();   // распечатать все конструкции с bypass'ами
var RegExp: TRegExpr; 
begin  
  RegExp:= TRegExpr.Create;
  RegExp.Expression:= '(<a *(.+?)</a>)|(<button *(.+?)>)';   
  if RegExp.Exec(Engine.DlgText) then 
    repeat Print(RegExp.Match[0]);
    until (not RegExp.ExecNext);  
  RegExp.Free;
end;

function Bypass(dlg: string): boolean;   // найти и отправить байпасс по названию диалога
var
  RegExp: TRegExpr;
  SL: TStringList;
  i: integer;
  bps: string;
begin
  Result:= true;                                            // задаем результат по умолчанию
  RegExp:= TRegExpr.Create;                                 // инициализируем объекты для дальнейшей работы
  SL:= TStringList.Create;
  
  RegExp.Expression:= '(<a *(.+?)</a>)|(<button *(.+?)>)';  // задаем регэксп на поиск всех возможных bypass'ов 
  if RegExp.Exec(Engine.DlgText) then                       // если нашлелся нужный шаблон, то
    repeat SL.Add(RegExp.Match[0]);                         // заполняем наш список такими совпадениями
    until (not RegExp.ExecNext);                            // пока не закончатся шаблоны

  for i:= 0 to SL.Count-1 do begin                          // теперь пробегаемся по нашему списку
    if (Pos(dlg, SL[i]) > 0) then begin                     // если в i-ой строке нашелся искомый текст, то
      RegExp.Expression:= '"bypass -h *(.+?)"';             // ищем шаблон текста c bypass'ом
      if RegExp.Exec(SL[i]) then                            // и если нашли, то копирем из него интересующий нас кусок
        bps:= TrimLeft(Copy(RegExp.Match[0], 12, Length(RegExp.Match[0])-12));
    end;
  end;
  
  Print(bps);                                               // распечатываем конечный вариант bypass'а
  if (Length(bps) > 0) then Engine.BypassToServer(bps);     // если его длина > 0, то отправляем на сервер
  
  RegExp.Free;                                              // не забываем освобождать память
  SL.Free;
end;

procedure Check;
var
obj: TL2NPC;
buff:TL2buff;
begin
    if User.Dead then begin
        Engine.FaceControl(0,false);
        Print('Уехал в вальгаллу');
        Delay(1000);
        Engine.GOHome;  
        Delay(3000);
     end;
     if not User.Buffs.ById(1204, Obj)  then begin 
        Engine.FaceControl(0,false);
        print('Ohh.. Fuck Бать мой баф закончился');
        engine.unstuck;    
        Delay(30000);
     end;
end;

procedure rebuff;
begin
  Engine.SetTarget(35639);
  Engine.MoveToTarget(-20);
  delay(1500);
  Engine.DlgOpen();
  delay(1500);
  Bypass('Чародей');
  delay(3000);
end;

procedure tpTospot;
begin
  Engine.SetTarget(30059);
  Engine.MoveToTarget(-20);
  delay(1500);
  Engine.DlgOpen;
  delay(1500);
  Engine.DlgSel(1);//стройка где написано телепорт
  delay(1500);
  Engine.DlgSel(10);//номер строки куда нужно тп
  delay(15000);
end;
procedure roadToSpot;
begin
  Engine.MoveTo(15976, 114136, -3576);
  Engine.MoveTo(15256, 114136, -3576);
  Engine.MoveTo(14776, 114104, -3584);
  Engine.MoveTo(14184, 114120, -3616);
  Engine.MoveTo(13912, 114120, -3632);
  War:=true;
  Engine.FaceControl(0,true);
end;

procedure GoGK;
begin
//тут подводка к гк
end;

begin
	while 1<>2 do begin
		if war=true then begin//когда мы на войне
    		check;
			delay(150);
		end;
		if war=false then begin//когда мы не на войне
			GoGK;
			rebuff;
			tpTospot;
			roadTospot;
            delay(150);
		end;
	end;
end.

С первой строки выдаёт ошибку File "RegExpr.PCU" not found
Как решить? Что,где и куда можно посмотреть или скачать)

Изменено пользователем nawQa
Ссылка на сообщение
Поделиться на другие сайты
  • 3 недели спустя...

Всем привет. У ково есть данный скрипт под крякнутый адрик?

const
  DialogRepeatEnable: boolean = true; // повтор диалогов, true(да) / false(нет)
  // список ников персонажей, которые должны повторять за основным окном
  DialogRepeatPlayerList: array of string = ['Krickt1338', 'Krickt1339', 'Vasya'];
  OpcodeStr = '23';  // для Interlude заменить на '21'
  OpcodeHex = $23;  // для Interlude заменить на $21

procedure OnCliPacket(ID1, ID2: Cardinal; Data: Pointer; Size: Word);   // обработчик исходящих пакетов (C->S)
begin
  if (DialogRepeatEnable) and (ID1 = OpcodeHex) then   // если повтор включен, и id пакета совпадает с выбором диалога, то
    DialogRepeat(MemToHex(Data^, Size));               // вызываем функцию, которая повторит выбор диалога указанным окнам
end;

procedure DialogRepeat(PacketData: string);
var 
  E: TL2Control;
  i: integer;
begin
  for i:= 0 to Length(DialogRepeatPlayerList)-1 do begin         // проходим по списку чаров, которыми нужно повторять диалоги
    E:= nil;
    E:= GetControl(DialogRepeatPlayerList[i]);                   // получаем Engine нужного окна
    if (E <> nil) then E.SendToServer(OpcodeStr + PacketData);   // если Engine получен, то отправляем пакет выбора диалога
  end;
end;

procedure DialogOpen(E: TL2Control);    // берет в таргет и открывает диалог с нужным NPC другим окном
begin
  E.SetTarget(User.Target.ID);
  E.DlgOpen;
end;

procedure DialogOpenThread();           // основной поток, выполняющий всю логику
var
  p1, p2: integer;
  i: integer;
  E: TL2Control;
  LastTargetID: cardinal;               // тут мы храним ID последнего нашего таргета
  LastDlgText: string;                  // тут будет храниться текст последнего диалога
begin
  Engine.SendActID(1);                        // активируем перевхат C->S пакетов 
  while (true) do begin                       // запускаем бесконечный цикл
    Engine.WaitAction([laDlg], p1, p2);       // ждем события "открытие диалога"
    while (User.Target.ID = LastTargetID) and (Engine.DlgText <> LastDlgText) do delay(10);
    for i:= 0 to Length(DialogRepeatPlayerList)-1 do begin   // для каждого ника из списка персонажей
      E:= nil;
      E:= GetControl(DialogRepeatPlayerList[i]);             // получаем его Engine
      if (E <> nil) then                                     // и если Engine получен, то 
        Script.NewThread(@DialogOpen(E));                    // запускаем для его поток, который откроет диалог с нужным NPC
    end;
    LastTargetID:= User.Target.ID;                           // перезаписываем ID поеледнего цели
    LastDlgText:= Engine.DlgText;                            // и текст последнего диалога
  end;
end;

begin
  if (DialogRepeatEnable) then              // если повтор включен, то
    Script.NewThread(@DialogOpenThread);    // запускаем поток, который будет делать все необходимое

  // code ...    
    
  Delay(-1);
end.
Изменено пользователем AKIBA
Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
×
×
  • Создать...