На Delphi прогу писал? Вроде же есть модуль для считывания dds для него. Кстати формат текстового файла достаточно оригинален. И его соответствие матрице иконок.
Всем спасибо, все свободны :lol: Возможно скоро будет iWeb-php и для PerfectWorld :lol: Кстати, gouranga, не подскажешь как вытащить ВСЕ опкоды, например для общения с gdeliveryd или gamed в полном обьеме?
Некоторые данные урывки кода, позволяющие полностью разобрать работу протокола: Во первых, все протоколы унаследуются от Rpc, который унаследован от Protocol. А вот и код: Кодировка protected void Encode(OctetsStream paramOctetsStream) { paramOctetsStream.compact_uint32(this.type).marshal(new OctetsStream().marshal(this)); } public OctetsStream marshal(OctetsStream paramOctetsStream) { paramOctetsStream.marshal(this.xid); paramOctetsStream.marshal((this.xid.IsRequest()) ? this.argument : this.result); return paramOctetsStream; } private XID xid = new XID(null); private static class XID implements Marshal, Cloneable { public int count = 0; private boolean is_request = true; private static int xid_count = 0; private static Object xid_locker = new Object(); public OctetsStream marshal(OctetsStream paramOctetsStream) { return paramOctetsStream.marshal((this.is_request) ? this.count | 0x80000000 : this.count & 0x7FFFFFFF); } Еще две ОЧЕНЬ интересных функций из хида: public void ClrRequest() { this.is_request = false; } public void SetRequest() { this.is_request = true; synchronized (xid_locker) { this.count = (xid_count++); } } Как оказывается все чрезвычайно просто и очевидно. А после всего этого идет маршалинг параметров запроса. На счет декодирования все в обратном порядке. Протокол для декодинга берется айвебом по мапу, который наверно грузится с ХМЛя. :lol:
Спасибо за совет, сделал дамп и открыл WireSharkом. Это действительно хедеры. Linux cooked capture 0000 00 00 03 04 00 00 00 00 00 00 00 00 00 00 08 00 Internet Protocol, Src: 10.0.2.15 (10.0.2.15), Dst: 10.0.2.15 (10.0.2.15) 0000 45 00 00 3f a8 90 40 00 40 06 7a 0b 0a 00 02 0f 0010 0a 00 02 0f Transmission Control Protocol, Src Port: 48593 (48593), Dst Port: 29400 (29400), Seq: 1, Ack: 1, Len: 11 0000 bd d1 72 d8 06 d5 3d 57 07 1a b4 f4 80 18 0f 3a 0010 18 4f 00 00 01 01 08 0a 00 0c e7 a2 00 0b f7 e6 Data (11 bytes) 0000 8b c5 08 80 00 20 76 00 00 ab cd Интересно, что у всех пакетов неверный чексум :lol:
0000101111000101 -> 3013bc5? Скрипт кривой, скажу. Legend: Исходные данные, Дек, Хекс Вот только вопрос почему когда я конвектирую 8bc5 в опкод всё норм, конвектирую из хекс в бин а потом обратно и вместо 8bc5 получаю 357818bc5 ?! 357818bc5 может так? вот! вот это то что нужно. правда в твоем отрывке еще шапище огромная, непонятно зачем. 8bc5 0880 0020 3a00 00ab вот важная часть. Я тоже не пойму что за шапище. Случайно tcpdump не поймал все TCP заголовки пакета? :-D
Ну ладно при помощи RPM прикрутил tcpdump. Вот запрос / ответ на GetRoleBase для персонажа с id 0xABCD, может хоть кто то поймет что где. Запрос: 02:41:42.191907 IP (tos 0x0, ttl 64, id 43070, offset 0, flags [DF], proto: TCP (6), length: 63) aumanager.48593 > aumanager.29400: P, cksum 0x184f (incorrect (-> 0x060f), 114637507:114637518(11) ack 119188052 win 3898 <nop,nop,timestamp 181516 181360> 0x0000: 4500 003f a83e 4000 4006 7a5d 0a00 020f E..?.>@[email protected]].... 0x0010: 0a00 020f bdd1 72d8 06d5 3ac3 071a aa54 ......r...:....T 0x0020: 8018 0f3a 184f 0000 0101 080a 0002 c50c ...:.O.......... 0x0030: 0002 c470 8bc5 0880 0020 3a00 00ab cd ...p......:.... Ответ: 02:41:42.191907 IP (tos 0x0, ttl 64, id 59413, offset 0, flags [DF], proto: TCP (6), length: 111) aumanager.29400 > aumanager.48593: P, cksum 0x187f (incorrect (-> 0x729c), 1:60(59) ack 11 win 1024 <nop,nop,timestamp 181516 181516> 0x0000: 4500 006f e815 4000 4006 3a56 0a00 020f E..o..@.@.:V.... 0x0010: 0a00 020f 72d8 bdd1 071a aa54 06d5 3ace ....r......T..:. 0x0020: 8018 0400 187f 0000 0101 080a 0002 c50c ................ 0x0030: 0002 c50c 8bc5 3800 0020 3a00 0000 3c01 ......8...:...<. 0x0040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0x0050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0x0060: 0000 0000 0000 0000 0000 0000 0000 00 ...............
Я сейчас его кстати и делаю :-) И не только NPCGen. Вот моя крайне оптимизированая процедура тягания координат: var __GETCOORDS_CX: PSingle = nil; __GETCOORDS_CY: PSingle = nil; __GETCOORDS_CZ: PSingle = nil; __GETCOORDS_BUF: PDWord = nil; __GETCOORDS_PROC: DWord = 0; __GETCOORDS_BASE: DWord = 0; __GETCOORDS_ADR: DWord = 0; function GetCoords(Base: DWord; out X: Single; out Y: Single; out Z: Single): Word; var B: DWord; hProcess, HandleWindow: THandle; ProcessID, temp: Cardinal; adr: DWord; begin B:=Base; if (Base=0) then B:=$00925484; //Assuming 1.3.4 if (Base=134) then B:=$00925484; //1.3.4 if (Base=140) then B:=$0095baa4; //1.4.0 if (Base=141) then B:=$009771bc; //1.4.1 Result:=65535; X:=0; Y:=0; Z:=0; HandleWindow :=FindWindow(nil,'Element Client'); if (HandleWindow=0) then Exit; GetWindowThreadProcessId(HandleWindow,@ProcessID); if (ProcessId=0) then Exit; Result:=0; adr:=0; if ((__GETCOORDS_PROC<>ProcessID) or (__GETCOORDS_BASE<>B)) or (__GETCOORDS_ADR=0) then begin hProcess := OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID); if (__GETCOORDS_BUF=nil) then getmem(__GETCOORDS_BUF,4); if (__GETCOORDS_CX=nil) then getmem(__GETCOORDS_CX,4); if (__GETCOORDS_CY=nil) then getmem(__GETCOORDS_CY,4); if (__GETCOORDS_CZ=nil) then getmem(__GETCOORDS_CZ,4); if (hProcess>0) then begin __GETCOORDS_BASE:=B; __GETCOORDS_PROC:=ProcessID; adr:=B; readprocessmemory(hProcess,ptr(adr),__GETCOORDS_BUF,4,temp); if (temp<4) then Result:=Result+temp*10000; adr:=__GETCOORDS_BUF^; readprocessmemory(hProcess,ptr(adr+$20),__GETCOORDS_BUF,4,temp); if (temp<4) then Result:=Result+temp*1000; adr:=__GETCOORDS_BUF^; __GETCOORDS_ADR:=adr; end; end else begin hProcess := OpenProcess(PROCESS_ALL_ACCESS,FALSE,__GETCOORDS_PROC); adr:=__GETCOORDS_ADR; end; if (hProcess>0) then begin readprocessmemory(hProcess,ptr(adr+$5FC),__GETCOORDS_CX,4,temp); if (temp<4) then Result:=Result+temp*100; readprocessmemory(hProcess,ptr(adr+$600),__GETCOORDS_CY,4,temp); if (temp<4) then Result:=Result+temp*10; readprocessmemory(hProcess,ptr(adr+$604),__GETCOORDS_CZ,4,temp); if (temp<4) then Result:=Result+temp*1; X:=__GETCOORDS_CX^; Y:=__GETCOORDS_CY^; Z:=__GETCOORDS_CZ^; end else begin X:=0; Y:=0; Z:=0; end; if hProcess <> 0 then CloseHandle(hProcess); end; Правда хендли не оптимизировал. Да и ладно.
Я имел ввиду в дефолтовом дистрибутиве PW. Кстати, при помощи чего компилить gcc? :lol:
Сначала берем Pointer по адресу BaseAddress. Потом к адресу на который он указывает прибавляем 32 и снова считываем указатель. К результирующему указателю нужно добавить N байт и считать Single для получения координаты. if (Base=134) then B:=$00925484; //1.3.4 if (Base=140) then B:=$0095baa4; //1.4.0 if (Base=141) then B:=$009771bc; //1.4.1 readprocessmemory(hProcess,ptr(adr+$5FC),__GETCOORDS_CX,4,temp); readprocessmemory(hProcess,ptr(adr+$600),__GETCOORDS_CY,4,temp); readprocessmemory(hProcess,ptr(adr+$604),__GETCOORDS_CZ,4,temp);
Ну извините, про линуксковские снифферки не слыхал. Кстати в колине нет ни gcc ни tcpdump.
Имена участников (разделяйте запятой).