Показать сообщение отдельно
Старый 14.05.2008, 08:32   #8
Пользователь
 
Регистрация: 22.04.2008
Сообщений: 51
Сказал Спасибо: 14
Имеет 36 спасибок в 11 сообщенях
alexsl пока неопределено
По умолчанию

важно: скрипт токо для отладки

Спасибо всем за замечание, вот вчерашний дописанный скрипт. В описаловке к скрипту все написано. Замечание:
- теперь можно управлять скрипом из других скриптов через чат.
- социальные действия отключены (если надо раскоментировать)
delphi Код:
/////////////////////////////////////////////////////////////// // для: L2PacketHack by xkor  // посл. редактирование: 14.05.2008, 15:03msk, alexsl  // назначение: перемещение чара по заранее записаным маршруту(м)  //    // краткая инструкция:  //  //                     1. прописать ник в MyNick    //  //    - для записи пути в файл:  //                     1. встаем на исходную позицию  //                     2. в чат пишим "===rec test1" (test1 - или другое имя без пробелов)  //                     3. бежим куда нужно. (желательно много не кликать на одно и тоже место. все клики записываются в файл)  //                     4. в чат пишим "===save"  //                     5. все. теперь данные записаны на диск, согласно настройкам и под именем test1 указ. в п.п.2  //  //    - записываем требуемые пути с разными маршрутами и названиями  //  //    - использование  //                   1. бег до последнего чекпоинта(при достижении скрипт завершает работу):  //                        пишим в чат "===go test1" (test1 - название записанного маршрута)  //                   2. бег до первого чекпоинта (при достижении скрипт завершает работу):  //                        пишим в чат "===back test1" (test1 - название записанного маршрута)  //                   3. для остановки скрипта при передвижении: пишим в чат "===stop"  //  //   как работает?: при запуске бежит к ближайшему чекпоинту и следует согласно направлению //   Использовались идеии, коды участников форума за, что спасибо  /////////////////////////////////////////////////////////////////////  var    // movement data    MovePath,                   //  данные по которому мы будем двигатся в данный момент    RecordPath: TStringList;    //  данные для записи пути    RecordPathFileName: string; // название файла для записи    PointsCount: integer;       // кол-во поинтов в процессе записи пути    SavePathEnabled: boolean;   // флаг записи пути    MoveToPathEnabled: boolean; // флаг движения по пути    MoveToForward: boolean;     // направление движения да-вперед, нет - назад    MoveStepIndex: integer;     // текущ. чекпоинт (куды бежим сейчас)    MoveTimer: TTimer;          //    old_X,old_Y,old_Z,old_time: integer;   myX,myY,myZ: integer;       // наши статы    myID: integer;    myHP,myMP,myMaxHP,myMaxMP: integerconst    MyNick = 'Мой ник';// <------------------------------   interlude = false;    debug = false;   // эта переменная указывает уничтожить пакет или нет если он обработан    // может данные нужны для других скриптов    EraseCommandFromChat = true;    //*******************************************************    RecordFilesPath = 'c:\'; // путь где хранятся наши файлы    RecordPathName = 'recordmove'; // файл по умолчанию    RecordFileExt = '.txt';// расширение по умолчанию    RangeToCheckPoint = 150; // дистанция до чекпоинта при которой считается , что мы достигли оного    MoveTrigerDelay = 800; // срабатывание таймера на движение  0,8 сек    cmdPrefix = '===';// с этих символов начинается команда    cmdDlm    = ' ';// разделитель параметров команды, параметры не должены содержать разделитель    // команды в общий чат                             // пример    cmdRecordPath = 'rec';   // в общий чат "===rec giran1"    cmdSavePath = 'save';    // в общий чат "===save"    cmdMove = 'go';         // в общий чат "===go giran1"    cmdBack = 'back';        // в общий чат "===back giran1"    cmdStop = 'stop';       // останавливает следование по маршруту    //*******************************************************  procedure Init; //Вызывается при включении скрипта  begin   MoveTimer := TTimer.Create(nil);   MoveTimer.Enabled := False;   MoveTimer.Interval := MoveTrigerDelay;   MoveTimer.OnTimer := @OnMove;   RecordPathFileName:='';   buf:=hstr('0F');   SendToServerEX(MyNick);   RecordPath:=TStringList.Create;   MovePath:=TStringList.Createendprocedure Free; //Вызывается при выключении скрипта  begin    if RecordPath<>nil then    try      RecordPath.Free;    except      debugmsg('error free RecordPath');    end;    if MovePath<>nil then    try      MovePath.Free;    except      debugmsg('error free MovePath');    endendprocedure debugmsg(s: string)begin    if debug then      SendMsg(s)endfunction GetValue(ValName: string): stringbegin    result:=RecordPath.Values[ValName];  endprocedure SetValue(ValName: string; Value: string)begin    RecordPath.Values[ValName]:=Value;  endprocedure StartRecord;  begin    if SavePathEnabled then      exit;    if MoveToPathEnabled then    begin      SendMsg('Во время следования по маршруту запись не возможна');      exit;    end;    RecordPath.Clear;    PointsCount:=0;    SendMsg('Начата запись маршрута');    SavePathEnabled := True  endprocedure StopRecord;  begin    if not SavePathEnabled then      exit;    // записываем    RecordPath.SaveToFile(GetRecordFileName);    SendMsg('Запись маршрута завершена');    SavePathEnabled := Falseendfunction GetRecordFileName: stringbegin    result:=RecordFilesPath+RecordPathFileName+RecordFileExt;  endprocedure SendMsg(msg:string)// отправка системных сообщений клиенту  begin    buf:=#$4A;    WriteD(0);    WriteD(10);    WriteS('');    WriteS(msg);    SendToClientEx(MyNick)endprocedure ParseMoveClient;  var    i,x,y,z: integer; s: stringbegin    if not SavePathEnabled then      exit;    i:=2;    x:=readd(i);    y:=readd(i);    z:=readd(i);    inc(PointsCount);    s:='|'+inttostr(x)+'|'+inttostr(y)+'|'+inttostr(z)+'|';    RecordPath.Add(s);    SendMsg('добавлен чекпоинт № '+inttostr(PointsCount))endfunction delta(xpos1, ypos1, xpos2, ypos2:extended):integer; //возвращает переменную rezu которая является растоянием между 2 точками  var    dx,dy,summa: extendedbegin    try    dx:= xpos1-xpos2;    dy:= ypos1-ypos2;    summa:= dx*dx+dy*dy;    if summa = 0 then result:= 0 else result:= Round(sqrt(summa));    debugmsg('delta='+inttostr(result));    except      debugmsg('error in delta');    endendfunction GetMinCheckPoint(PointsList: TStringList): integervar    i,m,min_dist: integer;    s: string;    x,y,z: integerbegin    result:=-1;    min_dist:=-1;    // проверка на наличие маршрута    if PointsList.Count=0 then    begin      exit;      MoveTimer.Enabled:=False;      MoveToPathEnabled:=False;      SendMsg('Нет данных по маршруту');      exit;    end;    try    for i:=0 to PointsList.count-1 do    begin      s:=PointsList[i];      y:=ExtractValue(s,2);      x:=ExtractValue(s,1);      debugMsg(s+' x:='+inttostr(x)+' y:='+inttostr(y));      m:=delta(x,y,myx,myy);      if m>0 then      begin              if (result=-1) then              begin                min_dist:=m;                result:=i;              end              else                if m<min_dist then                begin                  min_dist:=m;                  result:=i;                end;              end;    end;    except      debugMsg('error in GetMinCheckPoint');    end;//try  endprocedure GoToPath(ToForward: boolean)var    x,y,z,i: integer;    s: stringbegin    MoveToPathEnabled:= not MoveToPathEnabled;    MoveToForward:=ToForward;    if not MoveToPathEnabled then    begin      MoveTimer.Enabled:=False;      SendMsg('Следование по маршруту остановлено');      exit;    end;    //    // предположительно путь уже прописан в MovePath    //    SendMsg('Пробуем выйти на путь...');    // сперва идем к ближайшему чекпоинту    i:= GetMinCheckPoint(MovePath);    if i<0 then    begin      SendMsg('чекпоинт не найден');      MoveToPathEnabled:=False;    end else    begin      SendMsg('найден ближайший чекпоинт бежим туды');      MoveToPathEnabled:=True;      MoveStepIndex:=i;      if debug then        SendMsg('checkpoint #'+inttostr(i));      s:=MovePath[MoveStepIndex];      x:=ExtractValue(s,1);      y:=ExtractValue(s,2);      z:=ExtractValue(s,3);     if (old_x<>x) and (old_y<>y) and (old_z<>z) then     begin       MoveTo(x,y,z);       old_x:=x;       old_y:=y;       old_z:=z;       old_time:=0;     end;   end;    MoveTimer.Enabled:=Trueend//*************************************************************** procedure OnMove(Sender: TObject)var    x,y,z: integer; s: stringbegin    inc(old_time);// счетчик, сколько тиков прошло с последнего клика. исп. при следованию по маршруту   if not MoveToPathEnabled then   begin     try       TTimer(Sender).Enabled:=False;     except     end;     SendMsg('Движение остановлено');     exit;    end;    // возможно мы пали смертью храбрых, то не дергаемся пока   if myHP<=0 then   begin     sendmsg('Die');     MoveToPathEnabled:=False;     exit;   end;   debugmsg('hp:'+inttostr(myhp));   try     // проверяем на существ. объекта      // при отладке всякое может быть      MovePath.Count;    except      TTimer(Sender).Enabled:=False;      exit;    end;    s:=MovePath[MoveStepIndex];    x:=ExtractValue(s,1);    y:=ExtractValue(s,2);    z:=ExtractValue(s,3);    if PosInRange(x,y,z,RangeToCheckPoint) then    begin      if MoveToForward then      begin        if MoveStepIndex=MovePath.Count-1 then        begin          MoveToPathEnabled:=False;          SendMsg('Мы по идее в конечной точке');          exit;        end          else        begin          inc(MoveStepIndex);        end;      end      else      begin         if MoveStepIndex>0 then dec(MoveStepIndex)         else         begin            MoveToPathEnabled:=False;            SendMsg('Мы по идее в начальной точке');            exit;         end;      end;      // мы достигли чекпоинта идем далее      SendMsg('бежим к #'+inttostr(MoveStepIndex));      s:=MovePath[MoveStepIndex];      x:=ExtractValue(s,1);      y:=ExtractValue(s,2);      z:=ExtractValue(s,3);      MoveTo(x,y,z);    endendfunction ExtractValue(sData: string;nIndex: integer): integervar    s: string;    i,j: integerbegin    i:=0;j:=0;s:='';    s:=sData;    while j<nIndex do    begin      i:=pos('|',S);      if i>=0 then      begin        s:=copy(s,i+1,length(s)-i);        inc(j);      end      else        break;    end;    i:=pos('|',s);    if i>=0 then      s:=copy(s,1,i-1);    try      result:=strtoint(s);    except    endend//******************************************************************  //Bot by Skymanrus  //modified by NLObP специально для Владера, моего сына!  //ПЕРЕМЕЩЕНИЕ:  //Идти в точку с координатами x,y,z  //MOVETO(x,y,z)  procedure MoveTo(TargetX,TargetY,TargetZ:integer)begin    //01=MoveBackwardToLocation:d(targetX)d(targetY)d(targetZ)d(originX)d(originY)d(originZ)d(moveByMouse)    buf:=#$01;    WriteD(targetx); //куда    WriteD(targety);    WriteD(targetz);    WriteD(MyX); //откуда    WriteD(MyY);    WriteD(MyZ);    WriteD(1); //используем 1-мышь 0-клавиатура    SendToServerEx(MyNick)end//Ориентация на местности:  //Проверка находится ли заданная точка в пределах досягаемости. Если да, то выполняется кусок скрипта в фигурных скобках {}.  function PosInRange(targetx,targety,targetz,distanciya:integer):booleanbegin       if delta(targetx, targety, MyX, MyY)<=distanciya       then result:=true else result:=falseendprocedure UserInfo;            // обновление донных о себе  var    i:wordbegin    MyID:=ReadD(18);    MyX:=ReadD(2);    MyY:=ReadD(6);    MyZ:=ReadD(10);    i:=22;   ReadS(i);   if interlude then i:=i+48 else i:=i+44;   MyMaxHP:=ReadD(i);   MyHP:=ReadD(i);   MyMaxMP:=ReadD(i);        // чисто информативно   MyMP:=ReadD(i)endprocedure StatusUpdate;       // обновление данных о себе  var    i: integer; begin   for i:=0 to ReadD(6)-1 do    case pck[i*8+10] of      #$09: MyHP:=ReadD(i*8+14);      #$0A: MyMaxHP:=ReadD(i*8+14);      #$0B: MyMP:=ReadD(i*8+14);      #$0C: MyMaxMP:=ReadD(i*8+14);     end; end; //***************************************************************  procedure OnConnect(WithClient: Boolean); //Вызывается при установке соединения  begin  endprocedure OnDisonnect(WithClient: Boolean); //Вызывается при потере соединения  begin  endfunction iif(Bool: Boolean;aTrue: variant; aFalse: variant): variantbegin    if Bool then      result:=aTrue    else      result:=aFalse;  endfunction ParseCmd(cmd: string):booleanvar    s: string;    i,j,k: integer;    params: array[0..9] of string; // до 10 параметров, должно хватить  begin    result:=False;    try      j:=-1;      i:=pos(cmdPrefix,trim(cmd));      if i=0 then        exit;      debugmsg('start ParseCmd: idx:'+inttostr(i)+' cmd: '+cmd);      result:=true;      k:=length(cmdPrefix);      s:=trim(lowercase(cmd));      s:=trim(copy(s,i+k,length(cmd)-i));      debugmsg('trim:'+s);      repeat        inc(j);        k:=pos(cmdDlm,s);        if k>0 then        begin          params[j]:=copy(s,1,k-1)//        s:=copy(s,k+length(cmdDlm),length(s)-k-length(cmdDlm));          s:=trim(copy(s,k+length(cmdDlm),length(s)-k));          debugmsg('extract idx:'+inttostr(j) +' param:'+params[j]);        end        else        begin          params[j]:=s;          debugmsg('parm is one');        end;      until pos(cmdDlm,S)=0;      if j>-1 then      begin        inc(j);        params[j]:=s;        debugmsg('extract idx:'+inttostr(j) +' param:'+params[j]);      end;      if j=-1 then        exit;      //*******************************************************      // пропарсили команду      // теперь выполняем      //*******************************************************      if params[0]=cmdRecordPath then      begin         if params[1]<>'' then           RecordPathFileName:=params[1]         else           RecordPathFileName:=RecordPathName;         StartRecord;      end      else      if params[0]=cmdSavePath then      begin         StopRecord;      end      else      if params[0]=cmdMove then      begin         if params[1]='' then         begin           SendMsg('хз куда бежать, укажите имя');           exit;         end;         try           MovePath.LoadFromFile(RecordFilesPath+params[1]+RecordFileExt);         except           SendMsg('файл пути не найден');           exit;         end;         GoToPath(true);      end      else      if params[0]=cmdBack then      begin         if params[1]='' then         begin           SendMsg('хз куда бежать, укажите имя');           exit;         end;         try           MovePath.LoadFromFile(RecordFilesPath+params[1]+RecordFileExt);         except           SendMsg('файл пути не найден');           exit;         end;         GoToPath(false);      end      else      if (params[0]=cmdStop) and MoveToPathEnabled then        MoveToPathEnabled:=False;    except      debugmsg('error in ParseCmd,params='+cmd);    endend//основная часть скрипта  //вызывается при приходе каждого пакета если скрипт включен  var    i: integerbegin    if FromClient and (ConnectName=MyNick)then      case pck[1] of  {       #$1B:  // social                case pck[2] of                  #$06: StartRecord; //Yes                  #$05: StopRecord;//No                  #$04: begin GoToPath(true); pck:=''; end;                end; //case  }       #$01: // move                ParseMoveClient;       #$38: // say2             // если это команда и она обработана и надо очистить чат              if ParseCmd(ReadS(2)) and EraseCommandFromChat then                pck:='';// kill packet       #$48:             begin               myx:=ReadD(2);               myY:=ReadD(6);               myZ:=ReadD(10);             end;      end; // case    if FromServer and (ConnectName=MyNick) then      case pck[1] of        #$04: UserInfo;        #$0E: StatusUpdate;      end; // case  end.

Добавлено через 48 минут
Цитата:
Надо попробовать развить скрипт в разрезе ASTAR (A*)
интересная идея, гдето видел геодату от явы сервера, вечерком посмотрю может можно будет прикрутить. ну а на счет оценки стоимости передвижения ... ммм .. какие идеи? вариант: бот камикадзе, бегает туды сюды тыкается или самому отмечать чекпоинты или если есть в геодате инфа о проходимости того или иного участка юзать ее.

Последний раз редактировалось alexsl, 16.05.2008 в 15:01.
alexsl вне форума   Ответить с цитированием
За это сообщение alexsl нажился 5 спасибками от: