Обещанный длиннопост.
Начну, пожалуй, с конца. С того, что больше всего попило кровушки.
Небольшой ликбез для тех, кто даже не знал, что в Варкрафте или Досбоксе есть сеть (можно пропустить):
Warcraft имеет поддержку сетевого IPX протокола. Нет, он не совместим с TCP/IP. Протокол уже много лет не поддерживается, и я даже не знаю, существует ли его реализация для Винды позже ХР. В ДосБоксе пошли навстречу всем страждущим и "запилили" эмуляцию. Приблизительно так: игра передает подготовленный IPX пакет "драйверу", его ловит ДосБокс, "обворачивает" в UDP и предает по TCP/IP другому Досбоксу, который его "разворачивает", вытягивает IPX пакет и подкладывает, как бы из "драйвера" запущенной игре. Но никто не запрещает другой программе слушать тот же UDP, ловить те же UDP пакеты и извлекать из них IPX данные. И наоборот, отправлять по UDP Досбоксу свои данные. Чем я, собственно, и занимаюсь.
Большинство современных разработчиков представляют упрощенную картину сетевого приложения приблизительно вот так:
Да и я, хоть и имел некоторый опыт гонять данные через сокеты, будучи нубом в этой сфере, думал так же. При этом, прочитав однажды где-то в журнале "Мурзилка", что IPX пакеты очень похожи на UDP пакеты, я сразу же представил схему портирования сетевого кода как-то так (оранжевая область - то, что надо переписать)
Но обычно мы забываем о тех мелких удобствах, которые несет нам прогресс. Реальная картина сетевого софта выглядит как-то так:
И вроде бы ничего страшного для современного программиста нет. Но в моем случае все немного печальнее:
Причем, я не уверен, использовали ли Blizzard сторонние либы или писали все сами. Я склоняюсь все же ко второму варианту, так как в суровые 90-е разработчиков под ДОС сетевыми либами не очень-то и баловали. Да и стиль кода очень похож. В любом случае, в виде ассемблера, для меня это все стало общей кодовой кашей. И если игровая логика мне была уже более-менее понятна, то чем ближе к низкоуровневому коду сети, тем становилось грустнее.
Кроме того, многие части этого кода обслуживали нюансы работы IPX драйвера, о которых я не подозревал: IPX мне знаком на уровне самых примитивных основ, а в TCP/IP всю эту муть скрывают от нас любезные разработчики либ. Как оказалось, сам драйвер умеет не так уж много, но зато его нужно очень деликатно умасливать, чтобы получить ожидаемые данные. Так что старая схема по портирования пошла в корзину, а под новую схему были два варианта.
Вариант первый, "как есть":
Т.е. я ручками переписываю всю логику по обслуживанию драйвера и нюансов работы IPX сети.
Вариант второй:
Всем мил и прост второй вариант. За одним теоретичесвим исключением. Начиная разбирать этот кусок игры, я понятия не имел (да и сейчас не имею) какие опции/эвенты сетевого кода важны для игровой логики. Может, игра совершенно игнорирует всю эту составляющую, просто передавая туда пакеты данных. А может, она следит за каждым чихом сети, чтобы подстроить latency, повторить запрос и т.д. И если я выберу второй вариант, у меня появится, хоть и не большой, но очень критический риск: на позних этапах доработки сетевой игры я не смогу синхрониховать WinWar с оригиналом. Будут какие-то критически малые различия в таймингах, и я не смогу заставить стандартные dotNET сокеты реагировать правильно. У меня просто не будет контроля над внутренней кухней отправки/получения данных. И хоть, опять же, вероятность такого события невелика, я в таком случае просто заброшу разработку.
Ну, соответсвенно, я выбрал первый вариант. Если честно, то работу с таймингами я до сих пор не довел до ума, просто расставив "на глазок" sleep-ы, чтобы оно хоть как-то работало, ибо слишком быстрая или слишком медленная передача данных разваливает синхронизацию оригинала. И все же, я более-менее спокоен, так как я контролирую бОльшую часть сетевого кода, а все "провтыки" основаны нежеланием моей ленивой жопы читать огромные талмуды по нюансам работы IPX протокола.
Теперь вернемся к игровому уровню. Тут, хоть все и попроще, но тоже напрягает. Формат игровых команд высчитывается на "раз-два". Вот, допустим, жмакнули мы на Таун Холл, сформировалась команда, типа:
Команда="выбьрать" Объект="42"
Что с ней делать дальше? В одиночной игре - взять и сразу обработать. А в сетевой? Передать в сетевой код для отправки? Нее.. Сначала мы пложоим ее в очередь на отправку. Задержка-то в сетевой игре существует, и по одному пакету гонять - несерьезно (с пингом, скажем в 100мс, получится не больше 10 АПМ для игры).
ОК, собрали мы очередь команд, подошло время отправки. Что мы делаем дальше, пихаем команды в сеть? Ну что вы! Мы пихаем их в пакет (мое временное название s_PacketData3), который кроме очень полезных, но теоретически необязательных флагов, имеет Id синхронизации. Чтобы игра с той стороны понимала, на какой мы стадии, и не случилась ли рассинхра.
Хорошо. Использовали мы твой, прости господи, s_PacketData3. Можно отправлять? Увы, мы должны запихать его в пакет. Да-да, пакет s_PacketData3 в пакет s_PacketDataExt. Он имеет еще CRC и позволяет проверить, не поломался ли наш пакет при передаче через сеть. Сейчас-то сети хорошие, Ютубчик редко глючит, а раньше и не угадаешь, что придет на тот конец провода. CRC не то, что гарантирует целостность данных, но довольно часто помогает отбросить поломанные пакеты.
Все, спаковали мы s_PacketDataExt, можем отправлять? Нет. Угадаете, что мы будем делать с пакетом? Да! Запихивать в другой пакет! Называется он у меня банальнее: WarcraftPacket. Что он имеет? Не поверите, тоже Id. Что за хрень? Зачем нам еще одно Id, мы уже имеем его в, прости господи, s_PacketData3! Это Id, совсем не то Id. В s_PacketData3 Id служит для того, чтобы игра понимала, какой набор команд должна обработать сейчас, а Id из WarcraftPacket имеет уровень ниже. Дело в том, что броадкаст в IPX тех времен, это такая себе дыра в которую все кричат, а ты что-то записываешь. Причем кричат частно кричат невпопад. Но даже если б кричали строго по-порядку, то и тогда ты не всегда успевал бы все записывать. Для таких целей Варкрафт слушает IPX "дыру" в 9 ух. Соовтетсвенно, что на выходе получается каша-малаша. И чтобы хоть как-то навести порядок, мы делаем дополнительную Id. Теперь, на уровне WarcraftPacket мы все упорядочним для передаче игре, и тогда, уже недочет по s_PacketData3 Id, будет означать именно потерю пакета, а не неправильный порядок. Стало быть надо подождать или сообщит о рассинхре.
Вот, теперь мы почти готовы к отправке, осталось только WarcraftPacket положить в IPX пакет, а его в UDP пакет и дело сделано!
Про установление игровой сессии и поддержке ее синхронизации - как-нибудь позже.
-
Скрыть объявление
Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.
-
Скрыть объявлениеЕсли Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.
Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
- Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
- Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
- Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
- Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
С уважением, администрация форума Old-Games.RU
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2Ffe0d2cf640dae5a19752aa96249be6af%2F1557921838%2F1716%2F1318103%2F1.png&hash=0e86bdb392bfd93437fb573e79c94f1f)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2F6728adbe610a773904941c4fd1e00ed0%2F1557921971%2F2707%2F1318103%2F2.png&hash=131ead190d51b0d3a5594e2d35719aa3)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2F6c5f0e8ed985d982462c98b0ae7fd888%2F1557922037%2F1975%2F1318103%2F3.png&hash=2148fc154e56dc1c87f2fe39799cb352)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2Fc9eeb4c6121e7ddb5b6a509e9e7204e5%2F1557922079%2F2104%2F1318103%2F4.png&hash=e8fe5295da64fbb82742d87995b5babe)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2F80d2528fbc9dcf3941560c6a306a7c3e%2F1557922151%2F1645%2F1318103%2F5.png&hash=16aded1e3792132c724567cb4960acc4)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2Fe17ea88e123746e7c21b53dce251bdea%2F1557922208%2F3780%2F1318103%2F6.png&hash=6a07dbd4209352a6787d840deab7a9d4)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2F24acd2db7dba662092b929165780fe37%2F1557922258%2F3412%2F1318103%2F7.png&hash=1a830c306b3048c6b70253f28d80e28f)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2Fbf2348494523e4e6cb0d9ddad4fe5782%2F1557922327%2F50281%2F1318103%2F21_800.jpg&hash=4e7b4f6a5c9e006556309ff70d39ba43)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2F14b76e6b81a6632fb27e54e6ca299f58%2F1557922446%2F54359%2F1318103%2F22_800.jpg&hash=c72c4901c3159c5837ff5ed2515052db)
![[IMG]](proxy.php?image=http%3A%2F%2Fi.piccy.info%2Fi9%2F4ee48748360e22994efc4486f27ec7e3%2F1557922512%2F73832%2F1318103%2F33_800.jpg&hash=5a62a767385e3bce3120545b670d7786)
Комментарии
Сортировать комментарии по