Сетевое взаимодействие в играх

Тема в разделе "WASM.A&O", создана пользователем igrock, 22 май 2008.

  1. igrock

    igrock New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2008
    Сообщения:
    29
    Здравствуйте.

    Начал реализовывать сеть в бомбермене, но после непродолжительных размышлений понял что с ходу не осилю ^_^.
    Решил накидать пару идей, и вот что получилось, может кто уже делал сетевую игру, подскажет какие могут быть "подводные камни".



    Сервер при запуске ждет подключений, клиенты при запуске подключаются и ждут команды от сервера, когда все подключились на сервере можно дать команду начинать,

    Кратко.

    Изначально ведется прием заявок, какого цвета хочет быть клиент, если такой цвет свободен то ему выдается id.
    Затем после команды начинать сервер рассылает информацию для расстановки юнитов на карте у клиентов, после этого каждый клиент будет знать какие id у какого юнита.
    Когда один из клиентов посылает сигнал, то сервер рассылает его по всем клиентам, у которых происходит активация юнитов.

    Подробно.

    Сервер ведет список подключившихся, который пополняется по мере подключения клиентов.
    Например максимальное количество клиентов 10;
    Соответственно при создании сервера генерируется 10 id-шников;
    При подключении клиенту выдается уникальный id из списка, в который в свою очередь заносится ip этого клиента и прочая информация, например цвет, и сервер в любое время может выдать список ip подключившихся.

    Изначальное состояние сервера и клиента
    Сервер Клиент
    id1 ... ... ip1
    id2 ...
    id3 ...
    =========

    После подключения клиента у сервера каждому id соответсвует определенный ip.
    Каждый клиент получает свой id.


    id1 ip1 -> id1 ip1
    id2 ...
    id3 ...
    =========

    Когда на сервере подали команду начинать, всем клиентам рассылается список id (+ информация о параметрах юнитов, например цвет), на основе которого клиент создает юнитов на карте, причем нет разницы чей юнит, они для ютого клиента на его карте равноправны, и управление ими осуществляется только через сервер, при помощи id.

    Взаимодействие и синхронизация.

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

    Получается сквозное управление всеми юнитами с одинаковым id на картах всех клиентов.
    Единственное отличие от версии локального управления с клавиатуры, комманды приходят по сети. Все равно что управлять машинкой не рукой а пультом дистанционного управления.

    Например клиент id=500 нажимает <Left>, данные [<Left>+500] отсылаются на сервер, затем их получают все клиенты, смотрят на id и отправляют этому юниту команду передвинуться влево.

    В случае с TCP, клиент может не получать никакого id у сервера, т.к. имея уникальный ip сервер отожествляет его с конкретным id хранящимся у него в базе, и когда клиент призылает <Left> сервер смотрит его ip и уже рассылает всем [<Left>+id]

    В случае UDP broadcast, сервер необходим только на стадии начальной инициализации сессии, клиенту при подключении необходимо получить уникальный id, а также узнать id остальных клиентов, потом сервер уже не нужен, т.к. клиент сам рассылает широковещательно [<Left>+id], а остальные клиенты на основании id активируют юнита на своей карте, клиент-владелец события может либо наравне со всеми принимать это сообщение как в случае с TCP, либо непосредственно активировать юнита.

    =======================================================

    Пересылаемые данные.

    а) Если пересылаются нажатия клавиш, то клиенты при получении таких данных обрабатывают их как если бы эти клавиши нажимались локально, но в таком случае каждому клиенту придется обрабатывать логику всех юнитов на карте.

    б) Если пересылаются координаты или вектор то вся логика обрабатывается на стороне клиента-владельца этого юнита, а остальным клиентам получив такие данные необходимо только передвинуть юнита на карте.

    Метод связи.

    а) Сервер является центральным координатором рассылаемых данных.
    При подключении выдает уникальный идентификатор каждому подключившемуся.
    При нажатии клавиши на клиенте, они передаются на сервер, который проверяет правильность данных, и рассылает всем подключившимся.
    Клиент получив эти данные от сервера проверяет идентификатор и обрабатывает нажатые клавиши только на этом юните.
    При отключении сервера, связь между клиентами обрывается, т.к. весь трафик проходит через сервер.

    б) Сервер необходим только для начальной стадии инициализации сессии.
    При подключении клиента ему выдается идентификатор сессии, его личный идентификатор клиента (который заносится в список сервера), а также все идентификаторы всех подключившихся.
    Когда на клиенте нажимается клавиша, то эти данные вместе с идентификатором отсылаются широковещательно, и сервер в данном случае не нужен.
    При отключении сервера связь между активными клиентами остается, новые клиенты подключаться не могут.

    Вот собственно такая идея )

    Спасибо.

    P.S. Конечно в сети есть куча доков, но хотелось бы развить свою идею, а не делать по шаблону ^_^,
     
  2. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    igrock
    да, в общем, всё верно, только каждый клиент должен рассылать не свой id, а hash(id+RndStr) & RndStr. если SSL юзаешь, то можно айдешник в чистом виде слать. ещё нужно ситуацию с читами разруливать - логи тебе в помощь.