Вернуться   CoderX :: Forums > Lineage II > L2PacketHack > Скриптинг
Войти через OpenID

Скриптинг Форум посвещенный созданию скриптов для L2PacketHack

Чат (Новых сообщений с момента вашего последнего визита нет)
Загрузка...
Задавайте ваши вопросы на форуме. Чат предназначен для небольших разговоров.
 
Ответ
 
Опции темы Опции просмотра
Старый 11.10.2008, 00:38   #1
Admin!
 
Аватар для xkor
 
Регистрация: 04.08.2007
Сообщений: 2,360
Сказал Спасибо: 113
Имеет 1,566 спасибок в 651 сообщенях
xkor на пути к лучшему
По умолчанию О плагинах для l2phx 3.4.1+

Итак вот подробное описание того какой должна быть структура плагина:
delphi Код:
library plugin_demo2; {$define Release} // для совместимости с релизом пакетхака, при дебуге можно закоментировать uses   FastMM4,   Coding in 'Coding.pas'; // модуль с описаниями основных типов                           // используемых в плагине и программе var                                {version} {revision}   min_ver_a: array[0..3] of Byte = ( 3,4,1,      46   );   min_ver: Integer absolute min_ver_a; // минимальная поддерживаемая версия программы   ps: TPluginStruct; // структура передаваемая в плагин // Обязательно вызываемая функция. // Должна вернуть описание плагина, // заодно может проверить версию программы function GetPluginInfo(const ver: Integer): PChar; stdcall; begin   if ver<min_ver then     Result:='Демонстрационный Plugin к программе l2phx'+sLineBreak+             'Для версий 3.4.0+'+sLineBreak+             'У вас старая версия программы! Плагин не сможет корректно с ней работать!'   else     Result:='Демонстрационный Plugin к программе l2phx'+sLineBreak+             'Для версий 3.4.0+'; end; // Обязательно вызываемая функция. // Получает структуру с ссылками на все функции основной программы, // которые могут вызываться из плагина. // Если вернёт False то плагин выгружается. function SetStruct(const struct: TPluginStruct): Boolean; stdcall; begin   ps:=struct;   Result:=True; end; // Необязательно вызываемая функция. (может отсутствовать в плагине) // Вызывается при установки соединения (cnt) с клиентом (withServer=False) // или сервером (withServer=True) procedure OnConnect(const cnt: Cardinal; // номер соединения                     const withServer: Boolean); stdcall; // с сервером? begin end; // Необязательно вызываемая функция. (может отсутствовать в плагине) // Вызывается при разрыве соединения (cnt) с клиентом (withServer=False) // или сервером (withServer=True) procedure OnDisconnect(const cnt: Cardinal; // номер соединения                        const withServer: Boolean); stdcall; // с сервером? begin end; // Необязательно вызываемая функция. (может отсутствовать в плагине) // Вызывается при выгрузке плагине procedure OnFree; stdcall; begin end; // Необязательно вызываемая функция. (может отсутствовать в плагине) // Вызывается при загрузке плагине procedure OnLoad; stdcall; begin end; // Необязательно вызываемая функция. (может отсутствовать в плагине) // Вызывается при вызове скриптовой функции обьявленной в RefreshPrecompile function OnCallMethod(const MethodName: String; // имя функции в верхнем регистре                       var Params, // параметры функции                       FuncResult: Variant // результат функции          ): Boolean; stdcall; // если вернёт True то дальнейшая                               // обработка функции прекратиться begin   Result:=False; // передаём обработку функции программе   if MethodName='PI' then begin     Result:=True; // запрещаем дальнейшую обработку функции в программе     FuncResult:=Pi;   end; end; // Необязательно вызываемая функция. (может отсутствовать в плагине) // Вызывается перед компиляцией скриптов function OnRefreshPrecompile(var funcs: TStringArray): Integer; stdcall; begin   SetLength(funcs,1); // указываем количество добавляемых в скрипт функций   funcs[0]:='function Pi:Extended'; // одна из добавляемых функций end; // Необязательно вызываемая функция. (может отсутствовать в плагине) // Вызывается при приходе пакета, параметры: // cnt - номер соединения // fromServer - если пакет от сервера равна True, если от клиента то False // pck - собственно пакет (в виде массива) procedure OnPacket(const cnt: Cardinal; const fromServer: Boolean; var pck: TPacket); stdcall; begin   if pck.size<3 then exit; // на случай если предыдущие плагины обнулили пакет end; // экспортируем используемые программой функции exports   GetPluginInfo,   SetStruct,   OnPacket,   OnConnect,   OnDisconnect,   OnLoad,   OnFree,   OnCallMethod,   OnRefreshPrecompile; begin end.

о передоваемой плагину структуре TPluginStruct:
delphi Код:
TPluginStruct = packed record     Threads: PThreads; // указатель на первый элемент массива TThread                        // через него можно получить доступ к любой переменной соединения     ThreadsCount: Integer; // максимальное число соединений                            //(не путать с количеством реально установленых соединений!)     // функции отправки пакета:     SendPck: TSendPacket;     SendPckStr: TSendPckStr;     SendPckData: TSendPckData;     // функции преобразования:     DataPckToStrPck: TDataPckToStrPck; // преобразует пакет из массива в строку и отрезает 2 байта длинны     HexToString:THexToString; // преобразует Hex пакета в просто пакет в виде строки     StringToHex:TStringToHex; // наоборот     // функции чтения из пакета в виде строки:     ReadC: TReadC;     ReadH: TReadH;     ReadD: TReadD;     ReadF: TReadF;     ReadS: TReadS;     // функции чтения из пакета в виде массива:     ReadCEx: TReadCEx;     ReadHEx: TReadHEx;     ReadDEx: TReadDEx;     ReadFEx: TReadFEx;     ReadSEx: TReadSEx;     // функции записи в пакет в виде строки:     WriteC: TWriteC;     WriteH: TWriteH;     WriteD: TWriteD;     WriteF: TWriteF;     WriteS: TWriteS;     // функции записи в пакет в виде массива:     WriteCEx: TWriteCEx;     WriteHEx: TWriteHEx;     WriteDEx: TWriteDEx;     WriteFEx: TWriteFEx;     WriteSEx: TWriteSEx;     // функции работы с таймером на основе отдельного потока:     CreateAndRunTimerThread: TCreateAndRunTimerThread; // создаёт и запускает таймер     ChangeTimerThread: TChangeTimerThread; // может изменить интервал, параметр                                            // пользователя и процедуру вызываемую таймером     DestroyTimerThread: TDestroyTimerThread; // останавливает и уничтожает таймер   end;
у функций чтения первый параметр это пакет, второй - позиция с которой производиться чтение
у функций записи первый параметр это пакет, второй - записываемые данные, третий - индекс в который производиться запись, если 3й параметр не задан или равен -1, то данные пишутся в конец пакета
о параметрах остальных функций из структуры:
delphi Код:
procedure SendPacket(Size: Word; // размер пакета (размер pck +2)                        pck: string; // пакет в виде строки без первых 2х байт длинны                        tid: Byte; // номер соединения                        ToServer: Boolean); // направление отсылки, если True то на сервер   procedure SendPckStr(pck: string; // пакет в виде строки без первых 2х байт длинны                        const tid: Byte; // номер соединения                        const ToServer: Boolean); // направление отсылки, если True то на сервер   procedure SendPckData(var pck; // пакет в виде массива                         const tid: Byte; // номер соединения                         const ToServer: Boolean // направление отсылки, если True то на сервер             ); stdcall;   function DataPckToStrPck(var pck // пакет в виде массива            ): string; stdcall; // возвращает пакет в виде строки   function HexToString(Hex:String // HEX строка            ):String;   function StringToHex(s, // пакет в виде строки                        Separator:String // разделитель между байтами            ):String;   function CreateAndRunTimerThread(const interval, // интервал срабатывания таймера                                    usrParam: Cardinal; // параметр передаваемый в процедуру OnTimerProc                                    const OnTimerProc: TOnTimer // вызывается при срабатывании таймера            ): Pointer; stdcall; // возвращает указатель на объект потока   procedure ChangeTimerThread(const timer: Pointer; // указатель на объект потока                               const interval: Cardinal; // интервал срабатывания таймера                               const usrParam: Cardinal = $ffffffff;                               // параметр передаваемый в процедуру OnTimerProc,                               // если равен $ffffffff, то не меняется                               const OnTimerProc: TOnTimer = nil                               // вызывается при срабатывании таймера, если nil - не меняется             ); stdcall;   procedure DestroyTimerThread(var timer: Pointer // указатель на объект потока             ); stdcall;
__________________
Я здесь практически не появляюсь!, Skype - ikskor
xkor вне форума   Ответить с цитированием
За это сообщение xkor нажился 16 спасибками от:
Старый 13.10.2008, 18:31   #2
Admin!
 
Аватар для xkor
 
Регистрация: 04.08.2007
Сообщений: 2,360
Сказал Спасибо: 113
Имеет 1,566 спасибок в 651 сообщенях
xkor на пути к лучшему
По умолчанию

Ещё пожалуй расскажу о том как наиболее удобно отлаживать плагин
Вариант 1 (отладка только плагина):
1. Компилим плагин
2. Запускаем пакетхак
3. В delphi выбираем меню Run -> Attach to Process...
4. там находим и выбираем l2pbx.exe, убираем галочку "Pause After Attach" и жмём Attach
5. В пакетхаке подключаем плагин
6. Усё, можем ставить бряки в плагине

Вариант 2 (отладка программы вместе с плагином):
1. В дельфи создаём группу из проекта программы и проекта плагина
2. Компилим оба проекта (не забываем указать путь компиляции для плагина в папку plugins)
3. Запускаем программу с дебугом
4. В программе подключаем плагин и дельфи автоматически распознаёт что эта dll из группы и даёт возможность ставить бряки и в проекте плагина

Первый вариант позволяет отлаживать плагин без перекомпиляции основной программы, тоесть можно работать только с плагином
Второй позволяет отлаживать всё сразу

ЗЫ описание на основе дельфи 2007, но в 2006 скорее всего всё так же, а в более ранних версиях думаю тоже должны быть аналогичные возможности, но возможно немного в других местах
__________________
Я здесь практически не появляюсь!, Skype - ikskor
xkor вне форума   Ответить с цитированием
За это сообщение xkor нажился 4 спасибками от:
Старый 01.01.2009, 07:40   #3
Пользователь
 
Регистрация: 04.12.2008
Сообщений: 43
Сказал Спасибо: 11
Имеет 29 спасибок в 21 сообщенях
Xelat пока неопределено
По умолчанию

А как насчёт расписать TPacket?
Что включает параметр size, data?
Например содержится ли TPacket.id ещё и в TPacket.data[0]?
TPacket.size указывает размер всего пакета, или только данных? (хотя по проверке pck.size<3 я считаю что это длина всего пакета с байтами длины и айдишкой, но лучше перестраховаться)
Xelat вне форума   Ответить с цитированием
Старый 01.01.2009, 15:31   #4
Admin!
 
Аватар для xkor
 
Регистрация: 04.08.2007
Сообщений: 2,360
Сказал Спасибо: 113
Имеет 1,566 спасибок в 651 сообщенях
xkor на пути к лучшему
По умолчанию

Xelat, структура TPacket описана в файле Coding.pas вот так:
delphi Код:
PPacket = ^TPacket;   TPacket = record     size: Word;     id: Byte;     data: array[Word] of Byte;   end;
__________________
Я здесь практически не появляюсь!, Skype - ikskor
xkor вне форума   Ответить с цитированием
Старый 01.01.2009, 20:17   #5
Пользователь
 
Регистрация: 04.12.2008
Сообщений: 43
Сказал Спасибо: 11
Имеет 29 спасибок в 21 сообщенях
Xelat пока неопределено
По умолчанию

Ну блин, структуру я не идиот, там и смотрел!
Я ж не структу прошу расписать, а ньюансы полей.
А вот в SendPckData с массивом вообще не понятно, ну передам я массив байт, а как определяется конец пакета? Или надо передавать массив вместе с длиной пакета?
А так же в чём разница между процедурами SendPacket и SendPckStr? Первая отсекает строку заданного размера?
Вобщем подробностей бы побольше!
Xelat вне форума   Ответить с цитированием
Старый 08.01.2009, 22:04   #6
Новичок
 
Регистрация: 17.05.2008
Сообщений: 22
Сказал Спасибо: 5
Имеет 1 спасибку в 1 сообщении
pir пока неопределено
По умолчанию

А в плагинах VCL можно использовать?
pir вне форума   Ответить с цитированием
Старый 08.01.2009, 22:48   #7
Рыцарь
 
Аватар для QaK
 
Регистрация: 28.09.2007
Сообщений: 1,558
Сказал Спасибо: 71
Имеет 351 спасибок в 244 сообщенях
QaK пока неопределено
По умолчанию

Цитата:
Сообщение от pir Посмотреть сообщение
А в плагинах VCL можно использовать?
можно, только осторожно =) и вообще нафиг тебе VCL?
QaK вне форума   Ответить с цитированием
Старый 08.01.2009, 22:55   #8
Новичок
 
Регистрация: 17.05.2008
Сообщений: 22
Сказал Спасибо: 5
Имеет 1 спасибку в 1 сообщении
pir пока неопределено
По умолчанию

Хочу сервер сделать с помощью компонента ServerSocket, чтоб можно было проходящие пакеты удаленно принимать.
pir вне форума   Ответить с цитированием
Старый 08.01.2009, 23:10   #9
Рыцарь
 
Аватар для QaK
 
Регистрация: 28.09.2007
Сообщений: 1,558
Сказал Спасибо: 71
Имеет 351 спасибок в 244 сообщенях
QaK пока неопределено
По умолчанию

Цитата:
Сообщение от pir Посмотреть сообщение
Хочу сервер сделать с помощью компонента ServerSocket, чтоб можно было проходящие пакеты удаленно принимать.
да вы. батенька, маньяк =) не иначе что-то хитрое задумал =)
QaK вне форума   Ответить с цитированием
Старый 08.01.2009, 23:15   #10
Новичок
 
Регистрация: 17.05.2008
Сообщений: 22
Сказал Спасибо: 5
Имеет 1 спасибку в 1 сообщении
pir пока неопределено
По умолчанию

Ничего хитрого, просто GG всю отладку рубит, хотю на другой машине или под виртуалкой это делать
pir вне форума   Ответить с цитированием
Ответ

  CoderX :: Forums > Lineage II > L2PacketHack > Скриптинг


Опции темы
Опции просмотра

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 00:05.

vBulletin style designed by MSC Team.
Powered by vBulletin® Version 3.6.11
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Locations of visitors to this page
Rambler's Top100

Вы хотите чувствовать себя в безопасности? чоп Белган обеспечит её!