Как правильно форматировать и паковать строку (например для отправки сообщения в чат). С меня + P.S Нигде инфы нет
MorzE говорил, что нужно кодировать в UTF-16. делаю так: 代码: $name=iconv("UTF-8","UTF-16","test"); $msg=iconv("UTF-8","UTF-16","Hellow World"); $name=bin2hex($name); $msg=bin2hex($msg); $name=pack("H*",$name); $msg=pack("H*",$name); Получается примерно так же хекс-код , как у пакетов айвеба, только есть лишние байты(в начале слова), или немного другой хекс-код (также в начале слова).
повторюсь $name=unpack("H*",$name); - преобразование строки в хекс код И ещё, я уверен перед сообщением должна быть обязательно его длина.
Насчет длины +, действительно вроде так. Насчет unpack: функция вернет нам массив байтов, нужно будет в цикле складывать символы?
WorldChat 代码: <protocol debug="0" name="WorldChat" maxsize="256" prior="1" type="133"> <!-- link server to player --> <variable name="channel" type="byte"/> <variable name="emotion" type="byte"/> <variable name="roleid" type="int"/> <variable name="name" type="Octets" attr="ref"/> <variable name="msg" type="Octets" attr="ref"/> </protocol> для name и msg надо форматнуть в UTF-16 и запаковать, unpack просто переводит в хекс, но не запаковывает. делаю примерно так. 代码: $data=cuint(133)."\x2c".$channel.$emotion.$roleid.$name.$msg; // надо как-то упаковать строки
У тебя не только строки не запакованы, но и заголовок не верно сформирован. Как его сформировать, сразу скажу, не знаю. P.S. Паковать имя и сообщение не надо. Там обычный UTF-16
я говорил, что буду его разбирать потом (уже разобрал - это длина все параметров в байтах). Насчет строк: просто тупо конвертить строку в UTF-16 (с помощью iconv?)
Да. Ну и, конечно, длину строки перед ней ставить. P.S. броадкаст разобрал, в красный сообщения отправляет. Теперь надо ворлдчат разобрать.)
Почти все сделал, но есть один косяк: в начале строк (name,msg) идут 2 лишних байта (символ UTF-16) То ли это я туплю, толи не так пакую - хз: Вот правильный запрос (пойман сниффером): 代码: 80 85 28 01 00 00 00 00 22 08 74 00 65 00 73 00 74 00 18 48 00 65 00 6C 00 6C 00 6F 00 77 00 20 00 57 00 6F 00 72 00 6C 00 64 00 Вот мой запрос: 代码: 80 85 2C 01 00 00 00 00 22 0A FF FE 74 00 65 00 73 00 74 00 1A FF FE 48 00 65 00 6C 00 6C 00 6F 00 77 00 20 00 57 00 6F 00 72 00 6C 00 64 00 Вот мой php-код: 代码: <?php function cuint($data) { if($data < 64) return strrev(pack("C", $data)); else if($data < 16384) return strrev(pack("S", ($data | 0x8000))); else if($data < 536870912) return strrev(pack("I", ($data | 0xC0000000))); return strrev(pack("c", -32) . pack("I", $data)); } $fp=fopen("/root/root.txt","w"); $address='10.0.2.15'; $port=29100; $sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP); $bind=socket_connect($sock,$address,$port); $id=strrev(pack("I",34)); $channel=cuint(1); $emotion=cuint(0); $name=iconv("UTF-8","UTF-16","test"); $msg=iconv("UTF-8","UTF-16","Hellow World"); $length=8+strlen($name.$msg); $length=pack("C",$length); $data=cuint(133).$length.$channel.$emotion.$id.strrev(pack("C",strlen($name))).$name.strrev(pack("C",strlen($msg))).$msg; $zapr=socket_send($sock,$data,8192,0); $otv=socket_recv($sock,$buf,8192,0); echo $data; fwrite($fp,$data); socket_close($sock); fclose($fp); ?> Как видите, у меня лишние байты FF FE ---------------------------------- Решил проблему. Надо конвертить в UTF-16L. Оказывается я поймал не тот пакет, а ID пакета - 78(h) P.S Спасибо MorzE
У меня возникли еще вопросы: 1)Как узнать заголовок пакета, если такой пакет нельзя поймать сниффером и его нету в configs.xml 2) По какому принципу работает функция cuint (эта функция применима только для кодирования целых числе в пв или везде? И как гоуранга узнал алгоритм кодирования? Мне интересно это узнать) Заранее спасибо=)