Итак вот подробное описание того какой должна быть структура плагина:
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;