1

Тема: JQuery на примере начала диалога в Некровиле

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

С недавнего времени команда разработчиков в БК добавили возможность использования фрэймворка JQuery.
Для меня это большой плюс, т.к. громоздкие циклы с for теперь можно заменить на всего 1 строку кода.
Естественно мы раньше и сами могли прицепить его для собственного удобства, но это легко было бы проверить со стороны сервера и, соответственно, привлечь внимание к персонажу.

Что использую при тестах:
- IE 11. Его консоль и проводник DOM просто шикарны.
- (Please log in or register to see this URL)
- описание (Please log in or register to see this URL)

Постановка задачи:
1) Если находимся на клетке со сторожем - найти сторожа и нажать на него.
2) Если висит меню с выбором действий со сторожем - нажать Поговорить.
3) Сам разговор
4) Если уже поговорили - идти дальше.

Решение пункта 1
При помощи "Проводник DOM" легко найти, что код Сторжа выглядит таким образом:

<map name="ObjectsMap" id="ObjectsMap"><area title="Сторож могил" href="javascript:void(0)" coords="132,41,219,202"></map>

Это тэг 'area' в главном фрэйме, в title которого содержится слово сторож.
Используя синтаксис jquery поиск этого тэга можно записать таким образом:

$('area[title*="Сторож"]',get_mainframe().document)

Первый параметр - это селектор (Что искать), второй параметр - это контекст(Где начинать поиск).

Если вы выполнте данный код в консоли, то увидите, что будет возвращен объект, содержащий массив найденных реультатов, к которым можно обращаться по индексу ([0],[1]...[index]) и свойство length, указывающее на количество найденных объектов.

Результирующий код для пункта 1:

var storozh = $('area',get_mainframe().document).filter('[title*="Сторож"]');
if(storozh.length > 0) { storozh[0].click(); }

Примечание: Если на клетке было бы два сторожа, можно было бы кликнуть по второму storozh[1].click();

Решение пункта 2
До момента нажатия на сторожа, меню с "Поговорить" не существует в DOM и к нему нельзя обратиться.
После нажатия данное меню выглядит следующим образом:

<div id="pmenu" style="left: 195px; top: 141px; height: auto; overflow: visible; display: block; visibility: visible; -ms-overflow-y: visible;">
<a onclick="return p_action('dialog=gy_gravedigger_default&amp;use','1.4.10.71-77')" href="#">Поговорить</a><br>
<input name="close" style="width: 16px; height: 16px; vertical-align: middle;" onclick="closemenu(); return false;" type="submit" value="X"></div>

Меню - тэг div с id pmenu.

Код нахождения:

$('#pmenu',get_mainframe().document)

Но само меню нам не важно - нам важна ссылка на Поговорить, внутри данного меню.

Код нахождения ссылки "Поговорить":

$('#pmenu',get_mainframe().document).find('a:contains("Поговорить")')

Объединяем решение двух пунктов:

var talk_link = $('#pmenu',get_mainframe().document).find('a:contains("Поговорить")');
if(talk_link.lenght > 0)
    { talk_link[0].click();}
else
    {
        var storozh = $('area',get_mainframe().document).filter('[title*="Сторож"]');
        if(storozh.length > 0) { storozh[0].click(); }
    }

Решение пункта 3:
Это решается плагинами. На форуме где-то были, но искать сейчас некогда sad

Решение пункта 4:
А вот здесь уже то, что нельзя протестировать в IE, т.к. используются методы самого бота.

Псевдокод:

if(Поговорили?){ Поговорили=false; Walk("rr"); }else{ Поговорить и присвоить значение переменной Поговорили=true;}

Для реализации буду использовать методы external.InitVal(key,val), external.SetVal(key,val), external.GetVal(key).
При помощи данных методов доступ к переменной можно выполнить и из плагинов, и из маршрутов.
Существовать переменная будет до полного перезапуска бота.

Готовый(почти) код:

external.InitVal("storozh_talked",false);
if(external.GetVal("storozh_talked") == true)
    {
        external.SetVal("storozh_talked",false); Walk("rr");
    }
else
    {
        Поговорить;
        external.SetVal("storozh_talked",true);
    }

Остаётся объединить решения для 1, 2 и 4-го пункта:

external.InitVal("storozh_talked",false);
if(external.GetVal("storozh_talked") == true)
    {
        external.SetVal("storozh_talked",false);
        Walk("rr");
    }
else
    {
        var talk_link = $('#pmenu',get_mainframe().document).find('a:contains("Поговорить")');
        if(talk_link.lenght > 0)
            {
                external.SetVal("storozh_talked",true);
                talk_link[0].click();
            }
        else
            {
                var storozh = $('area',get_mainframe().document).filter('[title*="Сторож"]');
                if(storozh.length > 0) { storozh[0].click(); }
            }
    }

   
Хочу обратить внимание, что строки external.SetVal("storozh_talked",true) и external.SetVal("storozh_talked",false) здесь не обязательны, т.к. вы можете задать эти значения внутри плагина для диалога.

Собственно запись кода в одну строку, чтобы использовать в маршруте:

external.InitVal("storozh_talked",false); if(external.GetVal("storozh_talked") == true) { external.SetVal("storozh_talked",false); Walk("rr"); } else { var talk_link = $('#pmenu',get_mainframe().document).find('a:contains("Поговорить")'); if(talk_link.lenght > 0)    { external.SetVal("storozh_talked",true); talk_link[0].click(); } else { var storozh = $('area',get_mainframe().document).filter('[title*="Сторож"]');    if(storozh.length > 0) { storozh[0].click(); } } }
Software is like sex: it's better when it's free! © LinusTorvalds

Re: JQuery на примере начала диалога в Некровиле

Спасибо.

3

Re: JQuery на примере начала диалога в Некровиле

А можно ли как-то извратиться и "палить" ботов по факту использования JQuery?

Например (не пинать сильно, фантазирую, не знаю технической стороны вопроса):
1) какую-нить описанного выше функцию поиска в JQuery переопределить на $$
2) поменять в скриптах БК $ -> $$
3) и логировать всех, кто вызывает старую $, выполняя при этом всё что ожидается от функции.

Если да, то может всё же остаться на громозких фор-ах в плагинах?

(Please log in or register to see this URL)

4

Re: JQuery на примере начала диалога в Некровиле

Переопределять функции на рабочем проекте из-за пары десятков ботов...брр...я бы не стал.

Software is like sex: it's better when it's free! © LinusTorvalds