Десять уроков скриптинга (Урок 5)

Materials, references, tutorials

Moderators: Murderator+, Murderator

Post Reply
omi4
Posts: 457
Joined: 2005-07-10 21:53:05

Десять уроков скриптинга (Урок 5)

Post by omi4 »

Урок 5. Работа с журналом инжекта

Пока писал, понял… писатель из меня никакой. Может, кто допишет.
А пока пользуемся тем что есть


Напишем простую программку. Она открывает банк и мешочек в нем

Code: Select all

UO.Say("Bank") ;
UO.UseObject(0x01258856) ;


Пробуем, банк откроется, а вот мешочек нет. Дело в том, что ответ от сервера придет не мгновенно.
Переделаем...

Code: Select all

UO.Say("Bank") ;
wait(1000)
UO.UseObject(0x01258856) ;


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

Code: Select all

UO.Say("Bank") ;
CheckLag()
UO.UseObject(0x01258856) ;


Вот и сама функция.

Code: Select all

sub CheckLag()
   UO.DeleteJournal() ; вытрем все сообщения в журнале (Inj, но не клиента)
   UO.Click('backpack') ; одиночный клик по вашему backpack
;       ждем сообщения в журнале
   repeat
      wait(100)
   until UO.InJournal("Backpack")
;       этот цикл завершится, если это сообщение появится.... замечу "Backpack" и "backpack"
;       регистр важен Пишите точно что ждете
end sub


Многие с невероятным рвением тут же заменят все wait(ххх) на CheckLag(). ЧТО в корне не правильно
И точно не круто. Эта замечательная функция создана вовсе ни как универсальная динамическая пауза.
И у wait(ххх) есть свое назначение

Code: Select all

UO.DeleteJournal() ; вытрем все сообщения в журнале
UO.Say("Bank") ;
;       ждем сообщения в журнале
repeat
   wait(100)
until UO.InJournal("your Bank Box")
;       открываем мешок
UO.UseObject(0x01258856) ;
CheckLag() ; тут уместно так как мешок нам не сообщит что открыт


Теперь все пашет как часы. Это только на первый взгляд. Все рухнет, если мы не у банка и нет мешочка.
А любая программа считается рабочей пока не найдены условия когда она работать не сможет...
А они найдены. Далее правьте сами....

Рассмотрим теперь команды

Вот эта наверное самая главная

showjournal отобразить журнал Injection
Синтакс: ,showjournal [lines_num]
none uo.showjournal([lines_num])
Отображает в текстовом окне последние lines_num строк настоящего журнала Injection (по умолчанию 10).


Забиндим ее на клаву.. И будем всегда готовы ее нажать.
Только во время выполнения скрипта ее нажатие без смыслено по причине вот этой команды

DeleteJournal Очистка журнала
Синтакс: none uo.DeleteJournal()
Очищает журнал Injection. Учтите что журнал един для всех скриптов запущенных в данном экземпляре инжекта/клиента.
Команда выполняется чтобы отсечь уже отработанные варианты для команды InJournal


По этой причине будем чистить журнал не напалмом, а скальпелем

Code: Select all

sub CheckLag()
   DeleteJournal("Backpack") ; вытрим ТОЛЬКО нужные нам сообщения в журнале
   UO.Click('backpack') ; одиночный клик по вашему backpack
;       ждем сообщения в журнале
   repeat
      wait(100)
   until UO.InJournal("Backpack")
end sub


Вот скальпель

Code: Select all

sub DeleteJournal(msg) ; msg это параметр, см. выше как его передают
   var nom=UO.InJournal(msg) ; ищем сообщение и в переменную его
   if nom>0 then
      UO.SetJournalLine(Nom - 1," ----- 8< ----- ") ; подменим сообщение
      DeleteJournal(msg) ; вызов функцией самой себя, рекурсия
   endif
endsub


InJournal Поиск в журнале текста
Синтакс: number uo.InJournal(text)
Ищет в журнале Injection строку, в которой встречается text, и возвращает её номер плюс 1, или возвращает 0 если
такая строка с момента последнего удаления журнала DeleteJournal не обнаружена. Номер может быть использован в
дальнейшем для функций Journal, JournalSerial, SetJournalLine (не забыть отнять единицу).
Максимальная длина журнала на данный момент 100 строк. Просмотреть последние строки журнала можно командой showjournal.


SetJournalLine Строка журнала: перезапись
Синтакс: none uo.SetJournalLine(number,text)
Перезаписывает текст в строке журнала номер number новым текстом text. Получить текст можно командой Journal.


Вот еще важная команда, думаю что в ее описании достаточный пример

JournalSerial Обьект связаный со строкой журнала
Синтакс: object uo.JournalSerial(number)
Возвращает сериал обьекта object связаного со строкой журнала номер number. Обычно это обьект, который произнёс
данную строку. Системные сообщения имеют обычно сериал 0x01010101. Для чтения данной строки используется Journal.
Так как функция Injournal возвращает номер строки в журнале +1, то можно воспользоваться например подобной комбинацией:


Code: Select all

var name=uo.GetName(uo.JournalSerial(uo.InJournal("хавчик")-1))
if name<>"" then
 uo.print(name+", хочешь кушать? :)")


Устаревшие команды .. Так для общего развития

LastMessage Последняя строка журнала
Синтакс: text uo.LastMessage()
Возвращает последнюю строку журнала Injection. Journal(0) возвращает то же что и LastMessage. Предпочтительно
использовать функцию InJournal для проверок в журнале.


Journal Строка журнала
Синтакс: text uo.Journal(number)
Возвращает строку журнала Injection номер number. Journal(0) возвращает то же что и LastMessage. Предпочтительно
использовать функцию InJournal для проверок в журнале.


Теперь рассмотрим более подробно приемы работы с журналом..

Вот скрипт который делает ключи.
Ждет сообщения сделал - не сделал

Code: Select all

sub Tinker()
   UO.CancelMenu()
   UO.AutoMenu('Tinkering','Keys')
   UO.AutoMenu('Keys','Iron key')
   repeat
      DeleteJournal("You put")
      DeleteJournal("fail")
      UO.Usetype(0x1EBC)
      repeat
         wait(100)
      until UO.InJournal("You put") or UO.InJournal("fail")
   until UO.Dead()
end sub


Вроде все работает, с максимальной скоростью, только если инструмент разрушится .... Зависнем

Code: Select all

sub Tinker()
   var LastTimer
   UO.CancelMenu()
   UO.AutoMenu('Tinkering','Keys')
   UO.AutoMenu('Keys','Iron key')
   repeat
      if UO.Count(0x1BEF) and UO.Count(0x1EBC) then
         DeleteJournal("You put")
         DeleteJournal("fail")
         DeleteJournal("You broke your tools")
         LastTimer=UO.Timer()
         UO.Usetype(0x1EBC)
         repeat
            wait(100)
         until UO.InJournal("You put|fail|You broke your tools") or UO.Timer()>LastTimer+50
      else
         UO.CancelMenu()
         return
      endif
   until UO.Dead()
end sub


Изменения. Скрипт теперь в формате инжи 505.хх Добавлено сообщение инструменту кирдык.
Добавлен таймер для исключения зависания. Проверка возможности крафта и выход из цикла.
Leo
Expert!
Posts: 791
Joined: 2005-01-15 19:15:05
Location: Dragon World
Contact:

Post by Leo »

Вполне сносно написал, мне понравилось. Молодец.
HOBOK
Posts: 5
Joined: 2004-12-30 12:43:07
Contact:

Post by HOBOK »

еще бы кто первые уроки показал, как скрипты запустить с инжекта или выполнить простейшие команды, буду очень признателен
Leo
Expert!
Posts: 791
Joined: 2005-01-15 19:15:05
Location: Dragon World
Contact:

Post by Leo »

В этом разделе есть такое.
Lord
Posts: 56
Joined: 2005-01-14 20:05:16
Contact:

Post by Lord »

А почему пропущен урок 4? Когда он появиться?
ZIL
Posts: 8
Joined: 2005-09-04 15:14:21

Post by ZIL »

Задам этот вопрос в этом топике.

Захотел я написать скрипт, который будет копать и когда будет выкапывать (Iron, Rusty, Copper), то будет сразу их выбрасывать на землю. И я столкнулся с большой проблемой - как обозначить руду, ведь он с одинаковой графикой каждая!
Попытался через цвет - не получилось!

Может я ошибаюсь? Помогите

VAR Iron = '?'
VAR Rusty = '?'
VAR Copper = '?'
flake
Expert!
Posts: 746
Joined: 2004-08-11 23:56:17
Location: The Citadel
Contact:

Post by flake »

Должно получаться через цвет.
uo.findtype( 'type', 'color' )
ZIL
Posts: 8
Joined: 2005-09-04 15:14:21

Post by ZIL »

ЧУДЕСА!!! Получилось!
:D Спасибо вам!


Жду 4 урок!!!!
Ner-Zul
Posts: 12
Joined: 2005-08-08 14:02:17

Post by Ner-Zul »

когда будут ещё уроки то? :( я уже заждался нафиг :( даёш народу ещё уроков???
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Ner-Zul wrote:когда будут ещё уроки то? :( я уже заждался нафиг :( даёш народу ещё уроков???

А чего Вам не ясно? Скажите тему - опишем.
Ner-Zul
Posts: 12
Joined: 2005-08-08 14:02:17

Post by Ner-Zul »

в каком то из первых уроков был список тем и уроков которые вы хотели написать :) вот плиз всё по этому списку :)
Edred
Expert!
Posts: 2544
Joined: 2004-04-03 17:36:29
Location: Saint-Petersburg

Post by Edred »

По причинам, от меня не зависящим, отсутствовал в инете семь месяцев. Вернулся, но Уроки врядли в ближ время буду писать.
Ner-Zul
Posts: 12
Joined: 2005-08-08 14:02:17

Post by Ner-Zul »

кто ж как не ты? :( ну вот остались мы без уроков :(
Loschen
Posts: 2
Joined: 2006-02-06 01:28:40

Post by Loschen »

очень жаль :cry:
Edred
Expert!
Posts: 2544
Joined: 2004-04-03 17:36:29
Location: Saint-Petersburg

Post by Edred »

Ner-Zul wrote:кто ж как не ты? :( ну вот остались мы без уроков :(


Я не говорю, что не буду их писать вообще. Я говорю, что не буду их писать в ближ. время. Ближ. время - это месяца два, максимум три. Потом все равно снова начну играть, ну и на уроки время найдется.
Ner-Zul
Posts: 12
Joined: 2005-08-08 14:02:17

Post by Ner-Zul »

как же это долго :(
klim_killer
Posts: 20
Joined: 2006-03-27 00:03:20

Re: Десять уроков скриптинга (Урок 5)

Post by klim_killer »

Подскажите по работе с журналом. Вот так выглядит скрипт:
sub kopat()
var where_x,where_y,coords,i,Pickaxe
InfoLogs()
UO.DeleteJournal()
where_x=uo.getx()
where_y=uo.gety()
for i=-2 to 2
uo.findtype('0x0E85')
Pickaxe=uo.getserial("finditem")
if not uo.objatlayer('Rhand') then
uo.equip('Rhand', Pickaxe)
wait(100)
end if
uo.print("Òàéë "+str(i+3)+"/5")
coords="waittargettile "+" 1343 "+str(where_x)+" "+str(where_y+i)+" 0"
uo.exec(coords)
uo.deletejournal()
uo.useobject(Pickaxe) # Çäåñü ïðîïèñûâàåì òèï êèðêè
if uo.injournal("tools") then
wait (500)
next
end if
while (not (UO.InJournal("stop mining") or UO.InJournal("far") or UO.InJournal("must")))
wait(500)
wend
uo.unequip('Rhand')
wait(100)
next
end sub


Но по пещере ходит чар, и кричит все ключевые слова. в связи с этим эффективность скрипта падает в разы. Можно ли каким либо образом указать, цвет сообщения, или указать, что это системные?

Заранее спасибо!
Mirage
Posts: 2802
Joined: 2009-05-28 09:58:28
Location: Иваново
Contact:

Re: Десять уроков скриптинга (Урок 5)

Post by Mirage »

Да это старый прикол, постоянно так тролили нубоботов :roll:
Тебе нужны 2 команды.

Простой скрипт для примера - по нему конструкция станет ясна я думаю.


Code: Select all

sub main()
   var text = uo.injournal("Where would you like to fish?")  ; ключевая фраза, через | можно писать сразу несколько сообщений типа "You put|is impossible|in your pack"
   UO.DeleteJournal()
   repeat
      wait(100)
   until text && UO.JournalColor(text) == '0x03B2' && UO.JournalSerial(text-1) == '0xFFFFFFFF' ; проверка сработает только на серое и на системное сообщение
end sub

sub text_info() ; скрипт для сбора информации по последний 10 сообщениям в журнале. Показывает серийник произнесшего, цвет сообщения и само сообщение.
   var i
   uo.textclear()
   for i=10 to 0 step -1
      uo.textprint(uo.JournalSerial(i)+"| "+uo.JournalColor(i)+"| "+uo.Journal(i))
   next
   uo.textopen()
end sub

Если сообщение произнесет кто то даже подменив цвет речи то скрипт все равно определит его серийник отличный от системного и не сработает.
Вариант старый но рабочий. Сейчас в 15 инжекте новые фишки появились но я пользуюсь старой пока что.


PS у фразы *Ктототам is attacking you* серийник атакующего соответственно должно быть UO.JournalSerial(text-1) <> '0xFFFFFFFF'
Post Reply