Форум работает в тестовом режиме. Все данные были перенесены со старого сайта 2018 года. Некоторая информация может быть недоступна, например вложения или хайды. Просьба сообщать о данных случаях через функционал "Жалоба", прямо под постом, где отсуствуют данные из хайда или проблемы с вложением.
Могут быть проблемы в "выкидыванием" с форума (слетевшей авторизацией). Нужно собрать статистику таких случаев.
Есть Тема, куда можете сообщить о проблемах с сайтом либо просто передать привет.

Прошу помощи в оптимизации и исправлении скрипта

Рег
14 Май 2016
Сообщения
37
Реакции
0
Приветствую!

В общем, нуждаюсь в помощи знатоков в вопросе приведения моего первого скрипта в порядок.. Спрашивал, спрашивал советов, а все равно где-то nahuevertil накосячил.

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

Там проблем много, как мне кажется.. Во-первых, само оформление может страдать, так что заранее приношу извинения за кровь из глаз эстетов. Во-вторых, проверка на смерть не отрабатывается должным образом. В-третьих, периодически появляется проблема с изначальным взятием квеста - искомая строчка была у NPC второй, а потом вдруг внезапно становится третьей. Пробовал вместо Engine.DlgSel(*) отправлять байпасс - по неясным причинам схватил авто-тюрьму на 1500 минут...

В общем, прошу просмотреть и высказать ваши советы и предложения. От меня взамен - тысяча благодарностей, плюсы к вашей карме и репутации на Равре ^_^



var obj: TL2NPC;
obj2: TL2Effect;


Enemy: TL2Live;

Item: TL2Item;
Npc: TL2Npc;
L2Skill: TL2Skill;
Control: TL2Control;
TNpcList: TL2List;
procedure Dead();
Begin
while 1<>2 do begin
delay(2000);
if User.Dead then begin
print('Умер');
Delay(5000);
engine.GoHome;
Engine.FaceControl(0, false);
end;
end;
end;
Begin
while 1<>2 do begin
delay(5000);
if user.InRange(149594, -112698, -2059,300,300) then begin
delay(100);
engine.settarget(31521);
engine.dlgOpen();
Delay(1000);
Engine.DlgSel(1);
Delay(1000);
Engine.DlgSel(1); //на самом деле, как вы знаете, достаточно было бы только открыть диалог, два раза кликнуть по первой строчке и все, однако
Delay(1000); //адекватно строка нажимается и отправляется байпасс только с двумя лишними строками.. не знаю, с чем связано..
Engine.DlgSel(1); //и именно на этапе взятия квестов эти самые квесты иногда меняются в диалоговом окне местами, из-за чего открывается не тот квест, отправляется не тот байпасс,
Delay(1000); //и мой персонаж отправляется в тюрьму..
Engine.DlgSel(1); Engine.bypasstoserver('Quest 621_EggDelivery 31521-1.htm');
delay(1000);
engine.dlgOpen();
Delay(1000);
Engine.DlgSel(1);
Delay(1000);
Engine.DlgSel(2);
Delay(1000);
Engine.DlgSel(1);
Delay(1000);
Engine.DlgSel(1); Engine.bypasstoserver('Quest 622_DeliveryOfSpecialLiquor 31521-1.htm');
delay(1000);
// далее все без проблем и абсолютно идентично - маршрут к следующему NPC, диалог с ним и т.д.
delay(100);
engine.settarget(31521);
engine.dlgOpen();
Delay(1000);
Engine.DlgSel(1);
Delay(1000);
Engine.DlgSel(1);
Delay(1000);
engine.bypasstoserver('Quest 621_EggDelivery 31521-3.htm');
delay(1000);
engine.dlgOpen();
Delay(1000);
Engine.DlgSel(1);
Delay(1000);
Engine.DlgSel(1);
Delay(1000);
engine.bypasstoserver('Quest 622_DeliveryOfSpecialLiquor 31521-3.htm');
end;
begin
Script.NewThread(@dead);
end;
end;
end.

Заранее спасибо за ваше время и терпение :)
 
@SaintGlory,

в скрипте в процедуре Dead() после

Engine.FaceControl(0, false);

Поставь

exit;

Именно это не только интерфейс отрубит но и выключит сам скрипт.

@SaintGlory, Если ты запускаешь потоки то выделяй их в отдельные процедуры.

begin
Script.NewThread(@dead);
end;

Это написано не верно. Бегин и енд в данном случае никчему. Сам запуск потока в чамое начало основного тела поставь после begin

@SaintGlory, Если у тебя Перс берет не тот квест то после диалога с НПС проверяй наличие и шаг квеста по ИД в цикле
Код:
While not Engine.QuestStatus([ID квеста], [Шаг квеста]) do 
begin
//Здесь пишешь открытие диалога и т.д. с проверкой Байпаса в окне, если не найден байпас тогда делаешь продолжить. и он сново
//попробует с начала взять квест
end;
 
@SaintGlory, После открытие диалога есть смысл в твоем случае проверять наличие Байпаса в нем. Вот этим кодом можно получить текст диалога, далее обходи его циклом Для :
Код:
uses SysUtils, Classes;
var L:TStringList;

Begin
  L := TStringList.Create;  //Создаем объект (список для строк)
  L.Add(Engine.DlgText);    //Добавляем в список строку
end.
 
@ХОРВЕСТР, большое спасибо за помощь, но у меня осталась пара вопросов..

1) про выделение потоков в отдельные процедуры -

ХОРВЕСТР написал(а):
Сам запуск потока в самое начало основного тела поставь после begin
То есть, непосредственно перед взятием квеста?

Begin
Script.NewThread(@dead); //сюда?
while 1<>2 do begin
delay(5000);
if user.InRange(149594, -112698, -2059,300,300) then begin
delay(100);
engine.settarget(31521);
и так далее
2) А про сам квест.. Иногда он берет то, что нужно, иногда нет - без каких-либо закономерностей. После открытия диалогового окна бот прекрасно кликает на строчку Quest. Далее, он, в общем-то, также неплохо прожимает строчку по ее номеру, но байпасс все же там имеется вот такого вида:


engine.bypasstoserver('npc_268472806_Quest 621_EggDelivery');
При попытке отправить этот байпасс, персонаж автоматически улетел в тюрьму на полторы тыщи минут. Как ты считаешь, может ли помочь замена команды

Engine.DlgSel(1);
на

Engine.DlgSel('Egg Delivery');
3) Про проверку "наличия и шага квеста по ИД в цикле", а также про то, что ты описал в последнем сообщении, я, честно говоря, мало, что понял..) Признаюсь, очень хочется услышать подробнее про каждый из двух методов, что ты предлагаешь, если это не сильно тебя затруднит) А так, попробую поискать примеры пока.. Спасибо!
 
SaintGlory написал(а):
То есть, непосредственно перед взятием квеста?
Да именно! Ведь вы запускаете поток сразу на проверку смерти. и он будет выполняться до выключения всего скрипта.




SaintGlory написал(а):
2) А про сам квест..
На самом деле я не понимаю в чем проблема. У тебя не получается взять квест используя только команды Engine.DlgSel ? зачем ты используешь байпасы?



SaintGlory написал(а):
3) Про проверку
Что конкретно не понятно я написал? Ты сказал что у тебя перс то берет нужный квест то берет другой. Вот этим циклом проверяется есть ли у мерсонажа нужный квест и на каком он этапе. Если нету квеста он сново и сново пытается его взять ( опять таки без байпаса раз он отправляет в тюрму)

While not Engine.QuestStatus([ID квеста], [Шаг квеста]) do
begin
//Здесь пишешь открытие диалога и т.д. с проверкой Байпаса в окне, если не найден байпас тогда делаешь продолжить. и он сново
//попробует с начала взять квест
end;



SaintGlory написал(а):
Признаюсь, очень хочется услышать подробнее про каждый из двух методов
Здесь все просто. Это возвращает тебе весь код с открытым диалогом в данный момент построчно. Пробегаешься в цикле по строчкам и проверяешь есть ли в открытом диалоге нужный тебе байпас ( на случай если всетаки их использовать). Возможно у тебя в тюрьму летит изза отправки не нужного байпаса.

uses SysUtils, Classes;
var L:TStringList;

Begin
L := TStringList.Create; //Создаем объект (список для строк)
L.Add(Engine.DlgText); //Добавляем в список строку
end.

И ещё ! Попробуй реализовать все с помощью кликов мышью.! Я с помощью этого реализовал принятие почты. Уж со взятием квеста тоже можно придумать что-то.

Что бы рассчитать координаты точек используй:

http://rawr.su/topic/2104-mouse-recorder-pro-275-esche-odin-avtokliker-myshi/
Код:
//winapi
procedure mouseClick(point: array of integer); //base mouse delay
begin
  SetCursorPos(point[0], point[1]);
  delay(100);
  mouse_event($2, 0, 0, 0, 0); // Нажать левую кнопку мыши
  delay(20);
  mouse_event($4, 0, 0, 0, 0); // Отпустить левую кнопку мыши
end;
 
ХОРВЕСТР написал(а):
У тебя не получается взять квест используя только команды Engine.DlgSel ? зачем ты используешь байпасы?
Именно так. Скрипт отлично открывает диалог, выбирает квест (опустим сейчас тот факт, что периодически нужный квест у НПЦ "сползает" со второй позиции на третью))), а вот чтобы квест принять приходится отправлять байпасс.



ХОРВЕСТР написал(а):
Что конкретно не понятно я написал?
Это скорее я некорректно задал вопрос..) Я не вполне понял, что значит "с проверкой байпасса... если нужный байпасс не найден...". Каким образом реализовать эту проверку?



ХОРВЕСТР написал(а):
Попробуй реализовать все с помощью кликов мышью.
Ух ты! А вот об этом я не подумал. Но, я так понимаю, что в случае реализации квеста именно таким образом, этот скрипт будет работать только при определенном размере окна игры, определенном разрешении экрана и определенном расположении диалогового окна?
 
SaintGlory написал(а):
Каким образом реализовать эту проверку?
Ты знаешь как искать строку в строке?

Тот код возвращает массив Строк. Обойди их все и проверь входит ли твой байпас в одну из них. Ведь байпас это строка !

engine.bypasstoserver('npc_268472806_Quest 621_EggDelivery');

То что в кавычках ! И возможно ты его не правильно выделил ! ТЫ как его вычислял?


SaintGlory написал(а):
только при определенном размере окна игры, определенном разрешении экрана и определенном расположении диалогового окна?
Да именно. Я так понял тебе универсальность не нужна и ты пишешь для себя. ???

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



SaintGlory написал(а):
а вот чтобы квест принять приходится отправлять байпасс.
Объясни чем это обоснованно? С какой это целью делается? Лучше скриншоты приложи ! Это очень странное заявление если честно !
 
ХОРВЕСТР написал(а):
ТЫ как его вычислял?
Пробегал полностью оба квеста вручную и на каждом этапе разговора с каждым NPC использовал команду

print(Engine.DlgText);
Копировал из лога байпасс и вставлял в нужное место скрипта.



ХОРВЕСТР написал(а):
Я так понял тебе универсальность не нужна и ты пишешь для себя. ???
Был бы рад поделиться с друзьями, когда буду уверен, что им не грозят авто-санкции за использование моих наработок)) Скажем так, финальная цель этих потуг - создать универсальный скрипт под один конкретный сервер, на котором мы постоянно играем.



ХОРВЕСТР написал(а):
Объясни чем это обоснованно? С какой это целью делается? Лучше скриншоты приложи ! Это очень странное заявление если честно !
К сожалению, сейчас не имею возможности зайти в игру и сделать скриншоты, но в двух словах расскажу.
Если на этапе принятия квеста, когда нужно кликнуть строчку "I'll do it!" прописать просто Engine.DlgSel(1); то персонаж постоит на месте и побежит к следующему NPC без взятого квеста. У всех последующих NPC та же ситуация - Quest кликается выбором порядкового номера строки, нужный квест выбирается так же, а чтобы нажать финальную строчку и продвинуться по квесту приходится отправлять байпасс, иначе чар будет бегать по всей локации и общаться со всеми положенными NPC вхолостую. Причем описанная мною проблема с рандомными сменами искомых порядковых номеров строк была замечена только на стартовом NPC Jeremy.. У всех остальных неписей все прожимается прекрасно по схеме "открыл диалог - клик по строке - клик по строке - байпасс".
 
SaintGlory написал(а):
прописать просто Engine.DlgSel(1); то персонаж постоит на месте
ты пробывал указывать другие цифры,? подойди к НПС нажми все до того момента где не работает. и просто выполняй код

begin

Engine.DlgSel(1);

end.

меняй цифру пока не получится. начни с нуля и там до 20 пробегись

Я думаю что получится. у меня такая проблема тоже была я так сделал. ну то есть у меня строки не соответствовали тому что вижу на экране фактически.
 
SaintGlory написал(а):
Копировал из лога байпасс и вставлял в нужное место скрипта.

ВОТ !!! Ты кодом строки обойди и посмотри на какой позиции твой байпас. туда цифру и тыкай без байпаса ! ну там по тому что получилось сам смотри !
 
ХОРВЕСТР написал(а):
ты пробывал указывать другие цифры,?
Так у меня основная загвоздка в том, что мой скрипт один день работал без проблем, а потом вдруг внезапно строки у НПЦ скакать начали..)) Может это вообще глюк сервера, а я тут голову ломаю?.. :lol:
Ладно, в любом случае я уже получил достаточное количество рекомендаций..) Все попробую и отпишусь, как добьюсь желаемого результата. Или не добьюсь)) Спасибо большое, @ХОРВЕСТР!
 
я бы на твоем месте просто парсил бы диалог, с которым проблемы, мб там динамический байпасс и отсюда вылазят проблемы)

uses sysutils;

var
text,bypass:string;
i_bypass:integer;

begin
text:='Captcha: <font color="LEVEL">';
i_bypass:=pos(text, engine.dlgtext);
bypass:=copy(engine.dlgtext, i_bypass+29, 5);
print(bypass);
end.
вот небольшой пример, думаю разберешься) суть была такова что у джереми была капча на взятие квеста, которую нужно было вводить, отсчет шел по тексту <font color....> 29 символов, после которых было 5 цифр капчи, которые благополучно парсились и отправлялись с байпассом)
 
@SoundShocking, я правильно понимаю, что "парсинг диалога" - это и есть то, что описывается в ЭТОЙ теме? Ежели так, то у меня сохраненный диалог выглядел в html вот так:

<html><body>Chef Jeremy:<br>
Long ago..... *куча болтовни*
Will you help me?<br
<a action="bypass -h Quest 623_TheFinestFood 31521-03.htm">"I'll help you."</a>
</body></html>
Только в этом примере другой квест, но не суть)) В искомых двух было то же самое, только байпасс другой..
 
@ХОРВЕСТР, @SoundShocking, ну что ж, друзья.. Все оказалось банально и просто) Большое вам спасибо за ваше время и советы - именно вы натолкнули меня на верную мысль) Проблема с "прыгающими" строками решилась очень просто:

engine.DlgSel('Egg Delivery');
engine.DlgSel('Delivery of special liqour');
А дальше уже все по накатанной с прежними байпассами)
Еще немного потестирую, приведу в порядок оформление насколько смогу и выложу на ваш суд)
 
Назад
Сверху