Статьи Сетевой протокол Quake 3

Discussion in 'Статьи' started by begin_end, 18 Aug 2012.

  1. begin_end

    begin_end Green member

    Joined:
    4 Jan 2007
    Messages:
    257
    Likes Received:
    590
    Reputations:
    471
    Сетевой протокол Quake 3
    Опубликовано 29 ноября 2011
    Автор: Darren



    Этот документ описывает сетевой протокол, который Quake 3 использует для общения с клиентами и внешним миром (серверами запросов). В настоящее время в стадии разработки.
    Я в последнее время (август 2012) добавил запись в блоге с пересмотренной версией моего протокола 43 (прокси-сервер).


    Запрос

    Запросить сервер очень просто. Отправляется UDP пакет с 4 байтным заголовком (0xffffffff) и текстовой строкой GetStatus. Есть много сайтов, которые содержат подробное описание, так что я не буду вдаваться в подробности.


    Игровой протокол 68 – в версии 1.32

    Все игровые пакеты – UDP, но есть еще процессы «обмена рукопожатиями», которые должны произойти до того, как вы получите право присоединиться к серверу.

    Клиент посылает запрос на получение идентификатора (иногда вам нужно отправить несколько запросов, прежде чем сервер среагирует).

    [​IMG]


    Если сервер способен принимать новые подключения, он ответит.

    [​IMG]


    После этого клиент имеет <ID> и может отправить запрос на подключение. Но, увы: <CS> является Хаффман-упакованным в протоколе 68 и НЕ является открытым текстом, как показано ниже. Протокол 43 использует текстовую версию.

    [​IMG]


    <CS> представляет собой строку, содержащую детальные параметры подключеняи игрока, например:
    Code:
    \cg_predictItems\1\sex\male\handicap\100\color\3\snaps\40\rate\10000\model\doom/red\name\UnnamaedPlayer\protocol\68\qport\<PORT>\challenge\<ID>
    <PORT> представляет собой номер локального порта, используемого для передачи этого пакета.

    Если подключение успешно, сервер ответит следующим образом:

    [​IMG]


    Сервер поставит вас в CNCT (подключающееся) состояние и начнет отправлять вам обновления игры.

    Вот где комуникация значительно усложняется, поэтому я предупреждаю вас, что следующее может быть неполным и, возможно, неправильно – хотя я надеюсь, что это не так!

    Клиент – серверу
    [​IMG]


    Команды клиента
    Code:
    0 - clc_bad
    1 - clc_nop
    2 - clc_move
    3 - clc_moveNoDelta
    4 - clc_clientCommand
    5 - clc_EOF
    Сервер – клиенту
    [​IMG]


    Команды сервера
    Code:
    0 - svc_bad
    1 - svc_nop
    2 - svc_gamestate
    3 - svc_configstring
    4 - svc_baseline
    5 - svc_serverCommand
    6 - svc_download
    7 - svc_snapshot
    8 - svc_EOF
    Подробности
    (1) - сжатие Хаффмана с использованием заданного набора узлов для дальнейшего сокращения длины сообщения (подробности см. ниже).

    [​IMG]

    (2) - XOR алгоритм, используемый сервером для декодирования содержимого сообщения.
    Code:
    #define CL_ENCODE_START 12
    byte key, *string;
    int i, index;
    
    string = (byte *)clc.serverCommands[ reliableAcknowledge & (MAX_RELIABLE_COMMANDS-1) ];
    index = 0;
    //
    key = clc.challenge ^ serverId ^ messageAcknowledge;
    for (i = CL_ENCODE_START; i < msg->cursize; i++) {
        // modify the key with the last received now acknowledged server command
        if (!string[index]) {
            index = 0;
        }
    
        if (string[index] > 127 || string[index] == '%') {
            key ^= '.' << (i & 1);
        }  else {
            key ^= string[index] << (i & 1);
        }
        index++;
        // encode the data with this key
        *(msg->data + i) = (*(msg->data + i)) ^ key;
    }
    (3) - XOR алгоритм, используемый клиентом для декодирования содержимого сообщения.

    Замечания
    Данные имеют смешанный порядок следования байт, это верно?

    Фрагментация пакетов работает с помощью расчета sequencetNumber и FRAGMENT_BIT (где FRAGMENT_BIT это 1<<31).
    Если пакет фрагментирован, то для исправления sequencetNumber нужно перевернуть бит в ноль.

    cl_shownet 1 – MSG_SIZE
    cl_shownet 2|3 – READ_COUNT – CMD
    showpackets 1 – WHO recv MSG_SIZE : s=SEQ_NO (optional fragment info)



    Благодарности
    1. Quakesrc SVN Repository http://www.quakesrc.org/websvn/
    2. The Unofficial Quake 1 Network Protocol description. http://www.gamers.org/dEngine/quake/QDP/qnp.html
    3. The Quake 2 Network Protocol description by Tim Ferguson. http://goo.gl/MfzTz
    4. The quake 3 source code which id software released. http://www.idsoftware.com/
    5. A sniffers best friend, Ethereal – The Network Protocol Analyzer http://www.ethereal.com/




    Перевел с первоисточника на английском: begin_end, 17.08.2012.
    Переведенная статья в формате *.doc (11 KB).
    Обсуждение материала весьма приветствуется.
     
    _________________________
  2. begin_end

    begin_end Green member

    Joined:
    4 Jan 2007
    Messages:
    257
    Likes Received:
    590
    Reputations:
    471
    Данный материал выложен здесь с целью поиска аудитории, заинтересованной или опытной в указанных вопросах. Ежели кто-то работал с протоколом Quake3, разрабатывал ПО для него, просьба комментировать и дополнять. Необходима любая информация, так как официального опубликованного RFC в каком-либо виде нет. Этот материал, фактически все, что известно.
    Один из важных моментов - разобраться с применением сжатия Хаффмана. Как и с чем его есть в этом случае, м.б. пример рабочего софта...


    Авторы полезного контента будут щедро поощрены репутацией.
     
    _________________________
  3. Hyde

    Hyde New Member

    Joined:
    6 Aug 2012
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    Спасибо, полезно!
     
Loading...