PDA

Просмотр полной версии : О плагинах для l2phx 3.4.1+


xkor
11.10.2008, 00:38
Итак вот подробное описание того какой должна быть структура плагина:
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:
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, то данные пишутся в конец пакета
о параметрах остальных функций из структуры:

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;

xkor
13.10.2008, 18:31
Ещё пожалуй расскажу о том как наиболее удобно отлаживать плагин
Вариант 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 скорее всего всё так же, а в более ранних версиях думаю тоже должны быть аналогичные возможности, но возможно немного в других местах

Xelat
01.01.2009, 07:40
А как насчёт расписать TPacket?
Что включает параметр size, data?
Например содержится ли TPacket.id ещё и в TPacket.data[0]?
TPacket.size указывает размер всего пакета, или только данных? (хотя по проверке pck.size<3 я считаю что это длина всего пакета с байтами длины и айдишкой, но лучше перестраховаться)

xkor
01.01.2009, 15:31
Xelat, структура TPacket описана в файле Coding.pas вот так:
PPacket = ^TPacket;
TPacket = record
size: Word;
id: Byte;
data: array[Word] of Byte;
end;

Xelat
01.01.2009, 20:17
Ну блин, структуру я не идиот, там и смотрел! :)
Я ж не структу прошу расписать, а ньюансы полей.
А вот в SendPckData с массивом вообще не понятно, ну передам я массив байт, а как определяется конец пакета? Или надо передавать массив вместе с длиной пакета?
А так же в чём разница между процедурами SendPacket и SendPckStr? Первая отсекает строку заданного размера?
Вобщем подробностей бы побольше! :)

pir
08.01.2009, 22:04
А в плагинах VCL можно использовать?

QaK
08.01.2009, 22:48
А в плагинах VCL можно использовать?можно, только осторожно =) и вообще нафиг тебе VCL?

pir
08.01.2009, 22:55
Хочу сервер сделать с помощью компонента ServerSocket, чтоб можно было проходящие пакеты удаленно принимать.

QaK
08.01.2009, 23:10
Хочу сервер сделать с помощью компонента ServerSocket, чтоб можно было проходящие пакеты удаленно принимать.да вы. батенька, маньяк =) не иначе что-то хитрое задумал =)

pir
08.01.2009, 23:15
Ничего хитрого, просто GG всю отладку рубит, хотю на другой машине или под виртуалкой это делать :)

Xelat
09.01.2009, 01:31
я уже написал такой плагин, использую для своего бота... использовал в нём ICS.

pir
09.01.2009, 15:17
Ну поделись если не жалко. Я пока непойму как назначить обработчик события без наличия формы, такая конструкция Serversocket1.OnClientRead:=Serversocket1ClientRea d; непрокатывает...

Aniks
09.01.2009, 16:30
У тебя наверное Serversocket1.OnClientRead -> метод класса, а Serversocket1ClientRea -> процедура и ты их напрямую пытаешься присвоить. Только у методов класса два указателя - на инстанцию класса и на сам метод, поэтому и не получается. Попробуй свою процедуру Serversocket1ClientRea засунь в какой-нибудь класс, и тогда присваивай.

Xelat
10.01.2009, 01:49
бери пример от ICS - ConSrv1
и от него уже пляши, я так и делал.
если тебе не интересно самому разрабатывать плагин, а нужен только результат - стучи в аську.

Murdoc
12.01.2009, 15:33
Ничего хитрого, просто GG всю отладку рубит, хотю на другой машине или под виртуалкой это делать :)

А примотать к Л2пх сокс прокси не проще?

alexsl
25.01.2009, 10:47
приветы,
вот возникла такая вот ситуевина:

procedure OnPacket(const cnt: Cardinal; const fromServer: Boolean; var pck: TPacket); stdcall;
begin
if pck.size<3 then
exit;
if not FromServer and(pck.id=$49)and(bot.cntID=0)then
begin
// если в процедуре вызвать ps.ReadSEx
// то после завершения процедурки
// выскакивает ексепшн EInvalidPointer
if(lowercase(ps.ReadSEx(pck,3))='set')then
begin
pck.size:=2; // не пропускаем пакет
bot.cntID:=cnt;
Say('Выбрано это соединение.',bot.cntID);
end;
end;
end;

пробывал заменить на

s:=ps.DataPckToStrPck(pck);
if(lowercase(ps.ReadS(s,2))='set')then

выходит аналогичная ошибка.
мб ктонить подскажет, в какую сторону копать.
зы: HB T1.5, пхикс 3.4.81 ( 3.4.68 ) под ХП СП3 крутится на виртуальной машине

QaK
25.01.2009, 19:31
alexsl, дельфа какая версия?

alexsl
25.01.2009, 19:58
QaK, угу забыл указать юзаю Д7. спсб, попробую скомпилить под Д2005

QaK
25.01.2009, 20:00
alexsl, вот поэтому и эксепшн вылазит, перекомпиль в 200х норм должно пхать, хз с чем связано ...

alexsl
26.01.2009, 07:36
как не печально но при компиляции под D2005 результат тот же :(
ошибка:

================================================== ============================
= 26.01.2009 7:19:07 =
================================================== ============================
EInvalidPointer.

Exception class: EInvalidPointer
Exception address: 009F2990
------------------------------------------------------------------------------
System : Windows XP Professional, Version: 5.1, Build: A28, "Service Pack 3"
Processor: Intel, Pentium(R) Dual-Core CPU E5200 @ 2.50GHz, 2490 MHz MMX 64 bits
Memory: 255; free 136
Display : 688x595 pixels, 32 bpp
------------------------------------------------------------------------------
List of loaded modules:
[00340000] C:\WINDOWS\system32\oledlg.dll
<7DFC0000> 5.1.2600.5512 - 1.0 (xpsp.080413-2108)
Поддержка интерфейса пользователя OLE 2.0 для Microsoft WindowsR
[00400000] C:\WINDOWS\system32\Normaliz.dll
6.0.5441.0 - 6.0.5441.0 (winmain(wmbla).060628-1735)
Unicode Normalization DLL
[009F0000] Z:\L2PHX34159\plugins\helper.dll
<00400000> (no version info)
[00EA0000] Z:\L2PHX34159\newxor.dll
<00400000> (no version info)
[01520000] Z:\L2PHX34159\plugins\plugin_bd.dll
<00400000> (no version info)
[13140000] Z:\L2PHX34159\l2pbx.exe
3.4.1.59 - 3.4.1.59
[43090000] C:\WINDOWS\system32\iertutil.dll
7.0.6000.20772 - 7.00.6000.20772 (vista_ldr.080213-1606)
Run time utility for Internet Explorer
[43310000] C:\WINDOWS\system32\wininet.dll
7.0.6000.20772 - 7.00.6000.20772 (vista_ldr.080213-1606)
Internet Extensions for Win32
[5B260000] C:\WINDOWS\system32\uxtheme.dll
6.0.2900.5512 - 6.00.2900.5512 (xpsp.080413-2105)
Библиотека тем UxTheme (Microsoft)
[5F2F0000] C:\WINDOWS\system32\olepro32.dll
5.1.2600.5512 - 5.1.2600.5512
[698B0000] C:\WINDOWS\system32\hnetcfg.dll
5.1.2600.5589 - 5.1.2600.5589 (xpsp_sp3_qfe.080428-1317)
Диспетчер конфигурации домашней сети
[71A30000] C:\WINDOWS\system32\mswsock.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-0852)
Расширение поставщика службы API Microsoft Windows Sockets 2.0
[71A70000] C:\WINDOWS\System32\wshtcpip.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-0852)
Windows Sockets Helper DLL
[71A80000] C:\WINDOWS\system32\WS2HELP.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-0852)
Модуль поддержки Windows Socket 2.0 для Windows NT
[71A90000] C:\WINDOWS\system32\WS2_32.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-0852)
Windows Socket 2.0 32-Bit DLL
[71AB0000] C:\WINDOWS\system32\wsock32.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-0852)
32-разрядная библиотека Windows Socket
[71B00000] C:\WINDOWS\system32\mpr.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-0852)
Библиотека маршрутизации для нескольких служб доступа
[72FC0000] C:\WINDOWS\system32\winspool.drv
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-0852)
Драйвер диспетчера очереди Windows
[746E0000] C:\WINDOWS\system32\MSCTF.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2105)
Библиотека (DLL) MSCTF-сервера
[74DF0000] C:\WINDOWS\system32\RICHED20.DLL
5.30.23.1230 - 5.30.23.1230
Rich Text Edit Control, v3.0
[75310000] C:\WINDOWS\system32\msctfime.ime
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2105)
Microsoft Text Frame Work Service IME
[76360000] C:\WINDOWS\system32\IMM32.DLL
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2105)
Windows XP IMM32 API Client DLL
[76380000] C:\WINDOWS\system32\comdlg32.dll
6.0.2900.5512 - 6.00.2900.5512 (xpsp.080413-2105)
Библиотека общих диалоговых окон
[76BE0000] C:\WINDOWS\system32\PSAPI.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2105)
Process Status Helper
[77110000] C:\WINDOWS\system32\oleaut32.dll
5.1.2600.5512 - 5.1.2600.5512
[773C0000] C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dll
6.0.2900.5512 - 6.0 (xpsp.080413-2105)
User Experience Controls Library
[774D0000] C:\WINDOWS\system32\ole32.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2108)
Microsoft OLE для Windows
[77BF0000] C:\WINDOWS\system32\version.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2105)
Version Checking and File Installation Libraries
[77C00000] C:\WINDOWS\system32\msvcrt.dll
7.0.2600.5512 - 7.0.2600.5512 (xpsp.080413-2111)
Windows NT CRT DLL
[77DC0000] C:\WINDOWS\system32\ADVAPI32.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2113)
Расширенная библиотека API Windows 32
[77E70000] C:\WINDOWS\system32\RPCRT4.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2108)
Remote Procedure Call Runtime
[77F10000] C:\WINDOWS\system32\GDI32.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2105)
GDI Client DLL
[77F60000] C:\WINDOWS\system32\SHLWAPI.dll
6.0.2900.2995 - 6.00.2900.2995 (xpsp.060913-0019)
Библиотека небольших программ оболочки
[77FE0000] C:\WINDOWS\system32\Secur32.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2113)
Security Support Provider Interface
[7C800000] C:\WINDOWS\system32\kernel32.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2111)
Библиотека клиента Windows NT BASE API
[7C900000] C:\WINDOWS\system32\ntdll.dll
5.1.2600.5594 - 5.1.2600.5594 (xpsp_sp3_qfe.080503-1404)
Системная библиотека NT
[7C9C0000] C:\WINDOWS\system32\shell32.dll
6.0.2900.5512 - 6.00.2900.5512 (xpsp.080413-2105)
Общая библиотека оболочки Windows
[7E360000] C:\WINDOWS\system32\USER32.dll
5.1.2600.5512 - 5.1.2600.5512 (xpsp.080413-2105)
Библиотека клиента USER API Windows XP
------------------------------------------------------------------------------
Active Controls hierarchy:
TCheckListBox "clbPluginsList"
TGroupBox "GroupBox5"
TTabSheet "tsPluginsTab"
TPageControl "PageControl1"
TL2PacketHackMain "L2PacketHackMain"
------------------------------------------------------------------------------

а это лог из самого плагина:

26.01.2009 7:24:59 - Для выбора нужного соединения наберите в чате слово "set" и отправьте
26.01.2009 7:24:59 - Invalid pointer operation
26.01.2009 7:25:08 - Выбрано это соединение.
26.01.2009 7:25:08 - Invalid pointer operation

зы: мб поделитесь инфой кто компилил работающий плагин под какой дельфи и пхикс.

QaK
26.01.2009, 08:40
Я компилил под 2006 (с хкор"овского фтпшника) для ПНХ 80/81.

Добавлено через 46 секунд
Кинь исходник или сюда или в личку стукни - спишемся.

alexsl
26.01.2009, 09:10
кстати какие опции компиляции у тя стоят?
у муну в Д7:

-$A8
-$B-
-$C+
-$D+
-$E-
-$F-
-$G+
-$H+
-$I+
-$J-
-$K-
-$L+
-$M-
-$N+
-$O+
-$P+
-$Q-
-$R-
-$S-
-$T-
-$U-
-$V+
-$W-
-$X+
-$YD
-$Z1
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;Db iProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00400000
-E"C:\Temp\L2PHX34159\plugins"
-LE"c:\program files\borland\delphi7\Projects\Bpl"
-LN"c:\program files\borland\delphi7\Projects\Bpl"
-w-UNSAFE_TYPE
-w-UNSAFE_CODE
-w-UNSAFE_CAST

Grinch
26.01.2009, 10:21
Delphi 2007 c библиотеками которые нужны для компила пакетхака. на других обычно критует или длл или пакетхак. кароче хз в чем трабла :) а так работает и развивается потихоньку

Добавлено через 58 секунд
Зы брал у xkor'a c ftp

alexsl
26.01.2009, 20:25
ИМХО в общем с менеджером памяти FastMM какая то замарочка,
он идет начиная с Д2007.
вот может поможет, лог:


--------------------------------2009/1/26 14:38:36--------------------------------
FastMM has detected an error during a FreeMem operation. The block header has been corrupted.

The current thread ID is 0x7D4, and the stack trace (return addresses) leading to this error is:
C12993 [System][@FreeMem]
C64B39 [C:\Work\l2phx.3.4.1.81\Source\helper.dpr][helper][OnLoad][128]
55E338 [phxPlugins.pas][phxPlugins][phxPlugins.TPlugin.LoadPlugin][188]
572E99 [main.pas][main][main.TL2PacketHackMain.clbPluginsListClickCheck][3750]
46F9C7 [Controls.pas][Controls][Controls.TControl.DoMouseDown][5252]
46FA15 [Controls.pas][Controls][Controls.TControl.WMLButtonDown][5261]
4733E4 [Controls.pas][Controls][Controls.TWinControl.WndProc][7304]
44CB88 [StdCtrls.pas][StdCtrls][StdCtrls.TCustomListBox.WndProc][4790]
472B0B [Controls.pas][Controls][Controls.TWinControl.MainWndProc][7073]
42F91E [common\Classes.pas][Classes][Classes.StdWndProc][11583]
7E368734 [Unknown function at GetDC]

--------------------------------2009/1/26 14:39:05--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

5 - 12 bytes: AnsiString x 1

Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".


зы: поиграюсь с опциями FastMM, мб че получится

Добавлено через 4 часа 43 минуты
в общем разобрался,если юзать оригинальный файл FastMM4Options.inc и объявить дерективы ShareMM и AttemptToUseSharedMM в проекте то все работает норм. проверено Д7, думаю д2005 и 2006 норм должны компилится.
зы: юзал ФастММ 4.92 и 4.9

alexsl
29.01.2009, 07:39
кусок дллки для Д7, чтоб компилился нормально

library mylib;

{$define ShareMM}
{$define AttemptToUseSharedMM}

{$define RELEASE} // для совместимости с релизом пакетхака, при дебуге можно закоментировать

uses
FastMM4,
SysUtils,
Windows
.....


FastMM лежит тут http://fastmm.sourceforge.net
FastMM4Options.inc брал оригинальный

AD!
07.02.2009, 11:35
Начал попытки переписки скриптов в плагины, появились несколько вопросов
1.TReadDEx,TReadSEx и т.п при чтении не смещают index на количество прочтенных байт как в скрипте, так и должно быть?
2.как работает TDataPckToStrPck строка получается hex? или как?
и кто знает как отлаживать в в седьмой делфи, у меня никак не получилось(, аттачу ПХ и он отлаживать сразу начинает, даж плагин не включить!
p.s хорошо бы для образца каконибуть исходник плагина, или описание работы процедур и функций)

xkor
07.02.2009, 16:11
1.TReadDEx,TReadSEx и т.п при чтении не смещают index на количество прочтенных байт как в скрипте, так и должно быть?
угу, поскольку в качестве параметра может быть не только переменная но и просто число в плагине нельзя реализовать это как в скрипте.

2.как работает TDataPckToStrPck строка получается hex? или как?преобразует пакет из просто последовательности байт в памяти в строку, которая по сути та же последовательность байт, но с ней часто удобнее работать, hex тут не при чем...

и кто знает как отлаживать в в седьмой делфи, у меня никак не получилось(, аттачу ПХ и он отлаживать сразу начинает, даж плагин не включить!ну после атача просто нажимаешь F9, в пакетхаке подключаешь плагин и вуаля - можно останавливать бряки в плагине.
Только надо чтобы дельфя плагин компилила сразу в папку плагинов пакетхака, иначе она не поймет что тот плагин который ты включил тот же самый что ты отлаживаеш..

p.s хорошо бы для образца каконибуть исходник плагина, или описание работы процедур и функций)в SVN лежит два исходника плагинов - plugin_demo и plugin_demo2

AD!
11.02.2009, 09:57
Не мог разобраться с реализацией таймера плагине соорудил следующую конструкцию, вроде работает, но правильно ли? не будет затупов при долгой работе?:unknw:
также прописываются и другие события):cool:

......
type
aaa = class(TObject)
public
procedure CheckTime(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
end;

var
FormMain : TForm;
CheckTimer: TTimer;
Msg : TMemo;
...........
.............

function Create_FormMain : TForm;
...........
.......
Result := TForm.Create(nil);
TRY
.......
Result.OnClose := aaa.Create.FormClose;
........
end;


...........
............
//чтобы форма не закрывалась
procedure aaa.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caNone;
end;

//событие таймера
procedure aaa.CheckTime(Sender: TObject);
begin
msg.Lines.Add('test');
end;


procedure OnLoad; stdcall;
begin
FormMain:=Create_FormMain;
CheckTimer:=TTimer.Create(Application);
CheckTimer.OnTimer:=aaa.Create.CheckTime;
CheckTimer.interval:=2000; //время задержки
CheckTimer.enabled:=false;
end;

.........


а для чего в проекте используется FastMM4?

xenus
11.02.2009, 11:38
FastMM4 используеться для улутшения работы с памятью... восновном сказываеться на стабильность работы бинарника ;-)

xkor
11.02.2009, 14:42
а для чего в проекте используется FastMM4?
для того чтобы плагины и программа юзали один менаджер памяти, иначе нельзя бы было передавать стринги между плагином и программой и другие динамические массивы...

Ezhik
20.05.2009, 02:33
Драсте.
В гайде ФС:
Вы не можете объявить класс в скрипте, но вы можете использовать внешние классы, объявленные в вашем приложении или в дополнительных модулях.

Собстно вопрос: как из скрипта обратится к классу объявленному в ДЛЛ, или , что значит "можете использовать внешние классы"??

Добавлено через 53 минуты
или может так:
В длл есть возможность експортировать переменные, у меня эта переменная имеет тип класса объявленного в длл. Как из скрипта достучаться до этой переменной??

alexteam
20.05.2009, 12:10
никак. пх 2.5.х и ниже может експортировать из длл только процедуры/функции.

Grinch
20.05.2009, 12:38
пх 2.5.х и че за версия? может 3.5.х

alexteam
20.05.2009, 12:58
упс... опичаталси... :p

xkor
21.05.2009, 14:06
ну я бы ещё уточнил что из длл не только в пакетхаке нельзя классы экспортировать, как правило их вообще нельзя экспортировать из длл
исключения составляют только длл на .НЕТ (но их можно юзать только из программ на .НЕТ) и пакеты дельфи (но они собсно тоже не обычные длл а очень специфические)

из дллок экспортируют только интерфейсы (это что то типа расширения классов)

ЗЫ кстати в 3.6.х версиях пакетхака вроде можно создавать свои классы в скриптах

ЗЫ а вообще под внешними классами имелись в виду базовые классы встроенные в программу типа TForm, TButton...

Kennedy
24.07.2009, 23:48
Мучался-мучался с попытками создать хотя бы один плагин под последний зарелизеный пакетхак, но ничего у меня не получилось, то не к той памяти обратится, то вообще вылетит и ничего не скажет, а потом решил посмотреть на Changelog к последней версии, и обнаружил там следующую весчь:
в onpacket функцию плагинов теперь передается имя соединения (TOnPacket = procedure(const cnt: Cardinal; const fromServer: Boolean; const connectionname:string; var packet : tpacket); stdcall;)

И соответсвенно у меня просьба=) где можно узнать, или у кого, обо всех таких изменениях?) ну и как минимум последний uSharedStructs бы вытянуть

NLObP
24.07.2009, 23:51
Kennedy, на SVN (http://l2phx.pp.ru/wsvn/listing.php?repname=l2phx3&path=%2F&sc=1) посмотреть отличия версий.

Kennedy
24.07.2009, 23:52
Спасибо за столь быстрый ответ;)

Kennedy
25.07.2009, 04:04
Однако добиться исправной работы даже порезанного demo плагина у меня не получилось.Вот то что я сделал в итоге с исходником после нескольких часов его мучения:

library plugin_demo;
uses
FastMM4 in '..\fastmm\FastMM4.pas',
FastMM4Messages in '..\fastmm\FastMM4Messages.pas',
SysUtils,
Windows,
dialogs,
Classes,
usharedstructs in '..\units\usharedstructs.pas';
var {version} {revision}
min_ver_a: array[0..3] of Byte = ( 3,5,12, 120 );
min_ver: Integer absolute min_ver_a;
ps: TPluginStruct;
pps: PPluginStruct;
ppck: PPacket;
const
pause=15000;
var
ColvoHP, CharObjID, ItemObjHP: integer;
CurHP, MaxHP, lastHP, cntHP:integer;
TimerHP: Boolean;
StatusHP: Boolean;
function GetPluginInfo(const ver: Integer): PChar; stdcall;
begin
if ver<min_ver then
Result:='плаг'+sLineBreak+
'Для версий 3.5.12.120+'+sLineBreak+
'стар'
else
Result:='плаг'+sLineBreak+
'Для версий 3.5.12.120+'+sLineBreak+
'Автовыпивалка НР бутылок';
end;

procedure Say(msg:string); stdcall;
var
buf:String;
begin
ps.WriteC(buf,$4A);
ps.WriteD(buf,0);
ps.WriteD(buf,2);
ps.WriteS(buf,'AutoHP');
ps.WriteS(buf,msg + ps.getConnectionName(cntHP));
ps.WriteH(buf,0);
ps.SendPacketStr(buf,cntHP,False);
end;


function SetStruct(const struct: PPluginStruct): Boolean; stdcall;
begin
ps := TPluginStruct(struct^);
pps := struct;
Result:=True;
end;

procedure StatsUpdate;
var
i: integer;
begin
for i:=0 to ps.ReadDEx(ppck^,7)-1 do
case ppck^.data[i*8+8] of
$09: CurHP:=ps.ReadDEx(ppck^,i*8+15);
$0A: MaxHP:=ps.ReadDEx(ppck^,i*8+15);
end;
say('CurHP/MaxHP = '+inttostr(curhp)+'/'+inttostr(maxhp));
if (CurHP<=MaxHP-50) then TimerHP:=true else TimerHP:=false;
end;

procedure OnLoad; stdcall;
begin
statusHP:=false;
CharObjID:=0;
ItemObjHP:=0;
TimerHP:=false;
lastHP:=0;
cntHP := -1;
end;

procedure OnPacket(const cnt: Cardinal; const fromServer: Boolean; const connectionname:string; var pck: Tpacket); stdcall;
begin
if pck.size<3 then exit;

ppck:=@pck;

if not FromServer and(pck.pckId=$49)and(cntHP=-1)then
if(ps.ReadSEx(pck,3)='set')then begin
pck.pckSize:=0;
cntHP:=cnt;
Say('Выбрано это соединение.');
Say('Для...');
end;
end;

exports
GetPluginInfo,
OnPacket,
OnLoad,
SetStruct;

begin
end.


Плагин загружаю когда чара уже выбрали, дальше пишу set и в чат клиента пишется всего одна строчка "Выбрано это соединение" вместе с месседжем:
Application error. Exception EInvalidPointer in module plugin_demo.dll at xxx
Т.е. раз сообщение дошло то строчка в процедуре Say ps.SendPacketStr(buf,cntHP,False);
выполняется. И исключение срабатывает на выходе из этой процедуры.

Использую CodeGear Delphi 2007. Оригинальный плагин plugin_demo.pas из SVN.

alexteam
25.07.2009, 12:39
сломаны они, мне некогда переделывать взад. и остальным походу тоже.
юзаем рев 83.

Kennedy
25.07.2009, 13:19
Ммм... неужели с 83-й плагины не работали не разу?

В принципе есть желание заняться, только не все компоненты сторонние нашел для сборки пакетхака, если нетрудно сцыльте, перечислите или что-нить в этом роде)

NLObP
25.07.2009, 13:23
Ммм... неужели с 83-й плагины не работали не разу?

В принципе есть желание заняться, только не все компоненты сторонние нашел для сборки пакетхака, если нетрудно сцыльте, перечислите или что-нить в этом роде)

Загляни в эту тему (http://coderx.ru/showthread.php?t=618), там всё есть. Xkor'a спроси доступ на SVN для записи. Удачи.

QaK
25.07.2009, 18:16
Kennedy, c 83й версии алекстим что-то с TPluginstruct намудрил, нужно привести в исходное состояние.

AD!
11.08.2009, 17:13
Тоже наткнулся на EInvalidPointer при написании плагинов...
Вообщето проблема эта давно известная при создании обычной dll в делфях есть забавный заголовок который нужно читать, там в начале написано что стринг нежелательно использовать а надо либо пчар либо шортстринг.

но а например WriteD не хочет принимать shortstring совсем....

alexteam
11.08.2009, 18:55
про пчары наем. замесы со стрингом тянуцца бог знает с какой версии -)
в принципе стоило бы реализовать readx по аналогии с онным в скриптовом движке (тобиш передача офсета в этой функции онли, а не гоняние строки с офсетом туды-сюды)

и ваабще. не работают readx ? реализуйте их сами в плагине!
структура ведь с данными о пришедшем пакете передается и весьма успешно. читайте прям с нее своими функциями минуя багнутые функции "импортируемые" с пх
//Qak: ага, как ломать - так все бацаки, а как починить - так все чатлане

Xen
10.05.2010, 16:17
Не могу понять как средствами плагина отправить пакет серверу, т.е. чтобы плагин отправлял параметр в скрипт и скрипт отправлял на сервер, или (лучше) сам плагин отправлял пакет.

Можно самый простой, например "Hello World"?

J-Fobos
10.05.2010, 16:32
procedure SendPacket(Size: Word;pck: string; tid: Byte; ToServer: Boolean);
где
Size - размер пакета (размер pck +2)
pck - сам пакет
tid - номер соединения
ToServer - направление отсылки, True на сервер, False - на клиент

alexteam
10.05.2010, 16:45
через прослойку-скрипт чуть геморней.. но 100% работоспособно.
да и собирать/разбирать пакеты удобней.. во всяком случае плагин трогать не приходится.

Zergatul
18.08.2012, 17:38
Как правильно передавать параметр pck в
procedure SendPacketData(var pck; const tid: integer; const ToServer: Boolean); Virtual; Abstract;
Динамический массив? Если так, то почему тип не прописан статически

Добавлено через 2 часа 35 минут
Еще один вопрос:
пишу в коде
ps.SendPacketStr(#$46, cnt, true);
Типа RequestRestart для интерлюда, в итоге после выполнения этой строки происходит дисконект. Если отправлять через вкладку "Посылка", все работает корректно.

Версия: 3.5.34.176

alexteam
19.08.2012, 03:49
Динамический массив?
нет.

то почему тип не прописан
что значит "типо не прописан" ? он прописан. в явном виде.
var buf - указатель на данные.


пишу в коде

ты в качестве поинтера пытаешся какуюто хрень передать.
правильней так.

var
pck : TPacket;
begin
pck.size := 3;
pck.pckId := $46;
ps.SendPacketStr(pck, cnt, true);

Zergatul
20.08.2012, 14:47
var buf - указатель на данные.
Я предполагал, что это указатель на данные, но если это так, откуда процедура знает длину этих данных, если она просто смотрит на нее как на массив байт?

А под "не прописан тип" я имел ввиду, почему buf нетипизированый параметр

Добавлено через 2 минуты
ты в качестве поинтера пытаешся какуюто хрень передать.
правильней так.

var
pck : TPacket;
begin
pck.size := 3;
pck.pckId := $46;
ps.SendPacketStr(pck, cnt, true);
Эта функция требует первый параметр строку

Zergatul
20.08.2012, 23:17
procedure OnPacket(const cnt: Cardinal; const fromServer: Boolean; const connectionName: String; var pck: String); stdcall;
var
p: TPacket;
begin
if pck = #$1B#02#00#00#00 then
begin
p.pckSize := 3;
p.pckId := $46;
ps.SendPacketData(p, cnt, true);
Exit
end;
end;
Вот такой код, при выполнении вылетает. Лог на всякий случай прикрепил.
Может у меня старый юнит usharedstructs? Где можно взять самый новый?