- Рег
- 3 Дек 2015
- Сообщения
- 174
- Реакции
- 0
Видел, много раз поднималась тема о получении инфы, которую адреналин не дает (в частности разбор системных сообщений), выкладываю для тех, кто пишет что то немного посложнее возврата на спот.
Описание типов:
TL2PacketValueType = (
lpvNone,
lpvString,
lpvByte,
lpvWord,
lpvDWord,
lpvInteger,
lpvDouble,
lpvInt64,
lpvList
);
TL2PacketValue = record
public
name: string;
valueType: TL2PacketValueType;
hexValue: string;
stringValue: string;
byteValue: byte;
wordValue: word;
integerValue: integer;
doubleValue: double;
int64Value: int64;
listValue: array of TL2Packetvalue;
end;
TL2Packet = record
public
name: string;
contents: array of TL2PacketValue;
//structPath - путь к ini файлу с описанием протокола. в аттаче лежат под хроники c6-god из последнего phx.
procedure fetchFromMemory(const structPath: string; id, id2: cardinal; data: pointer; size: word; isClentPacket: boolean = false);
function valueWithName(const name: string; desiredType: TL2PacketValueType = lpvNone): TL2PacketValue;
end;
Как с этим работать?
Во первых, нужна точная структура пакета, который вы хотите разобрать.
Многие сервера используют нестандартный протокол, который знают только админы :lol:
Поэтому, очень часто, структуру придется восстанавливать самостоятельно.
Небольшой пример, вывода всей инфы о пакете:
uses SysUtils, PacketHelper;
procedure OnPacket(ID, ID2: Cardinal; Data: Pointer; Size: Word);
var
charName : String;
character: TL2Live;
i, j: cardinal;
packet: TL2Packet;
begin
case intToHex(id, 2) of
'62' :
begin
packet.fetchFromMemory(script.path + 'PacketsHighFive.ini', id, id2, data, size);
print('======');
print('@' + packet.name);
for i:= 0 to high(packet.contents) do
begin
if packet.contents.valueType = lpvList then
begin
for j:= 0 to high(packet.contents.listValue) do
begin
print(format('%s[%d] : %s', [packet.contents.listValue[j].name, j, packet.contents.listValue[j].stringValue]));
end;
end
else
begin
print(format('%s : %s', [packet.contents.name, packet.contents.stringValue]));
end;
end;
end;
end;
end;
begin
delay(-1);
end.
Вывод:
Теперь, разбор на примере вывода каунта пикапнутой адены:
вывод всего пакета:
uses SysUtils, PacketHelper;
procedure OnPacket(ID, ID2: Cardinal; Data: Pointer; Size: Word);
var
charName : String;
character: TL2Live;
i, j, amnt: cardinal;
packet: TL2Packet;
begin
case intToHex(id, 2) of
'62' :
begin
packet.fetchFromMemory(script.path + 'PacketsHighFive.ini', id, id2, data, size);
//получаем id сообщения
if packet.valueWithName('MsgID:Get.MsgID').integerValue = 28 then
begin
//тип 6 - amnt, скорее всего 4 байта без знака
//
amnt:= pcardinal(pchar(packet.valueWithName('data').listValue[0].stringValue))^;
print(amnt);
end;
end;
end;
end;
begin
delay(-1);
end.
Вывод:
Описание типов:
TL2PacketValueType = (
lpvNone,
lpvString,
lpvByte,
lpvWord,
lpvDWord,
lpvInteger,
lpvDouble,
lpvInt64,
lpvList
);
TL2PacketValue = record
public
name: string;
valueType: TL2PacketValueType;
hexValue: string;
stringValue: string;
byteValue: byte;
wordValue: word;
integerValue: integer;
doubleValue: double;
int64Value: int64;
listValue: array of TL2Packetvalue;
end;
TL2Packet = record
public
name: string;
contents: array of TL2PacketValue;
//structPath - путь к ini файлу с описанием протокола. в аттаче лежат под хроники c6-god из последнего phx.
procedure fetchFromMemory(const structPath: string; id, id2: cardinal; data: pointer; size: word; isClentPacket: boolean = false);
function valueWithName(const name: string; desiredType: TL2PacketValueType = lpvNone): TL2PacketValue;
end;
Как с этим работать?
Во первых, нужна точная структура пакета, который вы хотите разобрать.
Многие сервера используют нестандартный протокол, который знают только админы :lol:
Поэтому, очень часто, структуру придется восстанавливать самостоятельно.
Небольшой пример, вывода всей инфы о пакете:
uses SysUtils, PacketHelper;
procedure OnPacket(ID, ID2: Cardinal; Data: Pointer; Size: Word);
var
charName : String;
character: TL2Live;
i, j: cardinal;
packet: TL2Packet;
begin
case intToHex(id, 2) of
'62' :
begin
packet.fetchFromMemory(script.path + 'PacketsHighFive.ini', id, id2, data, size);
print('======');
print('@' + packet.name);
for i:= 0 to high(packet.contents) do
begin
if packet.contents.valueType = lpvList then
begin
for j:= 0 to high(packet.contents.listValue) do
begin
print(format('%s[%d] : %s', [packet.contents.listValue[j].name, j, packet.contents.listValue[j].stringValue]));
end;
end
else
begin
print(format('%s : %s', [packet.contents.name, packet.contents.stringValue]));
end;
end;
end;
end;
end;
begin
delay(-1);
end.
Вывод:
Теперь, разбор на примере вывода каунта пикапнутой адены:
вывод всего пакета:
uses SysUtils, PacketHelper;
procedure OnPacket(ID, ID2: Cardinal; Data: Pointer; Size: Word);
var
charName : String;
character: TL2Live;
i, j, amnt: cardinal;
packet: TL2Packet;
begin
case intToHex(id, 2) of
'62' :
begin
packet.fetchFromMemory(script.path + 'PacketsHighFive.ini', id, id2, data, size);
//получаем id сообщения
if packet.valueWithName('MsgID:Get.MsgID').integerValue = 28 then
begin
//тип 6 - amnt, скорее всего 4 байта без знака
//
amnt:= pcardinal(pchar(packet.valueWithName('data').listValue[0].stringValue))^;
print(amnt);
end;
end;
end;
end;
begin
delay(-1);
end.
Вывод: