1. 游客, мы просим Вас ознакомиться с Правилами Форума и Отказом от ответственности!

[поиск, вопрос] Замена iweb

本贴由 Botchal2010-06-24 发布. 版块名称: PW Web

  1. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    Начну издалека. Я уже давно хотел сделать что-то, что заменялобы iweb ненасущий. Лично мне не нравится iweb впринципе изза наличие в нём багов и дыр. Так вот пока я ломал голову про то как читать файлы чаров которые в gamedbd гоуранга с полной увереностью сказал что всё просто! но готового решения у него нету и ещё чтото там...

    короче вот мини гайд от гоуранги

    Значит что меня интересует:

    1)
    жалко не сказал как, единственное что интересует так это авторизация
  2. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    где эти конфиги?
  3. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    И всёже что с авторизацией?
  4. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    особенно про 
  5. gouranga Эксперт Программист Пользователи Open Source Contributor White List

    帖子:
    67
    支持:
    142
    性别:
    Репутация:
    0
    Страна:
    Netherlands Netherlands
    Botchal, зачем читать файлы чаров? Там старый-старый Berkley Db (версии 4.2 кажется, когда только появилась поддержка java), заморишься переделывать новые коннекторы.

    Iweb не работает с данными таким образом. Он соединяется с сервером Gamedbd и прочими серверами, и обменивается с ними данными.
    Данные шифруются с помощью RC4, и я подозреваю, что еще есть авторизация используя isec/iseckey (input) и osec/oseckey (output), как у клиента с сервером, посредством HMAC_MD5.

    Т.е. шифрование происходит в обе стороны: от iweb к gamedbd через isec*, от gamedbd к iweb через osec*. Я в этом не уверен, но это было бы логично, и лично я бы так и сделал.

    alexdnepro, там не так много, главное, правильно маршалить все. самое сложное — обработать compact_int. На шарпе примерно такой Extension:
    代码:
            public uint ReadCUInt(this System.IO.BinaryReader reader)
    {
    if (reader.BaseStream.Position == reader.BaseStream.Length)
    throw new IOException();
    
    long bytesLeft = reader.BaseStream.Length - reader.BaseStream.Position;
    byte firstByte = reader.ReadByte();
    if (firstByte < 0x80)
    {
    return (uint)firstByte & 0x7F;
    }
    else if (firstByte < 0xC0)
    {
    if (bytesLeft < 2)
    throw new IOException();
    
    reader.BaseStream.Position--;
    
    return (uint)reader.ReadUInt16() & 0x3FFF;
    }
    else if (firstByte < 0xE0)
    {
    if (bytesLeft < 4)
    throw new IOException();
    
    reader.BaseStream.Position--;
    
    return reader.ReadUInt32() & 0x1FFFFFFF;
    }
    else
    {
    if (bytesLeft < 5)
    throw new IOException();
    
    return reader.ReadUInt32();
    }
    }
    P.S. это, кстати, потенциальная дырка, если какие-то нубы держат сокеты серверов не на 127.0.0.1 — их можно запросто уложить флудом, а они увидят только BUFFER_OVERFLOW.
    P.P.S. чтобы понять как и что: открываем(google.ru < jd-gui) iweb, и смотрим как происходит обмен всем этим. =)

    upd. конкретно я наврал. =)
    Итак, важные параметры:
    ibuffermax — размер входного буфера
    obuffermax — размер выходного буфера
    isec — номер входного алгоритма шифрования
    iseckey — параметр входного алгоритма
    osec — номер выходного алгоритма шифрования
    oseckey — параметр выходного алгоритма

    По-умолчанию, isec и osec равны 0.

    Доступные алгоритмы шифрования (isec/osec должен быть равным или параметру type или name):
    代码:
    	<security>
    <entity class="com.goldhuman.Common.Security.NullSecurity" name="NullSecurity" type="0"/>
    <entity class="com.goldhuman.Common.Security.Random" name="Random" type="1"/>
    <entity class="com.goldhuman.Common.Security.ARCFourSecurity" name="ARCFourSecurity" type="2"/>
    <entity class="com.goldhuman.Common.Security.MD5Hash" name="MD5Hash" type="3"/>
    <entity class="com.goldhuman.Common.Security.HMAC_MD5Hash" name="HMAC_MD5Hash" type="4"/>
    </security>
    Из всех вышеперечисленных серверов
    代码:
    // 127.0.0.1:29100 - Deliveryd
    // 127.0.0.1:29400 - GameDbd
    // 127.0.0.1:29500 - Factiond
    // 127.0.0.1:29401 - UniqueNamed
    
    стоит выделить только UniqueNamed — у него есть шифрование по алгоритму RC4 (isec и osec = 2). Остальные должны отдавать данные просто так, главное правильно реализовать протокол.
    Чтобы таки что-то сделать, смотрим конфиг айвеба и реализовываем нужные классы и поток байт (октетов), функция которую я написал вверху нужна все-равно. =)

    P.P.P.S. таки получается, что задать шифрование можно любому под-серверу ПВ.
    已获得JonMagon, int 3, gamer777另外5人的支持.
  6. gouranga Эксперт Программист Пользователи Open Source Contributor White List

    帖子:
    67
    支持:
    142
    性别:
    Репутация:
    0
    Страна:
    Netherlands Netherlands
    а смысл стоить такую городину, если тебе, например, нужен топ игроков или персонажи онлайн? гемора на самом деле не так-то и много, хуже того, весь протокол между айвебом и геймбд — описан в config.xml айвеба.
    1 человеку нравится это.
  7. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    во! полный ответ, благодарю, я хочу сделать онлайн карту и юзербары, вот как гвоздь в жопе не поверите, привлекает всё до чего я не могу добраться))
  8. gouranga Эксперт Программист Пользователи Open Source Contributor White List

    帖子:
    67
    支持:
    142
    性别:
    Репутация:
    0
    Страна:
    Netherlands Netherlands
    Botchal, юзербары более-менее реалистично. карты — сложнореализуемо.
    дело в том, что информация о персонажах хранится не в sql базе. тебе придется проявить значительные усилия, для кеширования и управления базой.
    но в целом, алгоритм и для карты и для списка персов онлайн на поверхности:
    1) взять userid из базы authd, которые онлайн (таблица point, кажется)
    2) запросить для каждой учетки список персов и взять только тех что онлайн.
    3) нарисовать)

    alexdnepro, да не нужно все переписывать. Только маршалинг и все. Остальное по мере надобности.
    已获得2人支持.
  9. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0

    Просто смотрел в iweb и увидел там координаты! а делать буду по аналогии с pomm wow http://wow.lanexpress.ru/useful/maps/pomm.php вот как пример, это отличная вещь)

    Кстати если просто без авторизации сласть всякую хрень на порт 29400, база падает. хз почему

    И всётаки недокуриваю про обмен ключами и авторизацию, в моём понимании авторизация через сокет на php это бэсик авторизация, но в этом процессе никогда не было никаких ключей))

    Буду смотреть iweb, gouranga, не подскажешь в каком файле в iweb непосредственно обмен ключами идёт? Просто то что лежит в config.xml это данные для отправки, правильно? Но перед отправкой сначало надо как ты сам сказал авторизироваться(обменяться ключами)

    Ну в gamedbd как я понял, не там чтоли? Какие ещё усилия по кэширования?
  10. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    Помойму нельзя с одного акаунта за двух чаров играть(ну во всяком случаи так в вове)

    поэтому просто берём id онлайн аккаунтов из базы point отправляем их куда и как надо) и получаем координаты чаров
  11. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    Так это те ключи?

    代码:
    isec			=	2
    iseckey			=	hgzmbmeyrQaivu2pTikcp1svqcueef
    osec			=	2
    oseckey			=	7mlyiidbm0kntvhRgjhjzdczDtbhnh

    вроде оно
  12. gouranga Эксперт Программист Пользователи Open Source Contributor White List

    帖子:
    67
    支持:
    142
    性别:
    Репутация:
    0
    Страна:
    Netherlands Netherlands
    Опять же, я же написал, что ошибся. авторизации по-умолчанию требует только uniquenamed. Для остальных рекомендую, кстати, поставить. Поэтому просто соединяешься и начинаешь слать данные.
    например, начни с
    代码:
    <rpc debug="0" name="GetUser" type="3002" argument="UserID" result="UserRes" table="user" attr="get" retcode="retcode" value="value" maxsize="4096" prior="1" timeout="30"/>
    отправляешь type|length|userid, где length в данном случае 4.


    нельзя, суть моего алгоритма ты видимо не понял, перечитай еще раз, это вкопирку что ты написал)

    Да, только видимо gamedbd они не нужны.
    已获得2人支持.
  13. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0

    Вот делаю как обычно подключение через сокет:

    代码:
    <?
    
    $address = "127.0.0.1";
    $port = "29400";
    $socket = fsockopen($address, $port, $errno, $errstr, 30);//Открываем сокет
    if($socket==TRUE){echo"Конект есть
    ";}//Если есть соеденение то сказать что есть
    if(!$socket)die("$errstr($errno)");//Вывести что не так в случаи провала
    $data = "type=3002&length=4&userid=32";// Что отправляем, вот это самый главный вопрос
    fwrite($socket, $data);//Отправляем
    $answer = fgets($socket, 4096);//Ответ
    echo $answer;//Вывести ответ
    if($answer==""){echo"Ответа нету";}
    fclose($socket);//Закрыть сокет
    
    
    ?>
    
    
    Открыли,отправили,приняли ответ, НО при отправки данны(например POST запрос) я обычно сначала слал тип отправляемых данных, например

    代码:
    fwrite($socket,"Content-type: application/x-www-form-urlencoded\r\n");
    а потом уже

    代码:
    
    $data = "login=botchal&pass=111111&repass=111111";
    
    fwrite($socket, $data);
    
    
    И сервер как и положено думал что это POST запросы)

    В нашем случаи надо както озаглавливать данные?

    И ещё:

    В <rpc> есть только type но нету length и userid или подразумевается что userid это аргумент а его значение это value  

    но тогда где length  и откуда вообще взять эту длинну?

    Что вернёт мой примерчик я к сожалению сейчас сказать не могу так как один умный человек копает что-то там типа тасков и чаров на сервере нету так как сделал вайп(хз зачем)

    Скажи gouranga, как интерпритировать моему мозгу твою строку <rpc> ?)
    Что означают другие параметры?

    Это ведь XML, мне нужно озаглавливать типа

    $data ="Content-Type: text/xml\n";
    $data ="Content-Disposition: form-data; name=\"xmlmsg\"";
    $data ="\n\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

    ?
  14. gouranga Эксперт Программист Пользователи Open Source Contributor White List

    帖子:
    67
    支持:
    142
    性别:
    Репутация:
    0
    Страна:
    Netherlands Netherlands
    бог мой, а почему ты считаешь, что там http-сервер и ему надо слать заголовки?
    и опять же, логин-пароль не нужны. даже если бы и было что-то, то ключ для RC4, но его нет, просто открывай поток и начинай отправлять.

    length — длина отправляемых данных в байтах. почти наверняка нужна. по крайней мере в эмуле у нас нужна.

    代码:
    <?php
    
    function cuint($data)
    {
    if($data < 64)
    return pack("C", $data);
    else if($data < 16384)
    return pack("S", ($data | 0x8000));
    else if($data < 536870912)
    return pack("I", ($data | 0xC0000000));
    return pack("c", -32) . pack("I", $data);
    }
    
    $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); // http://ru.php.net/manual/en/function.socket-create.php
    if(!$sock)
    die(socket_strerror(socket_last_error()));
    
    // 127.0.0.1:29100 - Deliveryd
    // 127.0.0.1:29400 - GameDbd
    // 127.0.0.1:29401 - UniqueNamed
    // 127.0.0.1:29500 - Factiond
    if(socket_connect($sock, "127.0.0.1", "29400")) // думаю через него, http://ru.php.net/manual/en/function.socket-connect.php
    {
    socket_set_block($sock); // блокируем скрипт, пока данные не будут отправлены-получены.
    
    echo 'rpc debug="0" name="GetUser" type="3002" argument="UserID" result="UserRes" table="user" attr="get" retcode="retcode" value="value" maxsize="4096" prior="1" timeout="30"<br>';
    
    $data = cuint(3002) . pack("V*", 4, 32);        // пакет отправляемый серверу. хз как его слать досканально, но полагаю, что не так.
    // вероятнее всего, опкод (3002), длина пакета (4 или 8), int userId
    
    if (false !== ($sbytes = socket_send($sock, $data, 8192, 0))) {
    echo "Send $sbytes bytes from socket_send(). <br>";
    } else {
    echo "socket_send() failed; reason: " . socket_strerror(socket_last_error($socket)) . "\n";
    }
    
    if (false !== ($rbytes = socket_recv($sock, $buf, 8192, 0))) {
    echo "Read $rbytes bytes from socket_recv(). Closing socket...";
    } else {
    echo "socket_recv() failed; reason: " . socket_strerror(socket_last_error($socket)) . "\n";
    }
    
    socket_set_nonblock($sock);
    socket_close($sock);
    }
    else
    {
    die(socket_strerror(socket_last_error()));
    }
    на это gamedbd ругнулся мне, что у меня «неверный протокол» и отписал, что получил. ну, видимо процесс идет в примерно таком образе. осталось только понять как правильно кидать данные.
    я бы немного изменил jio.jar и сделал бы там принт отправляемых данных в файл.

    代码:
    	<rpcdata name="UserID">
    <variable name="id" type="int" default="0"/>
    </rpcdata>
    <rpcdata name="StockLog" attr="vector">
    <variable name="tid" type="int" default="0"/>
    <variable name="time" type="int" default="0"/>
    <variable name="result" type="short" default="0"/>
    <variable name="volume" type="short" default="0"/>
    <variable name="cost" type="int" default="0"/>
    </rpcdata>
    <rpcdata name="User">
    <variable name="userid" type="int" default="0"/>
    <variable name="rolelist" type="int" default="0"/>
    <variable name="cash" type="int" default="0"/>
    <variable name="money" type="int" default="0"/>
    <variable name="cash_add" type="int" default="0"/>
    <variable name="cash_buy" type="int" default="0"/>
    <variable name="cash_sell" type="int" default="0"/>
    <variable name="cash_used" type="int" default="0"/>
    <variable name="add_serial" type="int" default="0"/>
    <variable name="use_serial" type="int" default="0"/>
    <variable name="exg_log" type="StockLogVector" default="StockLogVector()"/>
    <variable name="addiction" type="Octets" attr="ref"/>
    <variable name="reserved0" type="byte" default="0"/>
    <variable name="reserved1" type="short" default="0"/>
    <variable name="reserved2" type="int" default="0"/>
    <variable name="reserved3" type="int" default="0"/>
    <variable name="reserved4" type="int" default="0"/>
    </rpcdata>
    <rpcdata name="UserRes">
    <variable name="retcode" type="int" default="-1"/>
    <variable name="value" type="User"/>
    </rpcdata>  
    <rpcdata name="UserPair">
    <variable name="key" type="UserID"/>
    <variable name="value" type="User"/>
    </rpcdata>
    <rpc debug="0" name="PutUser" type="3001" argument="UserPair" result="RpcRetcode" table="user" attr="put" key="key" value="value" maxsize="4096" prior="1" timeout="20"/>
    <rpc debug="0" name="GetUser" type="3002" argument="UserID" result="UserRes" table="user" attr="get" retcode="retcode" value="value" maxsize="4096" prior="1" timeout="30"/>
  15. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    вот от jio.jar и буду плясать, ибо гадать когда даже gouranga не может точно сказать какой опкод и нужна ли длинна нет смысла, кстати gouranga как это тебе gamedbd чтото отписала когда у меня возвращает по твоему скрипту 0 байт. Вот мне кажется что ты либо не то написал что у тебя в скрипте либо у меня что-то нетак хотя второе врятли.

    Вообще тяжело мне придётся, я ведь никогда не имел дела с бинарными данными, формат упаковки идт, это не php область...))

    Например:

    代码:
    $data = cuint(3002) . pack("V*", 4, 32);
    почему опкод надо проводить через функцию 

    代码:
    function cuint($data)
    {
    if($data < 64)
    return pack("C", $data);
    else if($data < 16384)
    return pack("S", ($data | 0x8000));
    else if($data < 536870912)
    return pack("I", ($data | 0xC0000000));
    return pack("c", -32) . pack("I", $data);
    }

    Почему форматы упаковки разные и от чего они зависят? Тоесть опкот мы проводим вообще по непонятной функции а длинну и значение мы упаковываем форматом "V беззнаковый long (всегда 32 бита, байтовый порядок little endian)"

    Вот в этой функции например else if($data < 536870912) , у нас что опкод может быть больше 536870912 ?!Оо


    Как я уже сказал я не имел дела с бинарными данными, не мог бы ты gouranga скинуть что почитать при данной проблеме отсутствия знаний в этой области? Но только не 1500 страниц а именно то что нужно

    P.S. Эти бинарные данные и форматы упаковки наверное основы основ в программировании) даже както стыдно, но ничего я ещё молодой и мозг норм шарит! Всё узнаю и успею!
  16. gouranga Эксперт Программист Пользователи Open Source Contributor White List

    帖子:
    67
    支持:
    142
    性别:
    Репутация:
    0
    Страна:
    Netherlands Netherlands
    чтобы что-то отправить, нужно знать как это сделать :lol:
    ты должен оотправлять на сервер byte[]. в нашем случае бинарный поток байт.
    опкод типа compacked_int, оттого я его так и отправляю. и компакт_инт может быть больше 536870912.

    говорю же, исправь jio.jar. пусть он у тебя логгирует отправленные данные.
  17. StAlKeR7779 Модератор Команда форума Модератор Программист Пользователи

    帖子:
    31
    支持:
    3
    性别:
    Репутация:
    0
    Команда:
    angelemu
    гоуранга =) он наверное имел в виду что опкод врятли будет больше 536870912 так заф тогда лишний код? =)
  18. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    StAlKeR6669 нет) это мы phpники нубы оказывается всё может быть, сейчас курю байтовый поток и прочую хренотень, это пиздец просто вынос мозга почитай немного офигеешь
  19. gouranga Эксперт Программист Пользователи Open Source Contributor White List

    帖子:
    67
    支持:
    142
    性别:
    Репутация:
    0
    Страна:
    Netherlands Netherlands
    http://iwebphp.com/ скачай, сделано для jade dynasty. упаковано с помощью Monas (http://ombudi.com/s-download/).
    чтобы понять как оно работает, варианта два
    1) поднять сервер JD и посниферить обмен пакетами, очень просто реализуемо
    2) попытаться распаковать байт код и потом его преобразовать в php. сложнореализуемо.
  20. TopicStarter Overlay

    Botchal MMORPG-DEVS.RU Пользователи

    帖子:
    182
    支持:
    67
    Репутация:
    0
    Ты ведь сначало посоветовал править jio.jar? Я вчера что зря редактор скачивал?
Черновик сохранён Черновик удалён

分享此页面