Глава 5 - введення в directplay
Введення в DirectPlay
DirectPlay - це рішення Microsoft для роботи з мережами. Хоча в кількох останніх версіях DirectPlay піддавався серйозним змінам, здається, що у версії 8 Microsoft вдалося реалізувати дійсно просту для використання систему. Фактично, настільки просту, що ви почнете працювати з мережею перш, ніж дізнаєтеся це.
Щоб використовувати DirectPlay в ваших проектах, переконайтеся, що включили заголовні файли Dplay8.h і DPAddr.h, а також вказали в списку компонування бібліотеки DPlay.lib і DXGuid.lib.
Я знаю, про що ви думаєте - що робить весь цей матеріал про DirectX версії 8 в книзі, присвяченій використанню DirectX версії 9. Не турбуйтеся, мій друг, Microsoft вирішила залишити незмінною 8 версію інтерфейсів в DirectX SDK версії 9 (дев'ятій версії інтерфейсів не існує ), так що інформація, яку ви знайдете тут, може бути застосована до DirectX як 8, так і 9 версій.
Мережеві об'єкти
Використовуючи DirectPlay ви отримуєте доступ до трьох, згаданим раніше мережевим моделям: клієнтської, серверної і тимчасової. У кожної є свій об'єкт інтерфейсу (всі вони описані в таблиці 5.1), і все надають схожі функції.
Таблиця 5.1. COM-об'єкти DirectPlay
Великомасштабні рольові ігри зазвичай для ефективної роботи вимагають використання моделі клієнт / сервер, тому я не буду в цій книзі обговорювати однорангові мережі. За прикладами їх використання зверніться до документації DirectX SDK і книгам, наведені в Додатку A. Я рекомендую в якості джерела інформації про використання тимчасових мереж в іграх книгу Тодда Барона «Програмування багатокористувацьких ігор».
Як я згадував раніше, сесія - це період часу протягом якого працює провідний вузол, або ви підключені до віддаленої системи. Коли з'єднання розривається, сесія завершується. У кожної сесії є унікальні властивості, такі як ім'я, пароль (якщо необхідний), максимально можливе число користувачів і т.д. Більш докладно про сесіях ми поговоримо в розділі «Конфігурація даних сесії» далі в цьому розділі.
Робота з гравцями
У термінах DirectPlay гравець (player) - це окреме підключення, що з'єднує вас з іншим комп'ютером в мережі. На одному комп'ютері може бути кілька гравців, але зазвичай використовується тільки один. Фактично, сервера для ідентифікації також призначається гравець.
Кожен гравець отримує ідентифікатор (Player ID), який система використовує для направлення повідомлень окремому гравцеві. Ці ідентифікатори - єдиний надійний метод визначення гравців, так що ваша програма повинна відстежувати їх.
У великих іграх можуть бути тисячі підключених гравців. Щоб поліпшити роботу з гравцями, деякі (або всі) гравці можуть бути об'єднані в групи (groups). Використовуючи групи ви злегка спрощуєте програмування, оскільки можете об'єднати в групу гравців, які перебувають в одній локації гри (такий, як карта або рівень) і відправляти дані всій групі відразу, а не кожному гравцеві індивідуально. (Є ряд інших причин для використання груп, але ця - одна з найбільш важливих.)
Взаємини між гравцями і групами показані на рис. 5.5. Немає ніяких обмежень на кількість гравців в групі і на кількість груп, які ви можете створити. Як видно на рис. 5.5, групи (позначені прямокутниками) можуть входити в інші групи (групи 1 і 2 входять в групу 3). Зверніть увагу, що гравці 7 і 8 ізольовані від груп; для DirectPlay не має значення, входить гравець в групу чи ні.

Мал. 5.5. Вісім гравців підключені до сеансу гри. Шість гравців відносяться до групи (або до двох груп), а два гравці знаходяться окремо від усіх груп
Незалежно від того, використовуєте ви групи чи ні, системи гравців, як тільки встановлено з'єднання, можуть взаємодіяти один з одним через повідомлення.
Мережеві повідомлення
Таблиця 5.2. Стандартні повідомлення DirectPlay
Хоча сенс деяких повідомлень зараз може бути вам незрозумілий, опису дають відправну точку. Ми будемо працювати лише з кількома повідомленнями, але це той випадок, коли чим менше, тим краще.
Опис мережевих повідомлень DirectPlay і пов'язаної з ними інформації ви знайдете в документації до DirectX SDK. Я рекомендую, щоб створюючи свій шедевр, ви тримали цей документ відкритим під рукою.
Для отримання повідомлень вашому мережевому об'єкту повинна бути призначена функція зворотного виклику, яка викликається кожен раз при надходженні повідомлення. Щоб забезпечити плавність потоку даних ця функція виконує розбір даних, грунтуючись на їх типі, і виконує повернення управління так швидко, як можливо.
Для відправки повідомлень ви використовуєте функцію відправки відповідного мережевого об'єкта (їх всього два). Ці функції прості у використанні і надають вам безліч параметрів доставки, включаючи гарантовану доставку, безпечне шифрування, асинхронну і синхронну доставку.
Асинхронна і синхронна робота
Перший варіант доставки, пропонований вам DirectPlay - це синхронна або асинхронна відправлення повідомлень. Це означає, що або система повертає вам управління після того, як отримала команду відправити дані (асинхронна робота), або вона чекає, поки дані не будуть успішно відправлено (синхронна робота).
Що краще? Швидше за все, ви віддасте перевагу асинхронний метод, оскільки він не затримує роботу системи, як це робить синхронний. Наприклад, якщо ви хочете відправити великий обсяг даних і одночасно намагаєтеся грати в гру, то не захочете переривати процес, чекаючи, поки мережа намагається передати інформацію. Просто повідомте, що потрібно відправити, і дозвольте DirectPlay зайнятися обробкою, а гравцеві продовжувати гру, ніби нічого не сталося.
Безпека
Страшно знати, що в будь-який час хтось в мережі може перехоплювати і записувати ваші дані. Тому у вас є можливість зашифровувати дані повідомлень, що ускладнює хакерам читання вашої дорогоцінної інформації.
Зворотною стороною безпечної доставки є уповільнення роботи системи, оскільки дані треба зашифрувати перед відправкою і розшифрувати після прийому. Якщо ви передаєте важливу інформацію, втрати часу не мають значення (але вони залишаються важливими для ігор).
У DirectPlay є вбудована підтримка безпечного обміну повідомленнями. На щастя, для її використання досить лише встановити відповідний прапор в операції відправки. Тепер цей тягар знято з ваших плечей.
гарантована доставка
DirectPlay може гарантувати доставку повідомлень, точно так же, як деякі транспортні компанії гарантують доставку відправляються через них посилок. Просто позначте повідомлення як вимагає гарантованої доставки, і будьте впевнені, що DirectPlay доставить його до місця призначення (за винятком випадку розриву з'єднання), безперервно повторюючи операцію відправки до успішного завершення. Використання гарантованої доставки залежить від вказуванні унікального прапора в викликається функції, що ви побачите трохи пізніше в розділі «Відправлення повідомлень сервера» цієї глави.
За гарантовану доставку доведеться платити швидкістю. Гарантована доставка надто повільна, щоб використовувати її в реальних ігрових ситуаціях. Ігри використовують метод доставки UDP (User Datagram Protocol), який не дбає про те, чи отримані дані (в протилежність методу доставки TCP, що гарантує доставку). Ви можете подумати, що це божевілля, але розібравшись в ситуації побачите, що ігри дуже часто відправляють оновлену інформацію, і втрата невеликої кількості даних час від часу цілком допустима.
регулювання потоку
Іноді ваша система може відчувати перевантаження, намагаючись обробити потік повідомлень. Однак, в DirectPlay є вбудована система регулювання потоку повідомлень, яка викидає повідомлення з низьким пріоритетом з черги.
Можливо, рис. 5.6 допоможе візуально представити концепцію використання механізму регулювання. Поглянувши на малюнок, уявіть чергу людей, які очікують перед входом в популярний нічний клуб. Кожна людина являє окреме повідомлення. і вибивала (механізм регулювання) повинен видалити найменш важливі з черги, коли заклад стає переповненим.

Мал. 5.6. Механізм регулювання (вибивала) приймає або відкидає повідомлення (відвідувачів) в залежності від їх важливості
DirectPlay чудово виконує регулювання потоку, так що зазвичай вам не треьуется міняти його параметри за замовчуванням.
Від маленьких байтів до великих словами
Світ дуже великий, все ми різні, і виникають ситуації, коли необхідний посередник. Я говорю про мовний бар'єр, зокрема про комп'ютерному мовний бар'єр.
DirectPlay введе вас в світ Unicode (якщо ви ще не знайомі з ним). Unicode - це універсальний стандарт, що дозволяє різним програмам і комп'ютерів спільно використовувати інформацію. Оскільки мережа може бути з'єднана з іншою мережею, розташованої в будь-якому місці світу, гравці можуть жити в різних країнах і говорити на різних мовах.
Оскільки версії Windows в різних країнах злегка відрізняються, призначені для користувача системи можна налаштувати на використання символів Unicode. В результаті вся система DirectPlay побудована навколо використання символів Unicode (для зберігання кожного символу використовується 16 біт замість 8) і пристосована до мов, які використовують більше 255 символів. Я чую ваш стогін, але дозвольте сказати, що в Windows є всі необхідні функції для перетворення з одного формату символів в інший, так що хвилюватися нема про що.
Ідентифікація додатків по GUID
Мережевих додатків так багато, як відрізнити свої від чужих? Дайте вашому додатку унікальний номер і дозвольте встановлювати з'єднання лише з тими додатками, у яких є той же номер. Цей спеціальний номер, звичайно ж GUID (Global Unique Identification), знайомий Windows-програмістам.
Створюючи додаток, приділіть хвилину, щоб призначити йому унікальний GUID і упевніться, що всі програми, які будуть з'єднуватися з вашим по мережі використовують той же самий GUID.
Ось і все, що я хотів зараз сказати про відправку даних. Хід виконання від створення мережевого об'єкту DirectPlay до відправки і отримання даних для різних типів об'єктів дуже схожий, так що в подальшому викладі я буду переплітати окрему інформацію.