Просмотр полной версии : разбор пакетов
Elecktron
10.12.2011, 21:52
кто как реализует разбор пакетов?
мне пока что в голову ничего лучше не приходит (кусок исходника джава сервера):
switch (opcode)
{
case 0x00:
msg = new Logout();
break;
case 0x0c:
msg = new CharacterCreate();
break;
case 0x0d:
msg = new CharacterDelete();
break;
case 0x12:
msg = new CharacterSelect();
break;
case 0x13:
msg = new NewCharacter();
break;
}
alexteam
11.12.2011, 04:07
ну разве что чтото вроде
type
TParserFunc = procedure .....
var
OpcodesFuncs : array[0..$ff] of TParserFunc;
гдето:
OpcodesFuncs[0] := @Parse_Die;
........
OpcodesFuncs[$DA] := @Parse_exPackets;
........
гдето вместо кейса:
OpcodesFuncs[packet.opcode]();
не си но идея понятна.
Elecktron
10.01.2012, 12:00
с разбором пакетов по ID разобрался.
а как разбить пакет на составляющие? (dword, char, string)
особенно неясно как быть с "секциями" с переменной длиной... (имя, титул персонажа)
supernewbie
10.01.2012, 16:38
Elecktron, формат надо знать, насчёт имён и титулов - это PWideChar так что в конце 00 00
есть там ещё циклы с блоками, дык там тоже всё просто - кол-во итераций пишется где-нить перед самими блоками
Elecktron
10.01.2012, 22:26
спасибо за ответ.
то что ник и титул widechar я вкурсе.
формат пакетов есть.
в лог я записываю вот так:
for (int i=0;i<packet->size;i++)
{
wsprintfA(buf, "%x",packet->data[i]);
stf(buf);
stf(" ");
}
но это весь пакет...
а мне нужно распределять по переменным, с которыми я буду уже работать.
пакет это массив, а переменные не массивы, и как это совместить я немогу понять...
supernewbie
10.01.2012, 22:32
ну как епт, перемещением памяти в переменные
в делфи это делается процедурой Move, в C++ вроде memcopy
Elecktron
11.01.2012, 01:43
memcpy() копирует массив в массив.
а мне нужно кусок массива в DWORD например..
или кусок массива в widestring, причем с четким определением его длины, чтобы потом было понятно с какого места продолжать чтение пакета.
потому что длина отводимая под ник/титул изменяется в пакете в зависимости от количества символов в нике/титуле...
ник/титул добивается нулями до длины 16/32 байта.
alexteam
11.01.2012, 03:04
memcpy() копирует массив в массив.
колво байтиков которые нужно скопировать указать нельзя чтоле ? да и не масив в масив, а кусок данных.
а мне нужно кусок массива в DWORD например..
и ? 4 байтика скопировать ? в чем трабл ?
или кусок массива в widestring
перебираем массив парами (word)
пока не наткнемся на 0. считаем колво.
алокейтим строку, копируем байтики.
ник/титул добивается нулями до длины 16/32 байта.
пох на длину вайдстринга в пакете.
тебе нужна пара нулей. (выше писали)
supernewbie
11.01.2012, 03:29
перебираем массив парами (word)
пока не наткнемся на 0. считаем колво.
алокейтим строку, копируем байтики.
кстати додумался как круче делать - string(pchar(@pck[байт с которого идёт строка]));
кто-нить видит подводные камни?
Elecktron
11.01.2012, 03:29
колво байтиков которые нужно скопировать указать нельзя чтоле ? да и не масив в масив, а кусок данных.
про количество я вкурсе. я не понял как вытащить кусок не сначала, например с пятого по восьмой..
перебираем массив парами (word)
пока не наткнемся на 0. считаем колво.
алокейтим строку, копируем байтики.
ок. попробую..
кстати додумался как круче делать - string(pchar(@pck[байт с которого идёт строка]));
кто-нить видит подводные камни?
widestring(pwidechar(@pck[байт с которого идёт строка]));
или
string(PWideToString(pwidechar(@pck[байт с которого идёт строка])));
хотя я делал так
widestring(pwidechar(Pointer(DWORD(ppck)+[байт с которого идёт строка]))));
string(PWideToString(pwidechar(Pointer(DWORD(ppck) +[байт с которого идёт строка]))));
где ppck это адрес пакета
function PWideToString(pw: PWideChar): string;
var
p: PChar;
iLen: integer;
begin
iLen := lstrlenw(pw) + 1;
GetMem(p, iLen);
WideCharToMultiByte(CP_ACP, 0, pw, iLen, p, iLen * 2, nil, nil);
Result := p;
FreeMem(p, iLen);
end;
supernewbie
11.01.2012, 04:42
дык щас же string=widestring и pchar=pwidechar
supernewbie, ну а это смотря а какой делфе говорить, я на 7й доси
supernewbie
11.01.2012, 04:46
Morfik, фуууу, срочно перебегай на xe2, там всякие чёткие списочки добавились, типо TList'а, который умеет хранить любой тип, и такая же хэш таблица
ах да, самое главное та, можно аллочить 8 гб памяти!!111рас
alexteam
11.01.2012, 04:51
фуууу
сам такой.
типо TList'а, который умеет хранить любой тип
он поинтеры хранить всегда умел.
можно аллочить 8 гб памяти
эт только тебе надо.
supernewbie
11.01.2012, 04:52
alexteam, а хеш таблица?
TЧетоТам<string,integer> - ахрененно же
кстати додумался как круче делать - string(pchar(@pck[байт с которого идёт строка]));
кто-нить видит подводные камни?
да. для делфи7 это будит тока первый символ ибо пчар это пансичар.
Elecktron
11.01.2012, 13:49
у меня почему-то работает только такая конструкция:
char buf[1024];
for (int i=0;i<packet->size;i++)
{
wsprintfA(buf, "%x",packet->data[i]);
stf(buf); //сохраняем в лог файл
stf(" "); // пробел :)
}
а хотелось бы как-то так:
charid[i]=packet->data[i];
где я косячу?
Elecktron, кури работу с указателями и преобразования типов
если память не изменяет по операторам С++, то будет как то так:
charid=*(int *)&(packet->data[i]);
Elecktron
12.01.2012, 05:44
спасибо помогло...
правда теперь другая проблема - вылетает в вечный цикл..
for (int i=0;i<packet->size;i++)
{
buf[i]=*(char *)&(packet->data[i]);
}
Ну так посмотри какое значение в packet->size и какое значение принимает i. Кроме того не вижу смысла преобразовывать байт в чар. Если нужно копировать в ворд (2байта) либо в дворд (4байта), то можно еще так -
memcpy(&d, buf+i, sizeof(int));
или так -
d = *(int*)(buf+i);
n1ghtmare
12.01.2012, 23:52
спасибо помогло...
правда теперь другая проблема - вылетает в вечный цикл..
for (int i=0;i<packet->size;i++)
{
buf[i]=*(char *)&(packet->data[i]);
}
Проверь свой size и что за бред это: *(char *)&(packet->data[i])
Не проще написать просто packet->data[i]
Edit: да и вообще ты копируеш кусок памяти по сути, нужно memcpy юзать здесь, это и быстрее и правильнее.
Elecktron
15.01.2012, 00:27
разобрался и заюзал это:
memcpy(&d, buf+i, sizeof(int));
vBulletin® v3.6.11, Copyright ©2000-2024, Jelsoft Enterprises Ltd. Перевод: zCarot