Читы для RF Online (Чит Портал Rising Force Online) Баги,Хаки,Чит Программы rfhuck.ru.

Объявление

Чит Портал RF Online и Других MMORPG Игр
Главный Админ

Модераторы

Support

Рейтинг Ролевых Ресурсов game100rus.com Gaming Servers TOP

Сделать стартовой Добавить в Избранное

Добавить в закладки

 

html counterсчетчик посетителей сайта

Все читаем правила форума.По поводу покупок писать мне в ЛС или в ICQ 352-259

 

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Подробное описание WPF

Сообщений 1 страница 11 из 11

1

[!] >>> PPC by Sauron, документация на PPC <<< [!]

1.
WP PPC - Wicked Patcher

или как пустить поезд по нашим рельсам.

Внимание! после версии wp655f, WP меняет свое название, и меняет набор модулей.

Wicked Patcher (после wp655f версии) содержит три модуля:

1. PPC -- Proxy Packed Converter - прокси сервер и скриптовый пакет-конвертер
2. MI -- Multi Injector - Мульти-инжектор (v.4.0)
3. SE -- Server Emulator - эмулятор серверов, (еще не закончен)

Здесь речь идет о PPC.

PPC = Proxy Packet Converter, что примерно означает - Прокси, Пакетный конвертер.

PPC предназначен для перехвата трафика TPC вообще , и трафика между клиентом (ботом) и сервером LA2/RFO (и других) в частности.
Так же , продвинутым контролем над этим трафиком , включая полное оперативное вмешательство в протокол соединения и изменение трафика по своему усмотрению с помощью гибкой системы скриптов.

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

PPC является первой в своем виде программой, где с помощью скриптов можно 'кодировать' алгоритм изменения трафика, в данный момент уже появилось много подражателей моей идеи (теже хлапексы, l2пакетхаки и прочие ), что радует, так как это подтверждает состоятельность моей идеи как факта.

Но, WP PPC является на сегодняшний момент единственной реально МНОГОПОТОЧНОЙ программой подобного рода.
Т.е. работает с большим количеством независимых друг от друга соединений.

Взять PPC можно в составе последней версии WP с моего сайта http://saur.x33.ru

Permeo Security Driver - http://www.satspace.ru/uploaded/perm...er.v.4.2.6.rar

В состав PPC входит:
1. Два прокси сервера с гибким настраиваемым протоколом , по умолчанию Socks 5.
Каждый из серверов многопоточный, то есть , каждый из серверов может держать несколько соединений одновременно. В принципе не обязательно он и Socks, так как прокси протокол написан на скрипте, а его можно изменять под свои нужды.

2. Продвинутый Автологгер (далее по тексту - AL),
предназначенный для протоколирования и автоматической записи пакетов трафика. Управляется как в ручную, так и через скрипты (включая способы шифрации и прочее)
Умеет автоматически определять является ли этот трафик последствием LA2 соединения, и, исходя из этого автоматически дешифрует (и шифрует обратно) пакеты LA2.
Так же, автоматически определяет разные способы работы с не LA2-трафиком, например RFO.
Возможно пользовательское дополнение своего типа трафика в определитель AL.

3. Скрипт-машина. (далее по тексту - СМ),
Позволяет гибко изменять пакеты трафика, путем написания скрипт-программ.
Это позволяет делать с пакетами все , что захотим.
Функции СМ все время дополняются и улучшаются, о них далее по тексту.
Каждый принятый пакет проходит последовательно до трех скриптов.
[принятый пакет] >> [дешифрация] >> [скрипт1] >> [скрипт2] >> [скрипт3] >> [шифрация ] >> [пакет на отправление]

I) Соединение клиента с сервером.

http://x33.ru/saur/upload/PPC/k1a.gif

Обычно Трафик между клиентом (ботом) и сервером происходит напрямую, т.е. клиент сразу лезет на заданный IP и порт сервера.
(для LA2 трафика: в боте прописывается в set.ini , а в клиенте в l2.ini)

Соединение через прокси ,у бота LA2 (walker), происходит на адрес указанный в самом боте, а он уже по прокси-протоколу передает ему адрес куда прокси сервер должен соединятся дальше на сервер.

Другими словами, перенаправить трафик бота LA2 (Walker) просто, так как у него в опциях есть настройки работы через socks5 прокси, а PPC это и есть sock5 прокси (по умолчанию)
Достаточно сделать следующее , чтобы бот соединялся через PPC :

http://x33.ru/saur/upload/PPC/k2.gif

127.0.0.1 ставить обязательно, а вот порт надо указывать такой, какой указываем в один из серверов PPC:

http://x33.ru/saur/upload/PPC/k3.gif

А чтобы по 10 раз не забивать адрес, то сохраните в опциях волкера настройки.
НО! Внимание! волкер глючит при лоаде настроек - поэтому вызывайте настройки в волкере два раза подрят - это исключит глюки при загрузки сохраненых опций волкера.

С клиентом сложнее, так как у него нету встроенной функции соединения через прокси, и для этого приходится пользоваться сторонними программами проксификаторами.
Permeo Security Driver и Proxifier являются стандартными проксификаторами, инструкций по использованию полно в интернете.

Внимание!
В последних версих WP PPC добавлен модуль Multi Injector.
Он позволяет перенаправлять программы без использования сторонних проксификаторов.
В WP PPC по умолчанию уже находятся записи MI для перехвата LA2 и RFO:
http://x33.ru/saur/upload/PPC/WPMIdef.gif

в случае LA2 клиента надо включить галочку на l2.exe (l2.dll в случае левых загрузчиков)
внимание! GG официального сервера Lineage2.com обнаруживает данный перехват
(если получится обойтись без драйвера, то скоро эта проблема будет решена)

в случае RFO включаем галочки на rf.exe и rf_online.bin (в rf.exe внедряем DLL помогающую перехватывать rf_online.bin)

Разумеется, чтобы MI работал с процессами, необходимо так же включить кнопку:
http://x33.ru/saur/upload/PPC/k15.gif

Для других программ создаются аналогичные записи пользователем.
Более полная документация по MI (Multi Injector) в процессе написания ..


2.

Настроив соединение, настраиваем PPC:

II) Настройки PPC

В начале , надо определить порт , на который зацепится наш прокси сервер.
Так как их два, то можем поставить два номера порта подряд, по умолчанию в PPC это 1777 и 1778. Но можно выбрать любые не занятые номера.
Обычно нужен только один сервер, поэтому выбираем любой из двух и нажимаем кнопку включения (с желтым солнышком).

http://saur.x33.ru/upload/PPC/k3.gif

Если появилось предупреждение о том, что порт занят, ставим другой номер порта.
! Очень важно правильно настроить фаерволл, разрешив WP PPC запускать сервера на локальном компьютере, а так же, разрешить выход в интернет. !

Нажав на кнопку [ * P-C панель] открываем главную панель PPC:

Тут изображена первая закладка главной панели PPC:

http://saur.x33.ru/upload/PPC/k4.gif

На ней, вверху, находится список задания условий для соединений, а в углу права внизу опции.

На этой закладке устанавливается привязка скриптов по условиям.
Условие может быть :
Имя сервера - у соединения должно совпасть имя сервера
Host / IP - у соединения должно совпасть Host или IP
Port - у соединения должен совпасть Port

Галочками ставятся либо какое ни будь одно условие либо комбинацию из них.
В списке ниже, устанавливается от 1 до 3 скриптов для данной привязки.

! Нужно помнить, что если мы поставим порт 2106, то указанные скрипты в этой записи запустятся ТОЛЬКО на этот порт, то есть только на время работы Логин сервера, следовательно самым разумным ставить только Host /IP ! Для этого должна стоять только одна галочка Host/IP на данном условии, и в поле 'Выбор по:' так же должно стоять IP нашего сервера.

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

Имена серверов берутся из обнаруженных в памяти ботов - эти имена мы прописываем в set.ini бота. Имена в условие запуска скриптов лучше не ставить, для начала достаточно только IP.

Например, мы хотим установить скрипт позволяющий боту нормально двигаться на ява-серверах, l2j. Пусть IP сервера у нас будет 195.152.91.110 , название скрипта - demo2.sc (скрипт уже есть в дистрибутиве).

Тогда все должно выглядеть так :

http://saur.x33.ru/upload/PPC/k5a.gif

(1) мы добавляем кнопкой [Добавить] сервер в список , можно с любым именем, например [Все имена].
(2) убедившись, что появившаяся запись отмечена (выбрана) , мы вводим IP в первом поле над кнопкой [OK]. (4) Далее нажимаем [OK].
(3) отмечаем галочку [x] Host/IP
(4) Далее нажимаем [OK].
(5) После этого, указываем какие скрипты будут запускаться при этих условиях.

Теперь нажав на пустое место под записью, чтобы снять выделение, мы должны увидеть раскраску полей . Если первое поле с номером зеленое , и нет ни одного поля с красным, значит, эта запись будет использоваться, иначе, она игнорируется (когда есть хоть одно красное поле - значит данные не до конца введены)

http://saur.x33.ru/upload/PPC/k5b.gif

Теперь, если будет произведен коннект по такому IP, то на этот коннект будут запущены скрипты ниже (список из трех строчек).
Мы поставили 1 скрипт, но можно ставить до трех. Они будут выполняться по очереди , отдавая друг другу пакет по цепочке, после последнего он зашифруется и отправится.


3.
http://saur.x33.ru/img/t.gif

Ниже на этой же закладке мы видим опции (они стоят в данный момент по умолчанию):

http://saur.x33.ru/upload/PPC/k6.gif

'[ ] без скриптов не пропускать '- если тут будет галочка, то соединение не попавшее в список выбора скриптов, (либо если запись выбора не полная, есть красные поля), то это соединение не будет установлено.
'[x] Автостарт Auto Logger'a (AL)' - AL работает сразу, с первым пакетом. Иначе он будет ждать нажатия кнопки [On/Off] см. закладку Auto Logger. (либо когда из скрипта будет команда)
'Пакетов сохранять [ 500 ]' - Так как сохранить весь трафик не возможно (будет слишком накладно), то здесь ставится максимально количество пакетов на одно соединение, когда количество в работающем AL превысит установленное, ранние (верхние) пакеты будут удаляться, а последние добавляться . Например , если стоит 500, но при работающем AL прошло 850 пакетов, то сохранятся пакеты с 350 по 850. Значения этой опции могут быть от 100 до 3000 (пока так)
'Макс. Размер файла AL [ 3 ] Мег.' - Все собранные пакеты (если AL был включен хоть на время), при разрыве соединения сохраняются в файл 'autolog.dat', туда добавляются все пакеты пока файл не превысит указанный размер тут. Далее файл переименовывается в 'autolog.dat~.dat' заменяя старый если был, и начинается новый фал. 3 мегабайта это достаточно, но кому мало, можно поставить до 10 (пока так). (см. закладку Auto Logger.)
'Тип АвтоПарсинга пакетов [1]' - значение 1 - означает автоматическое определение разделения 'склеенных' пакетов. Значение 0 - не парсить пакеты , значение 2 - делить по факту размера в первых двух байтов. По умолчанию значение 1 .
Значение можно изменять 'на лету' в скриптах. Допустим, зная, что первые пакеты - это пакеты защиты, мы ставим значение в 0 (в скриптах) и работаем, эмулируя защиту, когда приходит время протоколу la2 мы ставим 2.(в скриптах)
'Тип PDecode пакетов [1]' - значение 1 - автоматическое определение дешифрации пакетов гейм сервера, 0 - выключено ! В этом случае пакеты будут идти, как есть - не дешифрованные.
2 - включен тип декодировки пакетов для la2 'GSDecode' (дешифроваться будет, только, если определятся ключи). Оставим 1.
'Таймаут по не активности [0]' - в секундах. Любое соединение, через которое в течении установленного тут времени не было ни одного пакета - рвется.
0 - таймаут выключен. (по умолчанию)

Все опции PPC запоминаются при выходе из WP PPC.

Левее опций мы видим установки скрипта для Прокси протокола, по умолчанию запускается скрипт почти аналогичный тому что можно посмотреть в файле 'wpsc\socks5.sc'.

III) Скрипты.

Запустив бота можно переключиться на следующую закладку (Links Online):

Мы видим онлайн соединение нашего бота.
!!! (Далее мы будет разбирать реальное соединение, и там другое IP, отличающееся от того, что мы указывали выше, скрины переделывать мне уже влом. Будем считать, что IP было то, что будем видеть дальше)

http://saur.x33.ru/upload/PPC/k7.gif

Ниже списка мы видим закладки 'SysLog' , 'INFO' и 'Send Raw Packet'
'Syslog' это системный лог, туда пишутся глобальные сообщения об ошибках ( а так же сообщения от прокси скрипта).
'INFO' - это информация об активном соединении.
Там , кстати , можно всегда узнать реальный протокол =) (в данном случае 659)
'Send Raw Packet' - возможность послать пакет вручную, без скрипта.
в верхнем поле вводится пакет в виде двухсимвольных шестнадцатеричных байт разделенных пробелом, выбирается активное соединение и нажимается кнопка отсылки на сервер или на клиент.

В низу справа под списком Онлайн соединений мы видим кнопку [ Terminate link ]
Этой кнопкой мы всегда сможет разорвать соединение.

Кнопка с солнышком и надписью 'редактировать скрипты онлайн' активна только при выборе активного соединения из списка.
! Нажав не него мы получаем дополнительную закладку !!! с именем сервера и его Host/IP

http://saur.x33.ru/upload/PPC/k8.gif

На ней мы видим редакторы для трех скриптов и скрипт лог для данного соединения,
Скрипты можно оперативно, не разрывая связи править, записывать в память/ на диск/загружать...
Script Log - туда записываются сообщения скриптов для каждого пакета.

Вспомним, что скрипты, все три, вызываются по очереди для каждого пакета, и после них пакет шифруется и отправляется дальше, куда он и шел в начале.
Далее , следующий пакет трафика опять идет на скрипты и так далее: (и пакеты от сервера и от клиента все идут через скрипты, а уже в скриптах можно по переменной _gFromServ определить откуда пакет)

Кнопки Read/Write - читают/пишут скрипт в памяти, после исправления скрипта, чтобы он исправился в памяти надо нажать Write - с этого момента следующий пакет сразу попадет на исправленный скрипт. Read - читает пакет из памяти.
Кнопки Load/Save - загружают/записывают, соответственно, скрипт из/в файл.
Если воспользовались кнопкой Load, то после загрузки, надо нажать Write, чтобы скрипт из редактора записался в память на пакеты. Т.е. как и при редактировании.
В закладке ScriptLog мы видим сообщения от скриптов (функции типа Writelog() ) и ошибки скриптов. Если ошибка будет фатальна для соединения, то произойдет разъединение и вся закладка скриптов закроется. НО! Если был включен (по умолчанию включен, вспомним опции) Auto Logger, то все это запишется в лог , и сообщения скриптов тоже, так что мы всегда узнаем что там случилось.



4.
http://saur.x33.ru/img/t.gif

IV) Auto Logger. (AL)

Не прерывая соединение бота, можно переключиться на закладку 'Auto Logger'

Мы видим Список соединений сверху, слева список пакетов.
Нажимая кнопки 'Online'/'Log File'справа от списка соединений , мы можем видеть как запущенные в данный момент соединения, так и записанные в файл.

Когда нажат режим 'Online' , в списке вверху, раз в секунду, обновляются запущенные в данный момент соединения, и выбрав одно , можно увидеть пакеты данного соединения в левом списке.
Кнопкой Start log/Stop log мы может останавливать и заново запускать автолог для каждого соединения.
Нажав на любой пакет из списка пакетов, можно видеть содержимое пакета.
'S>c ' означает , что пакет идет в направлении от сервера к клиенту.

Сохраняется только определенное количество пакетов, максимум 3000 пакетов (см. опции)
При разрыве соединения, лог этого соединения записывается в файл.

http://saur.x33.ru/upload/PPC/k9.gif

В случае, если пакет был исправен скриптом, или было некое сообщение из скриптов, то появляются дополнительные закладки:

http://saur.x33.ru/upload/PPC/k10.gif

Тут пакет идет с клиента через скрипт , закладка C>(scr) , далее пакет из скрипта иде на сервер (scr)>S.

Закладка Scripts log появляется, когда скрипт выдает какое либо сообщение (к примеру ф-цией Writelog())

Есть еще закладка (scr)<>(с)/(s) это закладка отражает все дополнительные пакеты, которые были переданы из скриптов при обработке данного пакета.

отображение пакетов в списке пакетов :
1. первая скобка '>':
S>c , C>s - передача текущего пакета без изменения.
2. первая скобка '}':
S}c , C}s - передача пакета с изменениями (закладки S>(scr) C>(scr) (scr)>S (scr)>C )
3. вторая скобка '>':
S>>c, C>>s - передача текущего пакета без изменений,
но были посланы дополнительно пакеты. (закладка (scr)<>(c/s))
S}>c, C}> - передача текущего пакета с изменениями,
и плюс были посланы дополнительные пакеты (закладки соответствуют)
4. значек в конце '~':
S>c~, S}>c~, S>>c~ .. - присуствуют сообщения из скриптов (закладка Script Log)
5. символ 'x':
S>x , C>x, S>>x, S}x - текущий пакет блокирован.
6. первый значек '='
=>c, =>s - пакет отправлен вручную, минуя скрипт. ('Links Online' / 'Send Raw Packet')
7. первый значек 'T' : (см. '_gS3OnTimer' и gSys('S3timer'))
сообщения или дополнительные пакеты из скрипта3 запущенного по таймеру:
T>~ - присуствуют сообщения из скрипта3 по таймеру.
T>> T>>~ - были посланы дополнительные пакеты из скрипта3 по таймеру.

В последних версиях дополнено описание пакетов.
Описание пакетов зависит от типа трафика, и устанавливается либо автоматически, либо в ручную на закладке 'Описание'

пример 'раскраски' пакета в зависимости от типов аргументов (и типа трафика, в данном случае это трафик 'LA2'):
http://saur.x33.ru/upload/PPC/k12.gif
цвета заменяемые.
для одного типа аргумента один цвет, но до 5 тонов, чтобы одного типа аргументы не 'склеивались'

Номера пакетов можно переключить на название из описания или обратно:
http://saur.x33.ru/upload/PPC/k13.gif

V) Script Tester

Это отдельный скрипт-движок, для отработки синтаксиса выражений,
от остальной части PPC не зависим и не связан.
Системные переменные почти все отсутствуют, (для отладки инициализировать в ручную)
Можно писать несложные некоторые программки.

При выходе из WP, все , что написано в Script Tester'е будет автоматически сохранено в файле 'ScriptTester.txt'. И при запуске WP опять туда загрузится.

возможность выбирать скрипт-движок:
зависит от расширения файлов скриптов:

'.sc' - WPS, - текстовый файт WPScript
'.fsc' - FS, - текстовый файл FastScript
'.xml' - PFS, - прекомпилированный файл FastScript. (можно создать в Script Tester'e)

В .xml случае (прекомпилированный) файл можно только использовать, но не редактировать.
Так же его очень трудно понять, можно использовать в качестве некоего подобия шифрования скрипта

Прекомпилированный файл будет примерно в 6-9 раз больше текстового, но зато при первичной загрузке (и соответственно компиляции) будет выполняться быстрее.
компиляция происходит только один раз при загрузке, но, например, при количестве строк более 1000 компиляция '.fsc' будет примерно 2 секунды, а компиляция '.xml' будет 100 ms.

Далее, после компиляции, при работе скрипта, разницы в скорости не будет.

Внимание!
Крайне рекомендуется выбирать FS скрипт, так как FS движок более быстр и продвинут, чем WPS.



5.
http://saur.x33.ru/img/t.gif

VI) Функции скрипт-языка WPS.

Внимание!
В WP PPC встроено два разных скрипт-движка, чей синтаксис и ф-ции частично различны.
WPS, как устаревший движок, больше не поддерживается и описан в качестве документации. Используйте только FS движок.
Здесь описан скрипт движок WPS, информация о другом , FS, будет дальше по теме.

Синтаксис скрипт-движка WPS

Синтаксис скрип - языка WPS во многом схож с паскалем, об исключениях ниже.

Поддерживаются следующие операторы:

begin .. end;
if .. then .. else
case ... else end;
For .. to/downto .. do
While .. do
Repeat .. until
continue
break
goto
exit

Переменные автотипизированы, то есть, тип переменной определяется при присваивании , по результату или по первому операнду в выражении (если не ясен результат).
Переменные могут быть переопределены.
Объявленые переменные сохраняются от пакета к пакету в пределах одной сессии (по сути они глобальны для одной сессии)

Самое главное отличие от стандартных языков программирования, это частичное нивелирование определения типов char/byte в выражениях, с одной стороны это очень разгружает скрипт машину, и ускоряет ее в десятки раз, с другой стороны, накладывает ограничения.

Пример определения типа переменной;

c := 'a' ; // тип char;
k := c + 1; // тип сhar, равнозначно k = char( (byte(с)+1) and $ff );
k := 1 + c; // тип int, равнозначно k = byte(с) +1;
k := 0 + c; // тип int, равнозначно простому переводу типа k := byte(c);

пример нарушения правила 'о перестановке слагаемых' =)
zz := 2 + gBuff[1]; // - zz стала int , = (byte(buff[1]) + 2) and $FF;
zz := gBuff[1] + 'a'; // - zz стала строкой, (= 'aa')

Чтобы не было подобных ошибок, советую использовать явное преобразование:
k := byte(c);
k := char(c);

А вот присваивание элементу строки (одномерного массива) будет работает как угодно:
s := '123456'; // буфер - это таже строка.
s[4] := 'G'; // здесь s = '123G56'
s[5] := 60 ; // здесь s = '123G<6'

шестнадцатеричные значения как в паскале:

v := $10; // v = 16;
v := $FFFF; // v = 65535

символ цифрами тоже как в паскале:

c := #97; // c : char = 'a' (97 = $61)
c := #$61; // c :char = 'a' ($61) шестнадцатиречный символ =)

строку можно набрать по разному:

s := 'aaaa1';
s := '#$61+#$61+#97+#97+'1' ; // = 'aaaa1'
доступ к символам/байтам как в массиве с позиции 1 то есть, s[5] = '1'

(немного из старых объяснений:
Brotherhood Of Cheaters - Allcheats.ru - Братство Читеров - Показать сообщение отдельно - WP401F/451R(WP307F) в производстве (не только для ботов) )

функции и процедуры скрипта:

В скрипте можно писать функции и процедуры, синтаксис схож с паскалем.

procedure Name(v1, ... vn); // описание процедуры
begin // тело процедуры

end;

function Name(v1, ... vn); // описание функции
begin // тело функции

result := ... // возвращаемое функцией значение.
end;

процедуры и функции без аргументов описываются так:
procedure Name();
...
function Name();
...

Внимание !! (только для WPS)
Все внешние переменные описанные в главном теле скрипта копируются в тело функции/процедуры, но не изменяются при выходе. За исключением переменных описанных в аргументах.
Системные переменные в том числе. (_gOutBuff присваивать только в главном теле скрипта)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> например, так неправильно: <<<

procedure aaa();
begin
_gOutBuff := _gBuff; // здесь _gOutBuff локальный для этой ф-ции !!
// он копируется из основного, но не изменяет основной.
_gOutBuff[5] := #0;
end;

begin // главное тело скрипта

aaa; // <- вызов функции не изменит _gOutBuff;

end;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> Правильно так: <<

function aaa();
begin
result := _gBuff;
result[5] := #0;
end;

begin // главное тело скрипта

_gOutBuff := aaa; // теперь _gOutBuff установился нормально.

end;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> так тоже правильно: <<

procedure aaa(bf);
begin
bf := _gBuff;
bf[5] := #0;
end;

begin // главное тело скрипта

bf := 0; // определим переменную.
aaa(bf);
_gOutBuff := bf; // теперь _gOutBuff установился нормально.

end;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Массивы.

Одномерные массивы являются набором отдельных переменных.
Объявляется каждый элемент массива отдельно.
например:
a[100] := 10;
- создастся сотый элемент массива a[], но, другие элементы еще не определены.

length(a) - работать не будет, так как каждый элемент массива это отдельная переменная.

Если необходимо сразу весь массив, то , на данный момент, только так :
if _gAbsNumPkt = 1 then begin // если первый пакет, то объявляем переменные.
for i := 1 to 100 do a[i] := 0;
alen := 100; // создадим переменную, где будем держать размер массива.
end;

Строка/буффер тоже определяется как одномерный массив, но имеет свойства string.

Двух мерные массивы создавать нельзя, но можно создавать массивы строк/буферов.
например:
a[1] := _gBuff;
if length(a[1]) >2) then ID := a[1][3]; // если размер пакета больше 2, то берм ID пакета

length(a) - даст ошибку.
length(a[1]) - даст размер пакета.

Для целей PPC этого достаточно, так как в скриптмашине сделан упор на быстродействие, а более мощные массивы существенно снижают быстродействие.

Более продвинутые синтаксис и возможности имеет второй скрипт-движок FS, информация о нем будет дальше.

Системные переменные скрипт-движка WPS

Все переменные определенные когда либо в скриптах, действительны для всей сессии.
Кроме этого существуют системные переменные, для входящей и исходящей инф-ции в скриптах. (Только для WPS)

_gBuff :str - входящий буфер (строка) , в нем приходит пакет в скрипты.
_gOutBuff :str - исходящий буфер, это пакет который уйдет дальше по назначению.
Если ничего не присваивать этой переменной, то пакет на выходе будет без изменений.
_gFromServ :bool - возвращает true , если скрипт получил пакет с сервера на клиент.
false - если с клиента на сервер.

_gS3onTimer - возвращает true ('1') если скрипт запущен по таймеру (см. gSys('S3timer'[,time]))

_gS3TimerCount - возвращает счетчик срабатываний таймера с последнего сброса таймера.
при сбрасывани таймера в ноль (выключении - gSys('S3timer',0)) счетчик _gS3TimerCount обнуляется. (_gS3TimerCount только начиная с WP410F)
(см. gSys('S3timer'[,time]))

_gAbsNumPkt :int - абсолютный номер приходящего пакета, нумеруется с 1.

_gStopOnError (bool) по умолчанию false, если установить значение true, то будет разрыв соединения в случае любой ошибки скрипта.
Разрыв будет не сразу, может пройти еще пара пакетов (для лога полезно).

_gServName - строка, с именем сервера, как он определился PPC.
_gServHost - строка, с хостом сервера, если он определился.
_gServIP - int, IP сервера.
_gServPort - int, Port сервера.

_gCWinSock - доступно только в скрипте socks5, тип WinSocketStream.

0

2

6.
http://saur.x33.ru/img/t.gif

VI) Функции скрипт-языка WPS.(продолжение)

Стандартные Функции:

byte(char), char(byte) -прямое преобразование в тип byte или char соответственно.
Внимание! в скрипт-языке FS данный способ преобразования не приемлем.

Функции перевода адреса :
inet_ntoa(addr : int) : str; (стандартная ф-ция.)
inet_addr(s : str) : int64; (стандартная ф-ция.)
inet_addr('127.0.0.1') - вернет целое 16777343 ($100007F)
inet_addr('zzzz') - ошибка, вернет -1 ($FFFFFFFFFFFFFFFF) (64 бит)

_getIPbyHost(s : string) : integer; - возвращает IP адрес по имени хоста.
!использует DNS, задержка в случае отсутствия имени на DNS может достигать до 3 секунд.
возвращает 0 в случае ошибки или если адрес по имени хоста не найден.

Copy(s, inx, count) : str - возвращает подстроку из сткроки 's' начиная с 'inx' номера символа, количеством 'count'. (стандартная ф-ция)
Так же, возвращает из бинарного буфера 's' начиная с 'inx' количеством 'count' байт/символов.
Copy('skjd123lsd',3,2) - вернет 'jd'

Insert(sub, s, idx); - Вставляет подстроку 'sub' в строку 's' начиная с 'idx' позиции.
Строка и субстрока могут быть бинарным буфером/пакетом.

s := '123456';
Insert('zz',s,3);
//теперь s = '12zz3456';

Delete(var str, idx, count) : str - Удаляет подстроку из строки 'str' начиная с 'idx' количеством 'count' символов

pos(subs,s) : int - возвращает индекс , с которого начинается подстрока 'subs' в строке(буфере) 's', либо 0 если такая подстрока не найдена (стандартная ф-ция)
pos('4','FD12345') - вернет 6.

Length(s) : int - возвращает длину строки(буфера) (стандартная ф-ция)
Length('dfgoi') - вернет 5

IntToStr(i) : str - преобразует int в строку . (стандартная ф-ция)
IntToStr(123) - вернет '123';

StrToInt(s) : int - преобразует строку в целое (стандартная ф-ция)
StrToInt('2332') - вернет 2332;
StrToInt('$2332') - вернет 9010 ($2332);
StrToInt('sdsd') - даст ошибку скрипта.

FloatToStr(), StrToFloat() - тоже, что и предыдущие ф-ции , но только с дробными числами.
StrToFloat ('234.2') - вернет 234.2 (стандартная ф-ция)

UpperCase(s), LowerCase(s) - конвертирует все строчные в прописные и наоборот соответственно. (стандартная ф-ция)
UpperCase('AaaaVvvv') - вернет 'AAAAVVVV';

Trim(s) - обрезает ведущие и последние пробелы и символы управления (непечатные). (стандартная ф-ция)
Trim(' a sd ') - вернет 'a sd'

Format(frmstr, a1,...an) : str; - (стандартная ф-ция)
форматированный вывод аргументов a1..an в соответствии со строкой форматирования frmstr.
Функция возвращает отформатированную строку.
'frmstr' - форматирующая строка, это текстовая строка, в которой на нужных местах стоят специальные символы(спецификации), которые определяют, какие и как туда будут подставлены параметры.
'a1,..an' - параметры, каждый параметр соответствует одной спецификации символов в форматирующей строке.

более подробное описание форматирующей строки смотрите ф-ю 'format' в паскале/дельфи (или тут _http://www.helloworld.ru/texts/comp/lang/delphi/delphi5/pril/formstr.htm )
или смотрите 'printf' в c++ (например тут _http://ru.wikipedia.org/wiki/Printf )

Примеры:
x := 100; y := 200;
writelog(format('X в 10ной: %d Y в hex: %x',x,y));
в логе будет запись: 'X в 10ной: 100 Y в hex: C8';
тоже самое: writelog(format('%s %d %s %x','X в 10ной:',x,'Y в hex:',y));

Функции для работы с датой и временем:
Now; Date; Time; DateToStr; StrToDate; TimeToStr; StrToTime ; FormatDateTime;
Описание не даю, они стандартные.

Арифметические ф-ции: (тоже все стандартные)
Abs; Int; Fract; Round; Ceil, Floor, Trunc, Sin, Cos, Tan, ArcSin, ArcCos, ArcTan,
Exp, Ln, IntPower, Sqr, Sqrt, Inc, Dec;
операции : div, mod

Битовые операции:
BitAND, BitOR, BitNOT, BitXOR, SHR , SHL;

7.
http://saur.x33.ru/img/t.gif

VI) Функции скрипт-языка WPS.(продолжение)

Далее не стандартные ф-ции.

ScriptTimeOut(ms), ms = 100..31000. - смена установки таймаута скрипта (от 0.1 до 31 секунд).
Любой скрипт по умолчанию терминируется , если время его работы превышает 1 секунду по умолчанию, _ScriptTimeOut меняет это значение.
В скрипт-тестере можно поставить значение 99999, тогда таймаут не будет отслеживаться
(В пакетных скриптах совсем отключить таймаут нельзя)
Таймауты по неактивности во время действия скрипта не проверяются.

WriteLog(a1,a2,..,an); a1..n - любые переменные; Выводит в лог сообщения либо значения переменных. Лог - для socks -скрипта это Syslog, для пакетных скриптов - свой, Scripts Log. (виден в каждой записи в логе, либо в онлайн редакторе скриптов)
Скрипт-тестер выводит в свой лог.

WriteLogH(a1,a2,,,an); a1..n - любые переменные.
Выводит Int в шестнадцатеричном виде;
Если переменная это строка (Str), то выводится как есть, без изменений.
Удобно для вывода в лог шестнадцатеричных значений с сообщениями.

Например:
WriteLogH(' X координата: ',curx,' Y координата: ',cury);
это равнозначно :
WriteLog(' X координата: ',inttohex(curx,2),' Y координата: ',inttohex(cury,2));

WriteLogHexB(buf[,len]); пишет HexBlock buf'a в виде блока , как это сделано в Autologger'e;

InttoHex(int[,mincount]) : str - вернет целое в шестнадцатеричном представлении (в Hex) в виде строки.
IntTohex($3461EAE) - вернет строку '3461EAE';
IntTohex(7777) - вернет строку '1E61';

BuftoHex(buf : str) : str - переводит каждый байт в Hex;
BuftoHex(#$01+#$02+#$04); - вернет строку '010204'
BuftoHex('aaa') - вернет строку '616161';
BuftoHex(inttostr(7777)) - вернет строку '37373737'

FStr(len, ch) : str; создать и вернуть строку(буфер) размером 'len' и заполнить символом 'ch'.
buf := FStr(1024,'a') - создать буфер 1024 символа и заполнить его символом 'a'.
buf := Fstr(100,0); - создать буфер 100 байт и обнулить его.
ограничение на максимум - 65к =)

HStr(str,[,len]) : buf; // собрать пакет
HPck(str,[,len]) : buf; // собрать пакет и добавить длину автоматом
пакет задается в виде шестнадцатеричных литер с пробелом либо без него
второй аргумент это длина пакета, неуказанные литеры дополняются нулями

Пример:
// Допустим, нужен пакет социала "Greeting" вида "07 00 1B 02 00 00 00"
// т.е. надо собрать строку #$07+#0+#$1B+#2+#0+#0+#0
// сделать это можно по разному:
pck := HStr('07 00 1B 02 00 00 00'); // - готовый пакет #$07+#0+#$1B+#2+#0+#0+#0"
pck := HStr('07001B02000000'); // тоже самое
pck := HStr('07 00 1B 02',7); // тоже самое
в этом случае второй аргумент - это размер строки, до которого надо дополнить нулями.

или, если надо, чтобы размер добавлялся сам, то используем ф-цию HPck(str,[,len]) : buf;

pck := HPck('1B 02 00 00 00'); // = тоже самое, готовый п-т #$07+#0+#$1B+#2+#0+#0+#0"
первые 2 байта размера пакета добавляются автоматом
pck := HPck('1B02000000'); // тоже самое
pck := HPck('1B 02',5); // тоже самое, обратить внимание на указанный размер.
Как видим, в ф-ции HPck() размер нужной строки указываем без учета первых байт с длиной пакета.

Во всех случаях мы получаем полную 'правильную' строку #$07+#0+#$1B+#2+#0+#0+#0,
что соответствует пакету "07 00 1B 02 00 00 00" и готова к отправке.

ReadSocket(s : Socket; var buff : str, count : int) : int; - только в socks скрипте
WriteSocket(s : Socket; var buff : str, count : int) : int; - только в socks скрипте
(для пакетных скриптов ф-ция дальше по тексту)

GInt(buf; index ; size : [1..8]) : int; - берет Int как 4 байта из buf[index];
или Word как 2 байта. 'size' может быть от 1 до 8, следовательно, 8 байт = int64
s := #$01+#$02+#$03+#$04+#$05+#$06+#$07+#$08;
Gint(s,3,2) - вернет word 1027 ( $403);
Gint(s,3,4) - вернет int $6050403;
Gint(s,1,8 ) - вернет int64 $807060504030201;
Gint(s,5,1) - вернет byte $05;
Gint(s,6,4) - даст ошибку скрипта. (размер буфера, выход за пределы)

PInt(buf; iw : int/word; index; size : [2,4]); - тоже что и GInt, только записывает.

gBlockPacket; - функция блокирующая данный входной пакет, он дальше никуда не уйдет.
Например запрет на запрос '/gmlist' будет так:
Код:
if (not _gFromServ) and copy(_gBuff,1,3) = HStr('03 00 81') then gBlockPacket;
// код только для WPS.
AnsiToWStr(astr, wstr): int; - перевод Ansi строки 'astr' в WideString 'wstr'.
переменная 'wstr' должна быть объявлена, в нее запишется WideString.
вернет количество байт записанных в 'wstr' или -1 если ошибка.
пример:
ws := ''; // объявление переменной 'ws'.
k := AnsiToWStr('str',ws); // здесь в ws будет ='s.t.r.' (#73 #00 #74 #00 #72 #00)
if k < 0 then writelog('ошибка AnsiToWStr');

Внимание! функция по умолчанию не добавляет два нулевых байта как признак Wide-строки.
если нужны нули в конце: (признак окончания Wide-строки)
k := AnsiToWStr('str'+#0,ws); // здесь в ws будет ='s.t.r...' (#73 #00 #74 #00 #72 #00 #00 #00)

WStrToAnsi(wstr, astr [,n,len]): int; - перевод WideString с позиции 'n' длиной 'len' байт в Ansi.
вернет количество записанных байт в 'astr' или -1 если ошибка.
если 'n' не указан, то по умолчанию он равен '1' (начало строки/буфера),
если размер строки 'len' не указан, то переводится вся строка/буфер 'wstr',
если 'len' = -1, то признак конца строки 'wstr' - два нулевых байта '00 00' подрят.
так же, при 'len' = -1 в 'astr' добавляется признак конца строки (один байт #0)
Внимание! положительный 'len' округляется до ближнего четного, так как Wide-символы двухбайтные.

примеры:
ls := AnsiToWStr(buf,st,10,-1);
st := trim(st); // избавимся от #0 в конце, если он там будет (см. ф-цию 'Trim')
if ls = -1 then begin writelog('ошибка в AnsiToWstr'); exit; end;
if ls > -1 then AfterWideStr := buf[10+ls*2]; // байт после wide-строки.
возьмет из 'buf' с 10 байта wide-стринг, до первого признака конца wide-строки,
запишет его как ansi-стринг в 'st' (с нулем в конце! в этом случае),
вернет количество ЗАПИСАННЫХ байт в 'st'.
Умножая 'ls' на 2 (ls*2) получим количество прочитанных байт (Widestr двухбайтные)
То есть, buf[10+ls*2] - следующий байт после wide-строки, при условии, что не было ошибки (ls <> -1)
для избавления от нуля в конце 'st' можно применить ф-цию Trim(st);

st := ''; ws := ''; // объявим переменные.
AnsiToWStr('AB',ws); // запишем в 'ws' строку 'AB' в виде Wide-строки (#$41 00 #$42 00).
WStrToAnsi('',st) - в 'st' ничего не будет, ф-я вернет 0
WStrToAnsi('',st,1,-1) - в 'st', так же, ничего не будет, ф-я вернет 0
WStrToAnsi(ws,st) - в 'st' будет 'AB' (#$41 #$42), ф-я вернет 2;
WStrToAnsi(ws,st,1,-1) - в 'st' будет 'AB'+нуль (#$41 #$42 #00), ф-я вернет 3;

8.
http://saur.x33.ru/img/t.gif

VI) Функции скрипт-языка WPS.(продолжение)

Системные ф-ции:
функция переходник 'gSys()'
которая дает доступ к системным переменным и функциям.
Название переменных и функций в первом аргументе этой ф-ции.

gSys('Tick') : int - вернет количество миллисекунд прошедших со старта компьютера (стандартная ф-ция GetTickCount)

gSys('Tick',var,ms) : bool- вернет true, если прошло время равное 'ms' или больше
с последнего запуска этой ф-ции (с той же переменной var).
переменную 'var' использовать разную в каждом новом 'Tick' иначе они будут друг другу мешать.

Например, посылаем пакет на сервер каждые 10 секунд (10 сек или больше):
естественно, при отсуствии пакетов , время может быть от 10сек до ближайшего пакета после 10сек.
if _gAbsNumPkt = 1 then begin // первый пакет.
// первый пакет используется, чтобы установить начальные переменные 1 раз.
..
tv := 0; // если поставим 1 , то Tick выполнится с первого раза. иначе только после первых 10 сек.
..
end;
..
if gGSys('Tick',tv,10000) then begin // 10000 ms = 10 сек.
gPSys('Ensends',buf); // посылаем пакет buf на сервер (Ensendc - на клиент, см ниже)
end;

gSys('S3timer'[,time]): int; - 'time' в миллисекундах.
- установка/чтение значения таймера на запуск третьего скрипта.
возвращает текущее значение таймера.
значение '0' выключает таймер.
Если установлен таймер на запуск третьего скрипта, то третий скрипт будет запускаться не только в порядке очереди при каждом пакете, но и каждое 'time' время.
Узнать как запустился скрипт можно по переменной '_gS3onTimer' - она вернет 'true' ('1') если скрипт запустился по таймеру, или 'false' ('0') если скрипт запустился в порядке очереди приема пакета.
Переменная _gS3TimerCount вернет счетчик срабатываний таймера с последнего сброса таймера.
при сбрасывани таймера в ноль (выключении) счетчик _gS3TimerCount обнуляется. (_gS3TimerCount только начиная с WP410F)

Внимание! при включении (не изменении, а именно включении) таймера, первый раз таймер срабатывает сразу, далее через интервал.

_gBuff , в третьем скрипте, при запуске от таймера, либо содержит '03 00 00' либо ничего.
_gOutBuff , при выходе из третьего скрипта, при запуске скрипта от таймера, игнорируется.

gSys('SendC',bf[,len]): int - послать пакет на клиент без шифровки.
если размер пакета не указывать, то он определится автоматически.
gSys('EnSendC',bf[,len]) : int - послать пакет на клиент с шифровкой,
пакет автоматически зашифруется действующими ключами, если они определились(De/EnCode: Tx) , либо, если установлен PDecode в ручную.

gSys('sendS',bf[,len]): int, gSys('EnSendS',bf[,len]) : int- тоже, что и предыдущие ф-ции, но на сервер.

Функции 'EnSendC' и 'EnSendS' шифруют пакет в зависимости от типа трафика, если это трафик la2, то используется метод шифровки 'GSDecode'.

Ф-ции отсыла пакетов возвращают количество удачно отосланых байт,
либо '-1' , если отослать не удалось, т.е. была ошибка.

ключи используемые автоматической системой дешифрации:
! При включенной системе авто-дешифрации, ключи устанавливаются автоматически.
gSys('Kci') : string - получить ключ для пакетов пришедших с клиента.
gSys('Kco') : string - получить ключ для пакетов уходящих на клиент.
gSys('Ksi') : string - получить ключ для пакетов пришедших с сервера.
gSys('Kso') : string - получить ключ для пакетов уходящих на сервер.
gSys('Kci',string) - установить данный ключ. (для остальных соответственно)

gSys('TrafType'[,val]): int; - тип определившегося трафика.
- '0,1' не определен, '2' - la2, '3'..'14' - резерв.
gSys('tPDecode'[,val]): int; - тип де/шифровки пакетов (PDecode),
- '-1' стоит автоопределение, но еще не определен.
'0' - нет де/шифровки, выключено, '-1' - неизвестно, '2' - la2 (GSDecode), '3'..'14' - резерв.
gSys('tParse'[,val]): int; (тип _ParsingPackets) - тип парсинга пакетов.
- '-1' - стоит автоопределение, но еще не определен.
'0' - нет парсинга, '1' - 2 bytes size (la2-style), '3'..'14' - резерв.
gSys('isLS'[,val]): int; - флаг, что определился LS - Login Server (la2)
- возвращает тип LS сервера или 0 если не определился как LS
gSys('isGS'[,val]): int; - флаг, что определился GS - Game Server (la2)
- возвращает тип GS сервера или 0 если не определился как GS
Переменная 'val' устанавливает эти значения принудительно. (критично к изменениям)

gSys('DecGS',buf,key, KeyType) : bool;
- Декодирует буфер пакета 'buf' Гейм-сервера (GS) ключем 'key' (LA2 - функция).
gSys('EncGS', buf, key, Keytype) : bool;
- Кодирует буфер пакета 'buf' Гейм-сервера (GS) ключем 'key' (LA2 - функция).
Ключи 'key' изменяются в соответствии с правилами (де)кодирования GS LA2 (KeyType).
'buf' - бинарная строка буфера/пакета
'key' - бинарная строка с ключем, размер должен соответствовать KeyType.
'KeyType' - см. 'gSys.tKeyType' в 'FS' разделе
Ф-ции возвращают 1 если отработали удачно и -1 если не удачно.

gSys('LSchks',buf[,cs]) : bool; (la2 - функция)
- возвращает 1 (true) если чексумма пакета 'buf' Логин-сервера (LS) сходна с указанной в самом пакете, иначе 0 (false).
! Размер buf должен быть не менее 8, иначе игнорируется.
! Пакет может быть, как с 2 начальными байтами размера пакета, так и без них. Определяется автоматически.
Если присуствует аргумент 'cs', то в нем возвращается значение чексуммы.
Внимание! переменная 'cs' должна быть заранее определена.
например:
cs := -1;
gSys('LSchks',buf,cs);
пример использования см. в скрипте 'wpsc\demo3.sc'

gSys('ALstart'[,0/1]) : int - для текущей сессии запустить автолог (запись лога пакетов) или остановить.
без второго параметра возвращает состояние логерра 0- выключен, 1-включен
(тоже самое в ручную делает кнопка [on/off] на панели AL)

gSys('Killself'); - разорвать соединение, дисконнект. (убивается трид сессии)
(тоже в ручную делает кнопка [Terminate Link] на главной панели Links Online )
gSys('Killself',time) - разорвать соединение, дисконнект через 'time' миллисекунд(1000 = 1 сек).
советую всегда ставить немного задержку, хотя бы 3000 - gSys('Killself',3000);

9.
http://saur.x33.ru/img/t.gif

VI) Функции скрипт-языка WPS.(продолжение)

крипт-функции:
Blowfish:
gSys('BFinit',key) : int; - инициализация ключа BF, ключ = token
возвращает 0 если успешно, или -1 если ошибка.

gSys('BFdecb',buf); - BF кодировка 8-байтного буфера.
gSys('BFencb',buf); - BF декодировка 8-байтного буфера.

gSys('BFdec',buf[,len]); - BF кодировка буфера (пакета)
gSys('BFenc',buf[,len]); - BF декодировка буфера (пакета)
- в этих ф-циях размер буфера(пакета) должен быть кратен 8, иначе последние, не кратные, байты не закодируются.
Пример использования см. в файле 'wpsc\demo3.sc' в архиве.

Base64:
gSys('EnBase64',buf[,len]) : buf; - вернет 'buf' кодированый в Base64.
gSys('DeBase64',buf[,len]) : buf; - вернет декодированный 'buf' из Base64
если (де)кодирование не успешно, вернет пустую строку ''
более подробно о Base64 тут: _http://ru.wikipedia.org/wiki/Base64
пример:
ob := gSys('DeBase64',bi);
if (length(ob) = 0) and (length(bi) <> 0) then Writelog('Ошибка декодирования Base64');

gSys('MD5',buf) : md5; - Возвращает 16 байтный MD5 hash буфера или строки 'buf'.
gSys('SHA1',buf) : sha1; - Возвращает 20 байтный SHA-1 hash буфера или строки 'buf'.

gSys('rnd'[,maxval]) : int; (maxval = 0..$FFFFFFFF)
- возвращает случайное целое число X в пределах от 0 до maxval.
Если maxval не указан, то берется максимальное значение (2^32)

gSys('Rndmize'); - начальная установка счетчика случ. чисел по системному таймеру. (использовать не обязательно, вызывается в каждой сессии автоматически)

StringList(function,a1...a4) : retvalue; - Список строк, с возможностью чтения/записи из/в файл(а)
где 'function':
StringList('Create') : sl; - создать TStringList (sl - integer, объект класса)
StringList('Free', sl); - освободить TStringList
// ф-ции по полной аналогии TStringList в DELPHI
StringList('Clear', sl);
StringList('Delete',sl, index);
StringList('Add',sl, string) : integer;
StringList('AddObject',sl, string, integer) : integer;
StringList('Insert',sl, index, string);
StringList('InsertObject',sl, index, string, integer);
StringList('LoadFromFile',sl, string);
StringList('SaveToFile',sl, string);
StringList('IndexOf',sl, string) : integer;
StringList('IndexOfName',sl, string) : integer;
StringList('IndexOfObject',sl, integer) : integer;
StringList('CommaText',sl[,string]) : string;
StringList('Count',sl) : integer;
StringList('Names',sl,index) : string;
StringList('Objects',sl,index[,integer]) : integer;
StringList('Values',sl,string[,string]) : string;
StringList('Strings',sl,index[,string]) : string;
StringList('Text',sl[,string]) : string;
StringList('Duplicates',sl[,integer]) : integer;
StringList('Sorted',sl[,boolean]) : boolean;
StringList('CaseSensitive',sl[,boolean]) : boolean;
StringList('Sort',sl);
пример (WPS):
sl1 := StringList('Create'); // создали клас
StringList('LoadFromFile',sl1,'c:\temp\slf.txt');
val := StringList('Values',sl1,'ляля');
StringList('Free', sl1); // - обязательно освобождать.

В настоящее время здесь указан не полных список ф-ций.
Так же , ожидается пополнение функций время от времени (и версий PPC)

10.

Настройки в файле 'WPcfg.ini' :

Установки WP:
[WP]
autoonlynew=yes - установка автоматом только что запущенных ботов(т.е. ранее запущенные не трогаются)
autogmlist=yes - установка автоматом gmlist'а
autoanchors=yes - установка автоматом anchors
AutoCBuff=yes - установка автоматом c-buff
xxCheckAnchors=yes - также снимает pickup с Appretince's Wand для проверки
useTCheck=no - при выборе токена устанавливать галки из token.wp (сбрасывает галки)
autol2j=no - установка автоматом l2j
autoppeoff=no - установка автоматом PPE-off

установки таймаутов для PPC:
[PPC]
FirstPckNumber=30 - количество первых пакетов для следующей переменной. от 20 до 300.
FisrtPckTimeout=60 - разрыв, если неактивность в первых пакетах. сек. (время выбора персонажа на аккаунте исключается)
проверяется только, если трафик определен (например ла2)
если значение 0 - то выключен. (при запуске двух и более клиентов меньше 20 сек не ставить)
OnCloseTimeout=5 - разрывать в случае неактивности, после прихода пакета от сервера LogOutOk. сек. (2..60c)
Если стоит значение 0 - то выключен. (меньше 2 секунд не ставить, иначе клиент не успеет сообразить и выйдет по дисконнекту)
OnRequestLogOutTimeout=60 - разрывать в случае неактивности, когда клиент послал серверу на запрос LogOut. сек. (25..180c)
Если стоит значение 0 - то выключен. (меньше 30 секунд не советую)
TotalPacketTimeOut=900 - если вообще нету активности, то разрыв. сек. (900 = 15 минут)
минимальное значение 600 (10 минут), максимально 3600 (час.)
UndefinedLinkTimeOut=60 - тамаут по неактивности (секунды) для неопределенных соединений. 20 .. 300 секунд.
NoLookUp=0 - если 1 то раз в час не будет производиться lookup имен хостов через DNS.

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

Внимание! Кроме того существует пользовательский таймаут в опциях PPC.
см. опцию 'таймаут по неактивности' , если больше нуля, то будет разрыв соединения при неактивности, вне зависимости от типа трафика. (cм третий пост этой темы)

По умолчанию стоят оптимальные значения.

 

11.
http://saur.x33.ru/img/t.gif

VII) Функции скрипт-языка FS.

Внимание! В последних версиях WP PPC (начиная с WP410F) встроено два разных скрипт-движка.
Синтаксис и ф-ции частично различны.
WPS движок больше не поддерживается, пользуйтесь только FS.
Здесь описан скрипт движок FS, информацию о WPS см в начале темы.

Отличия FS от WPS

Скрипт Движок FS кардинально отличается от WPS.

. компилирование и запук скрипта на FS происходит отдельно.
компиляция происходит один раз, а далее происходит только запуск.
(В Script-Tester'e скрипт каждый раз компилируется перед запуском,
скрипты в соединениях компилируются только при первом запуске или при изменении скрипта в работающем соединении)

. ф-ция 'OnCreate' вызывается один раз сразу после компиляции, а 'OnDestroy' в конце соединения (или при перекомпиляции)
ф-ции 'OnCreate' и 'OnDestroy' могут отсуствовать в скрипте.
все созданные динамические объекты в скрипте обязаны быть освобождены в 'OnDestroy' или ранее.

. переменные в FS необходимо объявлять.
. в FS есть классы
например, TStringList, TMemoryStream (включая методы записи/чтения в/из файла)
так же, есть уже инициализированные объекты системных классов.
например, 'gSys' и 'gCrypt'
эти классы инициализировать и очищать не нужно.
(см. примеры)
. ф-ции PPC в движках FS и WPS отличаются.
стандартные ф-ции почти не отличаются.
. массивы в FS тормозные (так как на 'вариантах'), для большого массива строк лучше использовать класс 'TStringList', он намного быстрей, чем большие размеры вариант-массива. (не будет лагов)
(см. примеры)

. !Внимание! для сравнения строк, в которых могут быть нулевые символы, надо применять ф-цию 'StrCmp()'
это особенно касается пакетов, так как пакеты это строки с бинарным содержимым, в том числе и с нулевыми символами.
Вместо выражений типа 'if s1 = s2 then' надо писать 'if StrCmp(s1,s2) then'
Например, вместо 'if (_gBuff[3] = #$27) then' надо будет писать 'if StrCmp(_gBuff[3],#27) then'

. !Внимание! выход за границы строки буфера не всегда проверяется(для скорости выполнения).
помните, в паскале string = array[1..length(string)] of char;
т.е. индексация символов/байт в string/буфере начинаются с '1' а не с нуля.

. в WPS все три скрипта были связаны одними локальными переменными.
в FS локальные переменные каждого из трех последовательных скриптов не связаны,
т.е. в FS инициализация и использование переменных строго для каждого скрипта.
соответственно, ф-ции 'OnCreate' и 'OnDestroy' так же для каждого скрипта свои.

Некоторые аспекты синтаксиса скрипт-движка FS

В FS существует возможность создания динамических объектов, для которых , в последствии, необходимо освобождать память.
Для этих целей служат функции (либо процедуры, это не важно) OnCreate; и OnDestroy; их наличие не обязательно, т.е. они могут отсутствовать в скрипте.
Эти функции(процедуры) не следует вызывать в самом скрипте, они вызываются сами.
OnCreate; - вызывается только один раз, когда скрипт запускается в первый раз.
OnDestroy; - вызывается только один раз, когда скрипт более не будет запускаться. когда он освобождается.

Все динамически созданные объекты, например объекты классов, либо динамические массивы, обязаны быть освобождены в процедуре OnDestroy;
пример в файле 'wpsc\FS\demoFS1.fsc'.

Стандартные функции и процедуры FS (почти полные аналоги из Delphi):

Типы:
Boolean = boolean (fvtBool);
Char : char (fvtChar = fvtString);
String : string (fvtString);
Variant : variant (fvtVariant);
Pointer : variant (fvtVariant);
Array : array (variant fvtArray)

Integer , Byte, Word, Longint, Cardinal, Tcolor : integer (fvtInt);
Real, Single, Double, Extended, Currency, TDate, TTime, TDateTime, : Real (fvtFloat);

Константы:
'True' : boolean = true;
'False' : boolean = false;
'nil' : variant = 0;
'Null' : variant = null;

Список Стандартных Функций:
описание к стандартным ф-цим можно найти в руководстве Delphi или в интернете.

function IntToStr(i: Integer): String;
function IntToHex(i: integer; digit: integer) : string;
function FloatToStr(e: Extended): String;
function DateToStr(e: Extended): String;
function TimeToStr(e: Extended): String;
function DateTimeToStr(e: Extended): String;
function VarToStr(v: Variant): String;
function StrToInt(s: String): Integer;
function StrToInt64(s: String): Integer;
function StrToInt64Def(s: String; def: Integer): Integer;

function StrToFloat(s: String): Extended;
function StrToDate(s: String): Extended;
function StrToTime(s: String): Extended;
function StrToDateTime(s: String): Extended;

function Format(Fmt: String; Args: array): String;
function FormatFloat(Fmt: String; Value: Extended): String;
function FormatDateTime(Fmt: String; DateTime: TDateTime): String;
function FormatMaskText(EditMask: string; Value: string): string;

function EncodeDate(Year, Month, Day: Word): TDateTime;
procedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word);
function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;
procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word);
function Date: TDateTime;
function Time: TDateTime;
function Now: TDateTime;
function DayOfWeek(aDate: TDateTime): Integer;
function IsLeapYear(Year: Word): Boolean;
function DaysInMonth(nYear, nMonth: Integer): Integer;

function Length(s: Variant): Integer;
function Copy(s: String; from, count: Integer): String;
function Pos(substr, s: String): Integer;
procedure Delete(var s: String; from, count: Integer);
procedure DeleteStr(var s: String; from, count: Integer);
procedure Insert(s: String; var s2: String; pos: Integer);
function Uppercase(s: String): String;
function Lowercase(s: String): String;
function Trim(s: String): String;
function NameCase(s: String): String;
function CompareText(s, s1: String): Integer;
function Chr(i: Integer): Char;
function Ord(ch: Char): Integer;
procedure SetLength(var S: Variant; L: Integer);

function Round(e: Extended): Integer;
function Trunc(e: Extended): Integer;
function Int(e: Extended): Extended;
function Frac(X: Extended): Extended;
function Sqrt(e: Extended): Extended;
function Abs(e: Extended): Extended;
function Sin(e: Extended): Extended;
function Cos(e: Extended): Extended;
function ArcTan(X: Extended): Extended;
function Tan(X: Extended): Extended;
function Exp(X: Extended): Extended;
function Ln(X: Extended): Extended;
function Pi: Extended;

procedure Inc(var i: Integer; incr: Integer = 1);
procedure Dec(var i: Integer; decr: Integer = 1);
procedure RaiseException(Param: String);
procedure ShowMessage(Msg: Variant); <<< включена только в ScriptTester'e
procedure Randomize;
function Random: Extended;
function ValidInt(cInt: String): Boolean;
function ValidFloat(cFlt: String): Boolean;
function ValidDate(cDate: String): Boolean;

function VarArrayCreate(Bounds: Array; Typ: Integer): Variant;
function VarType(V: Variant): Integer;

0

3

12.
http://saur.x33.ru/img/t.gif

VII) Функции скрипт-языка FS. (продолжение)

Некоторые стандартные Классы (почти полные аналоги из Delphi):

Константы:
fmCreate : Integer', fmCreate;
fmOpenRead : Integer = fmOpenRead;
fmOpenWrite : Integer = fmOpenWrite;
fmOpenReadWrite : Integer = fmOpenReadWrite;
fmShareExclusive : Integer = fmShareExclusive;
fmShareDenyWrite : Integer = fmShareDenyWrite;
fmShareDenyNone : Integer = fmShareDenyNone;
soFromBeginning : Integer = soFromBeginning;
soFromCurrent : Integer = soFromCurrent;
soFromEnd : Integer = soFromEnd;
TDuplicates : 'dupIgnore, dupAccept, dupError';
TPrinterOrientation : 'poPortrait, poLandscape';

TObject
constructor TObject.Create
procedure TObject.Free

TPersistent (TObject) - не используйте напрямую.
procedure TPersistent.Assign(Source: TPersistent)

TList (TObject)
function TList.Add(Item: TObject): Integer
procedure TList.Clear
procedure TList.Delete(Index: Integer)
function TList.IndexOf(Item: TObject): Integer
procedure TList.Insert(Index: Integer; Item: TObject)
function TList.Remove(Item: TObject): Integer
property TList.Count
property TList.Items

TStrings (TPersistent) - абстрактный класс, не используйте напрямую.
function TStrings.Add(const S: string): Integer
function TStrings.AddObject(const S: string; AObject: TObject): Integer
procedure TStrings.Clear
procedure TStrings.Delete(Index: Integer)
function TStrings.IndexOf(const S: string): Integer
function TStrings.IndexOfName(const Name: string): Integer
function TStrings.IndexOfObject(AObject: TObject): Integer
procedure TStrings.Insert(Index: Integer; const S: string)
procedure TStrings.InsertObject(Index: Integer; const S: string; AObject: TObject)
procedure TStrings.LoadFromFile(const FileName: string)
procedure TStrings.LoadFromStream(Stream: TStream)
procedure TStrings.SaveToFile(const FileName: string)
procedure TStrings.SaveToStream(Stream: TStream)
property TStrings.CommaText
property TStrings.Count
property TStrings.Names
property TStrings.Objects
property TStrings.Values
property TStrings.Strings
property TStrings.Text

TStringList (TStrings)
function TStringList.Find(s: String; var Index: Integer): Boolean
procedure TStringList.Sort
property TStringList.Duplicates
property TStringList.Sorted
property TStringList.CaseSensitive

TStream (TObject) - абстрактный класс, не используйте напрямую.
function TStream.Read(Buffer: string; Count: Longint): Longint
function TStream.Write(Buffer: string; Count: Longint): Longint
function TStream.Seek(Offset: Longint; Origin: Word): Longint
function TStream.CopyFrom(Source: TStream; Count: Longint): Longint
property TStream.Position
property TStream.Size

TFileStream (TStream)
constructor TFileStream.Create(Filename: String; Mode: Word)

TMemoryStream (TStream)
procedure TMemoryStream.Clear
procedure TMemoryStream.LoadFromStream(Stream: TStream)
procedure TMemoryStream.LoadFromFile(Filename: String)
procedure TMemoryStream.SaveToStream(Stream: TStream)
procedure TMemoryStream.SaveToFile(Filename: String)

TComponent (TPersistent) - не используйте напрямую.
constructor TComponent.Create(AOwner: TComponent)
property TComponent.Owner

TCustomIniFile (TObject) - не используйте напрямую.
constructor TCustomIniFile.Create(Filename: String)
procedure TCustomIniFile.DeleteKey(Section, Ident: String)
procedure TCustomIniFile.EraseSection(Section: String)
function TCustomIniFile.ReadBinaryStream(Section, Name: string; Value: TStream): Integer
function TCustomIniFile.ReadBool(Section, Ident: String; Default: Boolean): Boolean
function TCustomIniFile.ReadDate(Section, Ident: String; Default: TDateTime): TDateTime
function TCustomIniFile.ReadDateTime(Section, Ident: String; Default: TDateTime): TDateTime
function TCustomIniFile.ReadFloat(Section, Ident: String; Default: Double): Double
function TCustomIniFile.ReadInteger(Section, Ident: String; Default: Longint): Longint
procedure TCustomIniFile.ReadSection(Section: String; Strings: TStrings)
procedure TCustomIniFile.ReadSections(Strings: TStrings)
procedure TCustomIniFile.ReadSectionValues(Section: String; Strings: TStrings
function TCustomIniFile.ReadString(Section, Ident, Default: String): String
function TCustomIniFile.ReadTime(Section, Ident: String; Default: TDateTime):TDateTime
function TCustomIniFile.SectionExists(Section: String): Boolean
procedure TCustomIniFile.UpdateFile
function TCustomIniFile.ValueExists(Section, Ident: String): Boolean
procedure TCustomIniFile.WriteBinaryStream(Section, Name: string; Value: TStream)
procedure TCustomIniFile.WriteBool(Section, Ident: String; Value: Boolean)
procedure TCustomIniFile.WriteDate(Section, Ident: String; Value: TDateTime)
procedure TCustomIniFile.WriteDateTime(Section, Ident: String; Value: TDateTime)
procedure TCustomIniFile.WriteFloat(Section, Ident: String; Value: Double)
procedure TCustomIniFile.WriteInteger(Section, Ident: String; Value: Longint)
procedure TCustomIniFile.WriteString(Section, Ident, Value: String)
procedure TCustomIniFile.WriteTime(Section, Ident: String; Value: TDateTime)
property TCustomIniFile.FileName

TMemIniFile (TCustomIniFile)
constructor TMemIniFile.Create(FileName: String)
procedure TMemIniFile.Clear
procedure TMemIniFile.DeleteKey(Section, Ident: String)
procedure TMemIniFile.EraseSection(Section: String)
procedure TMemIniFile.GetStrings(List: TStrings)
procedure TMemIniFile.ReadSection(Section: string; Strings: TStrings)
procedure TMemIniFile.ReadSections(Strings: TStrings)
procedure TMemIniFile.ReadSectionValues(Section: String; Strings: TStrings)
function TMemIniFile.ReadString(Section, Ident, Default: String): string
procedure TMemIniFile.Rename(FileName: String; Reload: Boolean)
procedure TMemIniFile.SetStrings(List: TStrings)
procedure TMemIniFile.UpdateFile
procedure TMemIniFile.WriteString(Section, Ident, Value: String)
property TMemIniFile.CaseSensitive

(TmemIniFile только с версии WP502F)

[ to be continued ....]

13.

VII) Функции скрипт-языка FS. (продожение)

Системные переменные PPC скрипт-движка FS
(часть переменных аналогично WPS)

_gBuff : str - входящий буфер (строка) , в нем приходит пакет в скрипты.
_gOutBuff : str - исходящий буфер, это пакет который уйдет дальше по назначению.
Если ничего не присваивать этой переменной, то пакет на выходе будет без изменений.
_gFromServ :bool - возвращает true , если скрипт получил пакет с сервера на клиент.
false - если с клиента на сервер.

_gS3onTimer - возвращает true, если скрипт запущен по таймеру (см. gSys.S3timer)

_gAbsNumPkt :int - абсолютный номер пакета, нумеруется с 1.

_gStopOnError : bool, по умолчанию false, если установить значение true, то будет разрыв соединения в случае любой ошибки скрипта.
разрыв будет не сразу, может пройти еще пара пакетов (для лога полезно).

_isScriptTester : boolean; - вернет true если скрипт запущен в Script-тестере.

_gIDSession : string; (read only)
- 16 байт идентификатор сессии соединения, не повторяется.
(используется для идентификации соединения,
например в DLL при использовании межсессионных глобальных переменных)

_gScriptNumber : integer; - возвращает номер позиции скрипта (1,2 или 3)

_gServName - строка, с именем сервера, как он определился PPC.
_gServHost - строка, с хостом сервера, если он определился.
_gServIP - int, IP сервера.
_gServPort - int, Port сервера.

_gCWinSock - доступно только в скрипте socks5 (только WPS), тип WinSocketStream

_gScriptDir : string - константа содержащая путь к скриптам ('...wp\wpsc\')
_gCustomDir : string - константа содержащая путь к данным пользователя('...wp\custom\')

Значения исключения в обработке исключений 'try'/'except'
ExceptionClassName : string;
ExceptionMessage : string;
см. 'RaiseException'



[ to be continued ....]



14.
http://saur.x33.ru/img/t.gif

VII) Функции скрипт-языка FS. (продожение)

Функции PPC скрипт-движка FS (1/4)
(часть функций аналогично WPS)

StrCmp(s1,s2 : string) : boolean; - сверяет строки/буфер (включая нулевые символы)
возвращает 'true' если строка 's1' полностью равна строке 's2' по содержимому.
!Внимание! ф-цию необходимо применять везде, где идет сравнение строк/буферов с бинарным содержимом (пакеты)

ScriptTimeOut(ms) : ms; ms = 100..31000. - аналогично 'ScriptTimeOut' в WPS;
- установка таймаута скрипта (от 0.1 до 31 секунд).
по умолчанию скрипт терминируется через 1 секунду (1000 ms).
возвращает установленное значение, если без аргументов, то текущее значение.

WriteLog(var); - Выводит сообщение или переменную в лог сообщения.
WriteLogln(var); - тоже самое, но с переводом строки.
Лог - для пакетных скриптов - Scripts Log. (виден в каждой записи в логе, либо в онлайн редакторе скриптов)
Скрипт-тестер выводит в свой лог.
Writelog в OnCreate() и OnDestroy() выводит в Syslog.
Более одной переменной (любое количество) можно выводить используя 'format()' (см стандартную ф-цию FS 'format()')
например:
i := 100;
s := 'i := ';
Writelog(format('%s %d',[s,i])); - выводит 'i := 100'
тоже самое: Writelog(format('i := %d',[i]));

WriteLogHexB(str [,len]); - аналогично 'WriteLogHexB' в WPS
выводит строку-буфер 'str' в виде блока в шестнадцатеричном виде.

BuftoHex(str) : str; - аналогично 'BuftoHex' в WPS
переводит каждый бинарный байт в строке-буфере в ascii-hex;
пример:
BuftoHex(#$01#$02#$04); - вернет строку '010204'
BuftoHex('aaa') - вернет строку '616161';
BuftoHex(inttostr(7777)) - вернет строку '37373737'
BuftoHex(HStr('01 02 FF 0C')); - вернет строку '0102FF0C'
ps: 'BuftoHex' является функцией обратной от 'HStr();'

FStr(len[,char]) : string; - почти аналогично 'FStr' в WPS;
создать и вернуть строку(буфер) размером 'len' и заполнить символом 'char'.
'char' по умолчанию #0;
ограничение на максимум - 65к

HStr(str,[,len]) : buf; - аналогично 'HStr' в WPS;
собрать пакет из ascii шестнадцатеричного вида.
пакет задается в виде шестнадцатеричных литер с пробелом либо без него
второй аргумент это длина пакета, неуказанные литеры дополняются нулями

HPck(str,[,len]) : buf; - аналогично 'HPck' в WPS;
собрать пакет и добавить длину пакета автоматически

Пример:
// Допустим, нужен пакет социала "Greeting" вида "07 00 1B 02 00 00 00"
// т.е. надо собрать строку #$07+#0+#$1B+#2+#0+#0+#0
// сделать это можно по разному:
pck := HStr('07 00 1B 02 00 00 00'); // - готовый пакет #$07+#0+#$1B+#2+#0+#0+#0"
pck := HStr('07001B02000000'); // тоже самое
pck := HStr('07 00 1B 02',7); // тоже самое
в этом случае второй аргумент - это размер строки, до которого надо дополнить нулями.

или, если надо, чтобы размер добавлялся сам, то используем ф-цию HPck(str,[,len]) : buf;

pck := HPck('1B 02 00 00 00'); // = тоже самое, готовый п-т #$07+#0+#$1B+#2+#0+#0+#0"
первые 2 байта размера пакета добавляются автоматом
pck := HPck('1B02000000'); // тоже самое
pck := HPck('1B 02',5); // тоже самое, обратить внимание на указанный размер.
Как видим, в ф-ции HPck() размер нужной строки указываем без учета первых байт с длиной пакета.

Во всех случаях мы получаем полную 'правильную' строку #$07+#0+#$1B+#2+#0+#0+#0,
что соответствует пакету "07 00 1B 02 00 00 00" и готова к отправке.

hStrCmp(buf,p,s,shex) : boolean; - макрос сравнения с преобразованием.
сравнивает часть строки/буфера 'buf' начиная с позиции 'p' длиной 's'
с хексом в виде шестнадцатеричных литер с пробелом либо без него в 'shex'
пример:
выражение
if hStrCmp(_gBuff,3,3,'070300') then ...
аналогично выражению:
if StrCmp(copy(_gBuff,3,3),HStr('070300')) then ...
(hStrCmp выполняется значительно быстрее)

SetPckSize(buf) : sbuf; - дабавляет в строку/буфер два первых байта размера.
- возвращает строку/буфер 'buf' с добавленными первыми двумя байтами размера (соответственно length(buf)+2)
пример:
выражение:
buf := SetPckSize(buf);
аналогично выражению:
buf := HPck(BuftoHex(buf));
(SetPckSize выполняется значительно быстрее)

gBlockPacket; - аналогично 'gBlockPacket' в WPS.
функция блокирующая данный входной пакет, дальше он никуда не уйдет.
Например запрет на запрос '/gmlist' будет так:
Код:

//этот код только для FS
if (not _gFromServ) and StrCmp(copy(_gBuff,1,3), HStr('03 00 81')) then gBlockPacket;
isBlockedPacket : boolean;
функция возвращает true, если данный пакет был блокирован (командой gBlockPacket).
распространяется на все три скрипта в пределах одного пакета.
так можно узнать, был ли пакет блокирован в предыдущем скрипте.
(блокированный пакет в любом случае не будет отослан после скриптов)

inet_ntoa(addr : int) : str; - перевод net-адреса в точечный строковой формат.
inet_addr(s : str) : int; - перевод строкового в net-адрес, или -1, если ошибка.
пример:
inet_addr('127.0.0.1') - вернет целое 16777343 ($100007F)
inet_ntoa($100007F) - вернет строку '127.0.0.1'
inet_ntoa(3589856213) и inet_ntoa(-705111083) - оба вернут '213.219.248.213'

htons(word) : word; - меняет местами байты в word'e;
htonl(int) : integer; - меняет последовательность байт в integer'e на обратную;

_getIPbyHost(s : string) : integer; - возвращает IP адрес по имени хоста.
!использует DNS, задержка в случае отсутствия имени на DNS может достигать до 3 секунд.
возвращает 0 в случае ошибки или если адрес по имени хоста не найден.

15.
http://saur.x33.ru/img/t.gif

VII) Функции скрипт-языка FS. (продожение)

Функции PPC скрипт-движка FS (2/4)
(часть функций аналогично WPS)

AnsiToWStr(astr, wstr): int; - перевод Ansi строки 'astr' в WideString 'wstr'.
переменная 'wstr' не должна быть константа, в нее запишется WideString.
вернет количество байт записанных в 'wstr' или -1 если ошибка.
пример:
k := AnsiToWStr('str',ws); // здесь в ws будет ='s.t.r.' (#73 #00 #74 #00 #72 #00)
if k < 0 then writelog('ошибка AnsiToWStr');

Внимание! функция по умолчанию не добавляет два нулевых байта как признак Wide-строки.
если нужны нули в конце: (признак окончания Wide-строки)
k := AnsiToWStr('str'+#0,ws); // здесь в ws будет ='s.t.r...' (#73 #00 #74 #00 #72 #00 #00 #00)

GetWideStr(str) : str; - облегченный перевод ansi строки в WideStr;
пример:
s := GetWideStr('123'); // вернет '1.2.3.' (31 00 32 00 33 00)
s := GetWideStr('123'#0); // вернет '1.2.3...' (31 00 32 00 33 00 00 00)

WStrToAnsi(wstr, astr [,n,len]): int;
- перевод WideString 'wstr' с позиции 'n' длиной 'len' байт в Ansi 'astr'.
вернет количество записанных байт в 'astr' или -1 если ошибка.
если позиция 'n' не указана, то по умолчанию равна '1' (начало строки/буфера), если размер строки 'len' не указан, то переводится вся строка/буфер 'wstr',
если 'len' = -1, то признак конца строки 'wstr' - два нулевых байта '00 00' подрят.
так же, при 'len' = -1 в 'astr' добавляется признак конца строки (один байт #0)
Внимание! положительный 'len' округляется до меньшего четного, так как Wide-символы двухбайтные.

примеры:
ls := AnsiToWStr(buf,st,10,-1);
st := trim(st); // избавимся от #0 в конце, если он там будет (см. ф-цию 'Trim')
if ls = -1 then begin writelog('ошибка в AnsiToWstr'); exit; end;
возьмет из 'buf' с 10 байта wide-строки, до первого признака конца wide-строки,
запишет его как ansi-строку в 'st' (с нулем в конце! в этом случае),
вернет количество ЗАПИСАННЫХ байт в 'st'.
Умножая 'ls' на 2 (ls*2) получим количество прочитанных байт (Widestr двухбайтные)
То есть, buf[10+ls*2] - следующий байт после wide-строки, при условии, что не было ошибки (ls <> -1)
для избавления от нуля в конце 'st' можно применить ф-цию Trim(st);

пример 2:
st := ''; ws := '';
ws := AnsiToWStr('AB',ws); // запишем в 'ws' строку 'AB' в виде Wide-строки (#$41 00 #$42 00).
WStrToAnsi('',st) - в 'st' ничего не будет, ф-я вернет 0
WStrToAnsi('',st,1,-1) - в 'st', так же, ничего не будет, ф-я вернет 0
WStrToAnsi(ws,st) - в 'st' будет 'AB' (#$41 #$42), ф-я вернет 2;
WStrToAnsi(ws,st,1,-1) - в 'st' будет 'AB'+нуль (#$41 #$42 #00), ф-я вернет 3;

GetAnsiStr(str) : str; - облегченный перевод widestr в ansi;
пример:
s := GetAnsiStr('1'#0'2'#0'3'#0); - вернет ansi '123'#0;
избавление от последнего '#0':
s := trim(GetAnsiStr(..));

GInt(buf, idx, size) : integer; - аналог 'GInt' в WPS
- берет Integer как 4 байта из бинарной строки/буфера buf[idx],
или 1..8 байт : 1-byte, 2-word, 3..4-integer, 5..8 - int64
по умолчанию idx = 1, size=4;
пример:
s := #$01+#$02+#$03+#$04+#$05+#$06+#$07+#$08;
Gint(s,3,2) - вернет word 1027 ( $403);
Gint(s,3,4) - вернет int $6050403;
Gint(s,6,4) - несоответствие размеру буфера, вернет последние 3 байта int $080706;

PInt(var buf, int, id, sz); - аналог 'PInt' в WPS
Тоже, что и GInt, только записывает целое 'int' в буфер 'buf' по индексу 'idx'

IntToBin(int {,len}) : string; - упрощенный PInt
- вернет строку/буфер с бинарным содержимом целого 'int'
len - размер целого (от 1 до 8 ), по умлочанию len = 4

Gfloat(buf, idx, sz) : double;
- берет Float (число с плавающей запятой) из бинарной строки/буфера buf[idx] 'sz' байт.
'sz' может быть 4 или 8, 4 если в буфере single-тип или 8 байт, если в буфере double-тип float.
по умолчанию idx = 1, sz = 8;

Pfloat(var buf, double, idx, sz);
- записывает float число 'double' в строку/буфер в бинарном виде начиная с байта buf[idx]
как single - 4 байта или double - 8 байт, в зависимости от 'sz'.
соответственно 'sz' может быть 4 или 8.
по умолчанию idx = 1, sz = 8;

FloatToBin(double {,len}) : string; - упрощенный Pfloat
- вернет строку/буфер с бинарным содержимом числа float 'double'
len - размер числа (4 или 8 ), по умлочанию len = 8.

FormatPck(format_args, [arg1 .... argx]) : string;
Функция последовательного перевода переменных 'arg1' .. 'argx' в последовательность байт
и возвращающая в виде бинарной строки/буфера. (например, для сбора пакета)
'format_args' - строка определяющая переменные и порядок их следования,
( внимание! формат-строка отличается от стандартной используемой в ф-циях типа format; )
формат-строка состоит из:
'%' - добавить в начало 2 байта получившегося размера результирующего пакета.
(символ '%' может быть только первым)
'c' - аргумент - символ/байт. (допускается integer, в этом случае берется младший байт)
записывается 1 байт.
'd' - аргумент - целое (integer, 4 байта).
записывается 4 байта.
'h' - аргумент - 2 байтное слово (word) (если integer, то берутся 2 младших байта)
записывается 2 байта.
'q' - аргумент - 8 байт целое (int64). (integer автоматом дополняется до int64)
записывается 8 байт.
'a' - аргумент - строка, ANSI.
строка никак не преобразуется,
если нуля в конце нет, то он не добавляется (нуль добавляем так: 'ляля'+#0, или str+#0)
's' - агрумент - строка ANSI,
строка преобразуется в WideStr, где каждый символ - 2 байта,
если оконечных нулей нет , то они не добавляются.
(нули добавляем так : str+#0 - добавляем только ОДИН нуль!)
'f' - аргумент - double, 8 байт (double floating-point)
записывается 8 байт.
'r' - аргумент - float, 4 байт (single floating-point)
записывается 4 байта.
'b' - аргумент - массив байт в виде строки
записывается 4 байта - размер блока.
далее записывается весь блок.
'x' - аргумент - массив байт в виде строки (размер ограничен 255)
записывается 1 байт - размер блока.
далее записывается весь блок (не более 255 байт)

примеры:
buf := FormatPck('ddc',[$15,1234,10]); - на выходе: #$15+#0+#0+#0+#$D2+#4+#0+#0+#$A';
- что соответствует такому пакету: '15 00 00 00.D2 04 00 00.0A'; (точками показаны отдельные аргументы)

buf := FormatPck('%cd',[61,0]); - на выходе: '#7+#0+#$3D+#0+#0+#0+#0';
- что соответствует такому пакету: '07 00.3D.00 00 00 00'; (точками показаны отдельные аргументы)
('%' значит добавить в начало размер пакета.)

buf := FormatPck('%cdds',[11,$10203040,1234,'12345678'#0]);
- на выходе будет пакет:
1D 00.0B.40 30 20 10.D2 | 04 00 00.31 00 32 00 33 ...@0 .Т...1.2.3
00 34 00 35 00 36 00 37 | 00 38 00 00 00 .4.5.6.7.8...
(точками в левой части показаны отдельные аргументы)

ScanPck5(buf, idx, fstr, var a1, var a2, var a3, var a4, var a5) : integer;
функция разбора строки буфера (пакета) обратная к ф-ции FormatPck
разбирает буфер 'buf' (пакет) в соответствии с форматной строкой
и заносит данные в 5 аргументов (не использованные аргументы должны быть NULL)
'idx' - индекс байта (начиная с 1) с которого производится разбор буфера (например, при повторном вызове этой ф-ции)
возвращает индекс следующего не разобранного байта в буфере,
либо 0 если буфер не имеет остатка,
либо -1 если произошла ошибка (например, не соответствие заказанного аргумента с содержимым)
В случае остатка буфера, возвращенный индекс можно использовать для дальнейшего разбора (опять вызвать ф-цию, на остаток буфера)
'fstr' - строка формата имеет до 5 последовательных значений (так как 5 аргументов)
содержит последовательные символы обозначающие формат чтения данных:
'c' - байт/символ, читает 1 байт
'h' - word, читает 2 байта
'd' - integer, читает 4 байта
'q' - int64, читает 8 байт
'f' - double, читает 8 байт (float)
'r' - short float, читает 4 байта (float)
'b' - последовательность байт, читает 4 байта длины, далее последовательность байт этим размером
'x' - последовательность байт, читает 1 байт, далее последовательность байт этим размером
'a' - строка байт до первого нулевого байта (ASCIIz, строка заканчивающаяся нулем)
'w' - строка WideStr, оканчивающаяся двумя нулямя. Вернет именно WideString.
's' - строка WideStr, оканчивающаяся двумя нулямя. Вернет в виде ASCII строки.
'znn' - читает фиксированную последовательность байт, 'nn' = 00..99 (например z10 - читает 10 байт)
'-nn' - пропустить 'nn' байт, эти байты в аргументы не заносятся.

примеры:
разбор пакета LA2 [s]2D 'Social Action':
в соответствющие переменные будут занесены соответствующие данные из пакета 'buf'
i := ScanPck5(buf, 1, 'hcdd', size, ID, PlayerID, Social, null);
if i < 0 then writelogln('Ошибка');

разбор пакета LA2 [s]0C 'DropItem'
начинаем с 4 байта (опускаем размер и ID пакета)
разбираем 3 аргумента, и затем продолжаем и берем оставшиеся 5:
i := ScanPck5(buf, 4, 'ddd', playerID, ObjectID, ItemID, null, null);
if i > 0 then i := ScanPck5(buf, i, 'ddddd', X, Y, Z, Scackable, Count);

разбор пакета LA2 [s]4A 'Say2'
в соответствющие переменные будут занесены соответствующие данные из пакета 'buf'
начинаем с 4 байта (опускаем размер и ID пакета)
i := ScanPck5(buf, 4, 'ddss', ObjectID, textTyp, charname, msg, null);
if i < 0 then writelogln('Ошибка');

Int64(v : variant) : integer; - принудительный перевод в целое int64
если необходимо, то округляется до целого.
пример:
writelogln(format('%x',[-1])); // выведет в лог '-1' как 32 разрядное '$FFFFFFFF'
writelogln(format('%x',[int64(-1)])); //выведет в лог '-1' как 64 разрядное '$FFFFFFFFFFFFFFFF'

Int32(v : variant) : integer; - принудительный перевод в целое int32
если аргумент int64 то вернет последние 4 байта.
если аргумент real то вернет округленное цело значение.
возвращаемое значение знаковое.

_gS3TimerCount - аналогично WPS
возвращает счетчик срабатываний третьего скрипта по таймеру.
обнуляется только при установки таймера в ноль (выключение таймера gSys.S3timer := 0; ).
При включении (не изменении, а именно включении) таймера, первый раз таймер срабатывает сразу, далее через интервал.

RaiseException(msg); - генерация исключения (ошибки).
(прерывает выполнение скрипта, если не стоит внутри try/except)
msg - сообщение при ошибке.
переменная 'ExceptionMessage' содержит ошибку в случе try/except
пример:
try
.... // код который может сгенерировать исключение (ошибку)
....
except //перехватывам ошибку, в случае возникновении
...
... /тут любой код, например, освобождение ресурсов в случае ошибки ..
Writelogln(ExceptionMessage); // печатаем ошибку в лог.
...
RaiseException(ExceptionMessage); // передаем ошибку дальше в скрипт движок, но в этом случае скрипт будет прерван.
end;

GetLastError : integer; - последняя системная ошибка Win32 ('0' - нет ошибки)
SetLastError(int); - установить последнюю системную ошибку Win32 ('0'- сбросить последнюю ошибку)
SysErrorMessage(int) : string; - получить описание системной ошибки Win32.

FileExists(fname) : boolean; - вернет 'true' если файл 'fname' существует.
'fname' - строка содержащая путь и имя файла.

0

4

16.

VII) Функции скрипт-языка FS. (продожение)

Функции и Классы PPC скрипт-движка FS (3/4)

Системные ф-ции WPS gSys('..') в FS заменяются на класс gSys и gCrypt:

Например:
gSys('Tick'..) ==> gSys.Tick;
gSys('S3timer'..) ==> gSys.S3Timer;
gSys('sendC'/'sendS'/'EnsendC'/'EnSendS'..) ==> gSys.SendC/ gSys.SendS/ gSys.EnSendC/ gSys.EnSendS
gSys('Kci') ... gSys('kso') ==> gSys.Kci ... gSys.Kso
gSys('DecGS'...) ==> gCrypt.DecGS(..)
и другие ...

= gSys: =

Класс gSys является объектом системного класса и не требует инициализации,
это системный класс-переходник, имеющий следующие методы и переменные:

Переменные класса gSys:

gSys.S3Timer : int; - значения таймера на запуск третьего скрипта (в миллисекундах).
установка в '0' выключает таймер.
Если установлен таймер на запуск третьего скрипта, то третий скрипт будет запускаться не только в порядке очереди при каждом пакете, но и каждое установленное время.
Прочитав переменную '_gS3onTimer' можно узнать, как запустился скрипт - она вернет 'true' если скрипт запустился по таймеру, или 'false' если скрипт запустился в порядке очереди приема пакета.
Прочитав '_gS3TimerCount' можно узнать счетчик срабатываний таймера с последнего сброса таймера.
Пример:
gSys.S3Timer := 1000; // установить вызов третьего скрипта каждую секунду.
i := gSys.S3Timer; // прочитаем текущее значение таймера.
gSys.S3Timer := 0; // выключить таймер. (_gS3TimerCount тоже сбросится)

gSys.ALstart : boolean; - состояние автологгера.
изменение останавливает или запускает автологгер для текущего трида.
gSys.ALstart := true; - запустить автологгер для текущего трида.
gSys.ALstart := false; - остановить автологгер для текущего трида.
(тоже самое в ручную делает кнопка [on/off] на панели AL)

системные переменные:
(критично к изменениям !)

ключи используемые автоматической системой дешифрации:
gSys.Kci : string - для пакетов пришедших с клиента.
gSys.Kco : string - для пакетов уходящих на клиент.
gSys.Ksi : string - для пакетов пришедших с сервера.
gSys.Kso : string - для пакетов уходящих на сервер.
! При включенной системе авто-дешифрации, ключи устанавливаются автоматически.

//Пример стандартного чтения ключей: (если вдруг понадобится)
if length(gSys.Kci) >= 16 then begin // если размер ключа 16 то это интерлюдия.
int64_1 := GInt(gSys.Kci , 1, 8 ); - первая часть ключа.
int64_2 := GInt(gSys.Kci , 9, 8 ); - вторая часть ключа (в interlude именно она инкрементируется)
end;
Установка ключей соответственно : (16 байт для interlude, 8 байт для C4/C5)
gSys.Kci := HStr('00 00 ... 00 ');
либо:
gSys.Kci := FStr(16);
PInt(gSys.Kci, int64_1, 1, ; - младшие 8 байт
PInt(gSys.Kci, int64_2, 9, ; - старшие 8 байт

gSys.tParse : int; (тип _ParsingPackets) - тип парсинга пакетов.
'-1' - стоит автоопределение, но еще не определен.
'0' - нет парсинга, '1' - 2 bytes size (LA2, RFO etc.), '3'..'14' - резерв.

gSys.isLS : int; - тип LS сервера или 0 если не определился как LS (Login Server's)
может принимать значения от 0 до 14;

gSys.isGS : int; - тип GS сервера или 0 если не определился как GS (Game Server's)
может принимать значения от 0 до 14;

gSys.TrafType : int; - тип трафика.
'0' не определен,
'1' стоит автоопределение, но еще не определен (автоопределение трафика в первых пакетах)
'2' - LA2,
'3' - RFO,
'4'..'14' - резерв.

gSys.Protocol : int; - номер протокола соединения (зависит от типа трафика).
протокол не определен, если значение -1.

gSys.tPDecode : int; - тип де/кодировки пакетов (PDecode),
'-1' стоит автоопределение, но еще не определен.
'0' - нет де/кодировки, выключено,
'2' - LA2, LS: BF;
'2' - LA2, GS: GSDecode/GSDecodej/GSDecodeI (см. gSys.tKeyType)
'2' - RFO: ...
'3'..'14' - резерв.

gSys.tKeyType : int; - тип ключа для де/кодировки (зависит от PDecode и типа трафика)
(при включенной системе Auto Detect устанавливается автоматически)
значениния tKeyType:
LA2:
1 - GS: GSDecodeJ (C4/C5 ключ 8 байт, инкрементация половины ключа , L2J сервера)
2 - GS: GSDecode (C4/C5 ключ 8 байт, инкрементация всего ключа , official сервер LA2)
3 - GS: GSDecodeI (Interlude ключ 16 байт, инкрементация второй половины)
1 - LS: BF decode
2 - LS: BF decode, RSA present
RFO: ...

gSys.tLA2BFdecode : bool; - флаг BF дешифровки (только LA2 LS)
gSys.tLA2BFToken : string; - токен BF дешифровки (только LA2 LS)

Функции класса gSys:

gSys.SetIDposlen(pos, len : integer);
установить позицию и размер байт(а) ID пакетов текущего трафика.
необходимо для работы фильтрации и идентификации пакетов.
pos - позиция байт(а) ID, начинается с единицы
len - размер ID, значение может быть от 1 до 8
(при автоопределении данные берутся из файла 'pckinfo.ini')
по умолчанию это третий байт, размер 1 байт.

gSys.GetIDposlen(var pos, len : integer) : boolean;
получить позицию и размер байт(а) ID пакетов текущего трафика.
ф-ция возвращает 'true' если ID был установлен до этого нормально и 'false' если стоит по умолчанию.

gSys.Tick : int; - вернет количество миллисекунд прошедших со старта компьютера (стандартная ф-ция GetTickCount)
gSys.Tick(var,ms) : bool - вернет true, если прошло время равное 'ms' или больше
с последнего запуска этой ф-ции (с той же переменной var).
переменную 'var' использовать разную в каждом новом 'Tick' иначе они будут друг другу мешать.

gSys.sleep(ms); - жесткая задержка скрипта (в ms.)
(использовать только при крайней необходимости задержки потока !)

gSys.SendC(string {,len}) : int - послать пакет на клиент без шифровки.
если размер пакета не указывать, то он определится автоматически.
gSys.EnSendC(string {,len}) : int - послать пакет на клиент с шифровкой,
пакет автоматически зашифруется действующими ключами, если они определились(De/EnCode: Tx) , либо, если установлен PDecode в ручную.

gSys.SendS(string {,len}) : int,
gSys.EnSendS(string {,len}) : int - тоже, что и предыдущие ф-ции, но послать пакет на сервер.

Функции '.EnSendC' и '.EnSendS' шифруют пакет в зависимости от типа трафика, если это трафик la2, то используется метод шифровки 'GSDecode'.

Ф-ции отсыла пакетов возвращают количество удачно отосланых байт,
либо '-1' , если отослать не удалось, т.е. была ошибка.

gSys.Killself; - разорвать соединение, дисконнект. (убивается трид сессии)
(тоже в ручную делает кнопка [Terminate Link] на главной панели Links Online )
gSys.Killself(time); - разорвать соединение, дисконнект через 'time' миллисекунд(1000 = 1 сек).
советую всегда ставить немного задержку, хотя бы 3000 - gSys.Killself(3000);

17.

VII) Функции скрипт-языка FS. (продожение)

Функции и Классы PPC скрипт-движка FS (4/4)

= gCrypt: =
Класс gCrypt является объектом системного класса и не требует инициализации,
это системный класс-переходник, имеющий следующие методы и переменные:

Функции класса gCrypt:

gCrypt.DecGS(buf; var key; KeyType) : bool;
- Декодирует строку-буфер пакета 'buf' Гейм-сервера (GS) ключем 'key' (LA2 - функция).
gCrypt.EncGS(buf; var key; KeyType) : bool;
- Кодирует строку-буфер пакета 'buf' Гейм-сервера (GS) ключем 'key' (LA2 - функция).
Ключи 'key' изменяются в соответствии с правилами (де)кодирования GS LA2 (KeyType).
'buf' - бинарная строка буфера/пакета
'key' - бинарная строка с ключем, размер должен соответствовать KeyType.
'KeyType' - integer, см. 'gSys.tKeyType'
Ф-ции возвращают 'true' если отработали удачно и 'false' если не удачно.

gCrypt.LSchks(buf {,cs}) : bool; чексумма (LA2 - функция, для С2-С5 версий протоколов)
- возвращает 'true' если чексумма строки/пакета 'buf' Логин-сервера (LS) сходна с указанной в самом пакете, иначе 'false'.
! Размер buf должен быть не менее 8, иначе игнорируется.
! Пакет может быть, как с 2 начальными байтами размера пакета, так и без них. Определяется автоматически.
Если присуствует аргумент 'cs', то в нем возвращается значение чексуммы.

Blowfish:
gCrypt.BFinit(key {,len}) : bool; - инициализация ключа BF, ключ = token, строка.
вернет 'true' если удачно. ('len' - длина, не обязательно)

gCrypt.BFdec(buf {,len}) : bool; - BF кодировка строки/буфера 'buf'(пакета)
gCrypt.BFenc(buf {,len}) : bool; - BF декодировка строки/буфера 'buf' (пакета)
вернет 'true' если удачно. ('len' - длина, не обязательно)
в этих ф-циях размер буфера(пакета) должен быть кратен 8, иначе последние, не кратные, байты не закодируются.

Base64:
gCrypt.EnBase64(buf) : buf; - вернет закодированную строку/буфер 'buf' в Base64
gCrypt.DeBase64(buf) : buf; - вернет декодированную строку/буфер 'buf' из Base64
если (де)кодирование НЕ успешно, вернет пустую строку '' с нулевой длиной.
более подробно о Base64 тут: _http://ru.wikipedia.org/wiki/Base64
пример:
bo := gCrypt.DeBase64(bi);
if (length(bo) = 0) and (length(bi) <> 0) then Writelogln('Ошибка декодирования Base64');

gCrypt.MD5(buf) : buf; - Возвращает 16 байтный MD5 hash буфера/строки 'buf'.
результат бинарный.
Пример для перевода в ascii-hex :
with gCrypt do writelogln(buftohex(sha1('asdasdasd')));
// выведет в лог '00EA1DA4192A2030F9AE023DE3B3143ED647BBAB'

gCrypt.SHA1(buf) : buf; - Возвращает 20 байтный SHA-1 hash буфера/строки 'buf'.
результат бинарный.

18.

VII) Функции скрипт-языка FS. (продожение)

Функции и Классы PPC скрипт-движка FS [5]

= gWSA: = (начиная с версии WP504F)
Класс gWSA является объектом системного класса и не требует инициализации,
это системный класс-переходник, имеющий следующие методы и переменные:

Функции класса gWSA:

Внимание! Это упрощенная версия нескольких ф-ций, достаточных для установки TCP соединения и работы с ним.

gWSA.TCPsocket(block : boolean) : TSocket;
- открытие сокета (который будет использоваться для TCP соединения)
если 'block' = true тогда сокет блокирующий, иначе не блокирующий.

gWSA.connect(socket : TSocket, ip,port : integer) : integer;
- открытие TCP соединения.
вернет -1 если ошибка (далее использовать gWSA.GetLastError для получения номера ошибки)

gWSA.select(socket; r, w, e : flag; sec, usec : integer) : integer;
- ф-ция 'обертка' для стандартного select.
для использования нужно задать вместо флага 'r','w' и/или 'e' булеву переменную
если флаг не используется, то указать NULL
в эти переменные вернется соответствующий флаг
либо ф-ция вернет 0 если тайм аут(время в 'sec' - целые секунды, 'usec' - микросекунды)
ф-ция вернет -1 если ошибка (далее использовать gWSA.GetLastError для получения номера ошибки)

gWSA.recv(socket; var buf : string) : integer; - аналог стандартной 'recv'
gWSA.send(socket; buf : string) : integer; - аналог стандартной 'send'

gWSA.ShutClose(socket); - закрытие соединения и освобождение сокета

gWSA.GetLastError : integer; - аналог стандартной WSAGetLastsError
gWSA.SetLastError(err : integer); - аналог стандартной WSASetLastError

= gInfo: = (начиная с версии WP656F)

IP и Порт локальных и удаленных сокетов сессии:
gInfo.ServerRemoteIP : integer; // тоже, что и _gServIP
gInfo.ServerRemotePort : integer; // тоже, что и _gServPort
// остальные это ip и port обоих сокетов:
gInfo.ServerLocalIP : integer;
gInfo.ServerLocalPort : integer;
gInfo.ClientRemoteIP : integer;
gInfo.ClientRemotePort : integer;
gInfo.ClientLocalIP : integer;
gInfo.ClientLocalPort : integer;
возвращают IP: Port обоих сокетов (клиента и удаленного)

некоторая инф-я о перехваченном процессе модулем MI (Multi Injector):
gInfo.ProcessID : integer;
возвращает ID перехваченного процесса, в случае, если трафик был перехвачен через MI
возвращает 0 если ID процесса не известен.
gInfo.ProcessName : string;
gInfo.ProcessPath : string;
возвращают Имя и путь модуля перехваченного процесса, в случае, если трафик был перехвачен через MI

константы возвращающие версию WP:
gInfo.GetVerWP : string; - возвращает версию WP
gInfo.GetVerPPC : string; - возвращает версию PPC
gInfo.GetVerMI : string; - возвращает версию MI
gInfo.GetVerSE : string; - возвращает версию SE



  19.

VII) Функции скрипт-языка FS. (продожение)

Функции и Классы PPC скрипт-движка FS [6]

= gDLL: = (начиная с версии WP505F)
Класс gDLL является объектом системного класса и не требует инициализации.
инициализации требует сама DLL.

объект gDLL используется для подгрузки внешних DLL и вызова их ф-ций.

!Внимание!
Ф-ции DLL должны быть безопасны для многопоточного приложения, которым является PPC.
Любые ошибки в DLL или в вызове ф-ций могут привести к падению системы, либо не устойчивой работе.

примеры использования см. в дистрибутиве wp505F.
демонстрационные DLL с исходниками находятся в директории 'dll\'
демо скрипты в 'wpsc\DEMO\'

Функции класса gDLL:

gDLL.LoadLib(name : string) : handle;
- аналог ф-ции Win32:LoadLibrary() - загружает DLL библиотеку.
'name' - имя и если нужно путь до файла динамической библиотеки.
возвращает хендл DLL либо 0 если ошибка (в этом случае см. GetLastError)

gDLL.FreeLib(handle);
- почти аналог ф-ции Win32:FreeLibrary()
'handle' - хендл DLL из ф-ции gDLL.LoadLib
выгружает DLL, либо уменьшает счетчик загрузок этой DLL.

gDLL.GetProcAddr(hlib : handle; funcName : string) : integer;
- аналог ф-ции Win32:GetProcAddress.
возвращает адрес ф-ции DLL по имени.
либо возвращает 0 если была ошибка (тогда см. GetLastError)
'hlib' - хендл DLL, см. gDLL.LoadLib()
'funcName' - строка с именем ф-ции DLL.
внимание! имя указываемой ф-ции чувствительно к регистру!

gDLL.CallFuncF5(hlib : handle; fn/addr; frmstr : string; var a1,a2,a3,a4,a5 : variant) : integer;
- вызов ф-ций DLL имеющих от 0 до 5 аргументов с описанием аргументов в форматной строке.
'hlib' - хендл объекта, см. gDLL.LoadLib()
'fn/addr' - может быть как строкой с именем ф-ции, так и адресом ф-ции, полученным gDLL.GetProcAddr()
'frmstr' - строка описания типов аргументов, имеет до 5 последовательных символов (так как до 5 аргументов)
a1,a2..a5 - аргументы, каждый аргумент описывается последовательно в форматной строке 'frmstr':
'd' аргумент в скрипте integer, в DLL передается pascal 'integer'
'r' аргумент в скрипте real/single, в DLL передается pascal 'single' (short-float)
's','p' аргумент в скрипте string, в DLL передается 'Pchar', указатель на первый байт строки/блока.
соответственно, любое изменение блока в DLL отразится на переменной в скрипте.
'D' аргумент в скрипте integer, в DLL передается указатель на 'integer'
в DLL аргумент должен быть описан как 'var integer' !
изменение содержимого отразится на переменной в скрипте.
'R' аргумент в скрипте real/single, в DLL передается указатель на 'single'
в DLL аргумент должен быть описан как 'var single' !
соответственно, изменение содержимого отразится на переменной в скрипте.
ф-ция CallFuncF5 возвращает значение integer из вызываемой ф-ции DLL.
если произошла ошибка, то возвращает '-1' и далее см. ф-цию GetLastError.

примеры см. в демо скриптах и демо-DLL.
!Внимание:
!если вызываемая ф-ция DLL имеет меньшее кол-во аргументов, то лишние аргументы в скрипте должны быть 'null'
!несоответствие в количестве либо в типе аргументов вызова ф-ции и самой ф-ции в DLL может привести к падению процесса WP PPC.

gDLL.CallFuncF10(hlib : handle; fn/addr; frmstr : string; var a1,a2,a3..a10 : variant) : integer;
- аналогично gDLL.CallFuncF5, только максимальное количество аргументов до 10
соответственно, лишние аргументы (последние) указываем как 'null';

gDLL.CallFunc3(hlib : handle; fn/addr; a1,a2,a3 : variant) : integer;
- упрощенный вызов ф-ций DLL имеющих от 0 до 3 аргументов.
Функция не имеет форматной строки, аргументы - константы (кроме строчных, там всегда PChar на строку)
'hlib' - хендл объекта, см. gDLL.LoadLib()
'fn/addr' - может быть как строкой с именем ф-ции, так и адресом ф-ции, полученным gDLL.GetProcAddr()
a1,a2,a3 - аргументы, типы аргументов могут быть:
аргумент в скрипте integer - в ф-цию DLL передается pascal 'integer' type
аргумент в скрипте real/single - в ф-цию DLL передается pascal 'single' type (short-float)
аргумент в скрипте string - в ф-цию DLL передается 'pchar' type, являющийся указателем на первый символ строки/блока.
в последнем случае любое изменение блока изменит и содержимое аргумента в скрипте.
!если вызываемая ф-ция DLL имеет меньшее кол-во аргументов, то лишние аргументы в скрипте должны быть 'null'
!несоответствие в количестве аргументов приведет к падению процесса WP PPC.
CallFunc3 возвращает значение integer из ф-ции DLL.
если возвращаемое значение '-1' то см. ф-цию GetLastError.

gDLL.CallFunc6(hlib : handle; fn/addr; a1,a2,a3..a6 : variant) : integer;
- аналогично gDLL.CallFunc3, только максимальное количество аргументов до 6

gDLL.CallFunc9(hlib : handle; fn/addr; a1,a2,a3..a9 : variant) : integer;
- аналогично gDLL.CallFunc3, только максимальное количество аргументов до 9

Пример:
вызов стандартной win32 ф-ции 'MessageBoxA' системной библиотеки 'User32.dll':
(запускать в скрипт-тестере, описание ф-ции MessageBoxA см. в интернете)

var hlib : handle;
begin
ScriptTimeOut(99999); // выключим таймер в скрипт-тестере.

hlib := gDLL.LoadLib('User32.dll'); // DLL системная, можно путь не указывать
gDLL.CallFunc6(hlib, 'MessageBoxA', nil, 'Сообщение', 'msg: ', 0, null, null);
gDLL.FreeLib(hlib);
end.

Второй вариант:
var hlib : handle;
begin
ScriptTimeOut(99999); // выключим таймер в скрипт-тестере.

hlib := gDLL.LoadLib('User32.dll'); // DLL системная, можно путь не указывать
gDLL.CallFuncF5(hlib, 'MessageBoxA', 'dssd',nil, 'Сообщение', 'msg: ', 0, null);
gDLL.FreeLib(hlib);
end.

Третий вариант:
var hlib : handle;
fa : integer;
begin
ScriptTimeOut(99999); // выключим таймер в скрипт-тестере.

hlib := gDLL.LoadLib('User32.dll'); // DLL системная, можно путь не указывать
if hlib = 0 then begin
writelogln('Ошибка: '+SysErrorMessage(GetLastError));
exit;
end;
fa := gDLL.GetProcAddr(hlib, 'MessageBoxA'); // берем адрес ф-ции, как вариант.
if fa = 0 then begin
writelogln('Ошибка: '+SysErrorMessage(GetLastError));
end else begin
gDLL.CallFunc6(hlib, fa, nil, 'Сообщение', 'msg: ', 0, null, null);
end;
gDLL.FreeLib(hlib);
end.

Более подробные примеры см. в скприпте wpsc\DEMO\gDLL-ex1.fsc
исходники необходимой DLL в dll\source\

Небольшое замечание:
Строка/буфер, отосланная в DLL придет там в виде указателя на символ (Pchar) , и следовательно, индексация первого символа будет pchar[0], в тоже время как в самом скрипте первый символ строки/буфера это buf[1].
Просто помните это

Внимание!

1. Ф-ции DLL должны быть безопасны для многопоточного приложения, которым является PPC. (что такой 'multithreaded' читайте в интернете)

2. В DLL передача динамических объектов, которые инициализированы внутренним менеджером памяти PPC (например, переменные string),
запрещено.

При написание DLL в стиле c++ (не используя передачу типов string и других динамических объектов инициализированных в PPC) никаких осложнений не требуется. (тогда пишите DLL хоть на фортране)

Использование VCL в DLL КРАЙНЕ не рекомендуется, но если это очень необходимо, то только с FastMM4 (не ниже версии что я указал в ссылке) и компилировать на delphi6. (либо настроить FastMM4Options.inc для других дельфи)

ShareMM не включено, любые созданные динамические объекты в DLL должны быть в этой же DLL освобождены.


20.

Немного о синтаксисе скрипт-языка FS. (продожение)

Пример использования директивы Uses.

Делаем первый файл , называем его demo-uses1.fsc
Это юнит-файл (uses-файл) который подцепляется из основного скрипта.
Код:

// demo-uses1.fsc  - привет использования директивы Uses. файл-юнит.
//  Unit 'demo-uses1.fsc'  <- объявлять скрипт юнитом  НЕ требуется.

function Func001 : boolean;
begin
  writelogln('сообщение из ф-ции Func001');
end;

begin
  writelogln('сообщение из тела юнита');

end.
Делаем второй файл - это основной скрипт.
Код:

// demo-uses2.fsc - пример использования директивы Uses, основной файл.

uses 'wpsc/demo-uses1.fsc';   // загружаем юнит-скрипт

begin
  writelogln('сообщение из основного скрипта перед вызовом ф-ции из юнита');
  func001;     // вызываем ф-цию из юнит-скрипта.

end.
Когда компилируем в xml скрипт, то все Uses файлы компилируются в него, и отдельно не требуются.

Внимание !!!! Uses файл может быть xml.
Т.е. файл который указывается в Uses так же может быть и xml-скрипт.

в директиве Uses можно указывать несколько файлов.
пример:
Код:

uses 'wpsc/d1.fsc','wpsc/d2.xml';
Функции OnCreate и OnDestroy должны быть только в одном из скриптов, так как дубликаты любых ф-ций не допускаются

Функции-события в FS.

функции-события OnCreate и OnDestroy
(О них много было сказано ранее в данной документации).

ф-ция 'OnCreate' вызывается один раз сразу после компиляции, а 'OnDestroy' в конце соединения (или при перекомпиляции)
ф-ции 'OnCreate' и 'OnDestroy' могут отсуствовать в скрипте.
все созданные динамические объекты в скрипте обязаны быть освобождены в 'OnDestroy' или ранее.

функции-события OnDeCode и OnEnCode
ф-ции автоматически вызываются при необходимости декодирования пакета (OnDeCode) после получения пакета
и обратного кодирования (OnEnCode) перед отсылкой пакета.
Эти ф-ции могут быть только в первом скрипте и только в FS-типе скриптах.
ф-ции не обязательны и могут отсутствовать в скрипте.

OnDeCode вызывается при получении пакета и ДО записей в автологгер основных пакетов и ДО автоматического декодирования (если включено)
в логгер попадет запись о пришедшем пакете уже после этой ф-ции (и после автодекодирования, если оно включено)

OnEnCode вызывается перед отсылкой пакета, но уже после записи в автологгер основных пакетов и ПОСЛЕ автоматического кодирования (если включено)
в логгер попадет запись о отсылаемом пакете ДО вызова этой ф-ции (если пакет вообще был изменен или отослан)

! так же, ф-ция OnEnCode вызывается автоматически при использовании gSys.EnSendC и gSys.EnSendS
!! Внимание !!
! в OnEnCode запрещено использовать ф-ции gSys.EnSendC и gSys.EnSendS во избежание замкнутой рекурсии

! ф-ция OnEnCode вызывается при ручной отсылке на закладке 'Send Raw Packet' !
если скрипт установлен и определена эта ф-ция, то вначале вызывается автокодирование (если включено), затем OnEnCode, далее пакет отсылается.

В этих ф-циях применяются следующие специальные переменные:
'_dBuff' - входной буфер пакета (не путать с _gBuff)
'_dOutBuff' - выходной буфер пакета (не путать с _gOutBuff)
'_dFromServ' - флаг направления пакета (не путать с _gFromServ)

Более подробно см. в демо скриптах demo_la2-endecGS-4.fsc и demo_la2-endecGS-5.fsc
demo_la2-endecGS-4.fsc - демонстрация автоопределения LA2 GS трафика и де/кодировка GS трафика.
demo_la2-endecGS-5.fsc - тоже самое, только используется DLL, где содержатся ф-ции определения и де/кодировки.

функции-события OnDeCodeAlt и OnEnCodeAlt
эти ф-ции полностью схожи с OnDecode и OnEnCode кроме того,
что вызываются в другой последовательности. (см. далее)
! в OnEnCodeAlt (по аналогии с OnEnCode) запрещено использовать ф-ции gSys.EnSendC
и gSys.EnSendS во избежание замкнутой рекурсии (так как эти ф-ции генерят эти же события)

функция-событие OnParse
Событие предназначено для парсинга пакетов с кодированными первыми
байтами размера пакета, либо вообще без них. (например, протоколы WOW, PW, Cabal ..)
имеет возвращаемую величину boolean.

Код:

function OnParse : boolean; // функция-событие на парсинг буфера пакетов.
// эта ф-ция вызывается при получении пакетов со стека TCP
//  в виде буфера содержащих один или несколько 'склееных' пакетов.                               
// буфер '_dParseBuff' (на вход и на выход),
// выделенный из буфера пакет '_dParsePck' (выход)
// флаг направления '_dFromServ'
// ф-ция не обязательна и может отсутствовать в скриптах.
begin
  ...
  // result :=  false; - автопарсинг после ф-ции не производится.                                                                                                                                                                                                               
  ...
end;
на данный момент последовательность вызова событий и обработки пакета:
0. пришел пакет в буфер
1. вызов ф-ции события OnParse (_dParseBuff >> _dParsePck > _gBuff)
2. -
3. автоматический парсинг пакета из буфера (если был разрешен)
4. автоматическое определение протокола, ключей (если включено автоопределение)
5. вызов ф-ции события OnDeCode
6. -
7. автоматическое декодирование пакета (если включено автодекодирование)
8. вызов ф-ции события OnDeCodeAlt
9. далее запускаются все три скрипта по порядку
10. фильтрование
11. запись в лог пакетов (_gBuff, _gOutBuff и пакетов отосланных в скриптах)
12. вызов ф-ции события OnEnCodeAlt
13. автоматическое кодирование (если включено автодекодирование)
14. -
15. вызов ф-ции события OnEnCode
16. запись в лог текста (writelog, writelogln, writeloghexb)
17. отсылаеся _gOutBuff, если не был блокирован в скриптах.
(прочерками отмечены не опубликованные позиции)

!! Внимание !!
! в OnEnCodeAlt (по аналогии с OnEnCode) запрещено использовать ф-ции gSys.EnSendC
и gSys.EnSendS во избежание замкнутой рекурсии (так как эти ф-ции генерят эти же события)
так же, ф-ции события OnEnCode/OnEnCodeAlt вызываются при отсылке пакетов вручную.

0

5

ну ты отжог! ) Читать не стал ( МНОГА БУКАВОК ) но все равно пасиб. )

0

6

нз =)

0

7

Да ну и Админы даже не оценили вот и выкладывай когда не ЦЕНЯТ !!!

0

8

Чел, ты сам то понял что написал  про  ВПФшку?))))Ахаха.....))))

0

9

ну и по написал ппц :writing:

0

10

ну и по написал ппц :writing:

0

11

да жжесть прости чувак скатано то красиво то ка эта вся брихня про LA2  :D

0