Шел 2006й год. Это были хорошие студенческие годы, время расцвета и становления игры DotA Allstars. В те времена все играли в доту через официальный сервер от Blizzard — Battle.net. Индустрия была очень скудная — не было нормальных трансляций, интернет у многих был еще на adsl, а из событий — мало освещаемые турниры с призами до $5000. Тогда инициативные игроки собирались в группы и организовывались в кланы. Именно тогда мне позвонил мой товарищ и предложил организовать первую Дота-лигу в СНГ. Это был настоящий вызов для меня, и он был принят…
StealthBot
В те времена я активно возился с чат-ботами, которые могли сидеть на канале в Battle.net, притворяясь обычным игроком в Warcraft. Тогда самый распространённый и функциональный бот был — StealthBot. У него были встроенные функции вроде автокика ненужных людей с канала(safelist), он мог говорить сколько сейчас время и изображать из себя «умного бота», отвечая на заранее зашитые ответы на команды.
А еще в нём была отличная штука — автор этого бота предоставил возможность расширять этого бота через обычный текстовый файл script.txt, в котором можно было писать собственные скрипты на языке Visual Basic Script. Со школьных годов я любил заниматься программированием, а сама игра Warcraft 3 — была моей страстью. Я знал эту игру практически наизусть, я знал все звуки всех юнитов, знал все ресурсы, текстурки и модели этой игры, клепал карты в World Editor’е и гордо называл себя мапмейкером.
Чего греха таить, я и сам так считал и критиковал эту карту, смотреть на неё не мог.
Но всё изменилось в 2005м. Тогда вышла версия 6.01, которая была очень здорово оптимизирована и переделана. Эта карта загружалась даже быстрее, чем любая другая карта(даже более простая). Это был настоящий прорыв! К сожалению, до многих мапмейкеров так и не дошло, почему дота стала популярной, и это вовсе не из-за отсутствия сюжета. Эта карта была сбалансированной — в ней можно было играть любым героем и побеждать!
Жизнь в Battle.Net’е
Чат в Battle.net был довольно убогий:
- В нём нельзя было открыть отдельный приватный чат, в нём нельзя сохранять переписку
- При переходе на другой канал, у тебя стирается весь предыдущий
- Чтобы зайти в Battle.Net нужен был официальный CD-KEY — ключ от игры. Если у тебя пиратский Warcraft — ты не можешь зайти в Battle.net.
- История чата была лишь на последнюю сотню строк, а более поздние стирались
- На одном канале могло сидеть не более 40 человек
- А еще в нём нельзя было копировать или выделять текст!
- Про ссылки или смайлы я вообще молчу
Чтобы хоть как-то разнообразить жизнь в Battle.Net’е я писал ботов. Первые мои боты могли запоминать, когда в последний раз такой-то член клана был в онлайне (посещал канал). Затем через бота можно было оставлять сообщения человеку, который сейчас оффлайн (своего рода почта).
В то время единственной более-менее нормальной дота-лигой был европейский канал «Clan DCE», где стоял простенький бот, который кикал всех, кого нет в белом списке. Попасть туда было довольно не просто, хотя и не трудно. Но это всё было не то. Там не было учёта «плохих» игроков — кто сильно ругался, или самое неприятное — выходил из игры до её завершения (ливер). Играть в меньшинстве крайне тяжело, и в 90% случаев это проигрыш. Со временем, в DCE уровень игры стал падать, ливеры попадались в каждой игре, и их просто не успевали банить на канале.
В итоге всё это наталкивало на мысль, что надо взять ситуацию в свои руки, и открыть крутую дота-лигу, которая бы всех устраивала и решала эти проблемы! Моих познаний в ботостроении тогда хватало, чтобы записывать данные в текстовые файлы, читать с них, и общаться с людьми в Battle.Net. Вся мозаика потребностей и возможностей сложилась в голове, и я сказал себе: «Всё что надо есть, я смогу!» и понеслась…
Воздушные замки в голове
Нужно было придумать процесс, как игроки будут участвовать в лиге. C нуля на пустом месте.
Перед созданием лиги, нужно было решить первую очень важную проблему: хостить игры в Battle.net’е могли лишь те игроки, у которых открыты порты или имеются белые ip-адреса. Такие игроки были редкостью, и чтобы вдруг не возникало ситуаций, когда собирался народ поиграть, а ни у кого из них нет белого ip-адреса, было принято решение, что начинать набор игроков на игру могли только игроки, которые имеют возможность хостить игры. Им админы и модераторы должны будут выдавать особый уровень доступа «Hoster»(Хостер).
Следующей проблемой было то, что когда игроки заходят к кому-то в игру, то бот никак не может узнать, в какую команду они зашли — за 1.Sentinel или за 2.Scourge.
Со школьных лет, мой учитель по информатике хорошенько вбил в мою голову мысль, что все программы должны быть максимально простыми настолько, насколько это возможно, и я следовал этому примеру с самого начала.
И тут я решил: пусть Хостер начинает набор игры, сообщая боту о своём намерении(командой .create). Бот в это время всем в чат начинает каждые 20 секунд сообщать, что сейчас происходит набор игры, с именем игры:
QDL: Происходит набор в игру QDL012. Осталось мест: Sentinel: 4, Scourge: 5
Имя игры — это своего рода адрес IP, куда подключаться. Вводя название игры в Battle.net’е, игрок попадал в эту игру к Хостеру, а Хостер должен был предварительно создать игру и ждать народ.
Игрок мог зайти за любую свободную сторону, и когда он определялся с выбором, он должен был сообщить об этом боту(с очень коротким ником QDL и QD.) через отправку личного сообщения короткой командой:
/w qdl .j1 — значит он зашел за первую команду
либо
/w qdl .j2 — за вторую
Как факт подтверждения регистрации, бот отвечал: Success!QDL012;team1
Одна команда из 9 символов запоминалась довольно быстро, более того, игроки подсказывали друг другу, что надо сделать. Когда все слоты забиты, и все игроки зашли, Хостер должен был проверить список игроков, которые «зарегистрировались» в боте, и проверить, все ли игроки соответствуют своим командам. Для этого он отправлял боту команду:
/w qdl .check
и ему в ответ прилетало длинное сообщение, со списком игроков по командам:
QDL012 {Sentinels: [1]Quad.Tims [2]Quad.5min [3]AlfaCriostat [4]y6uBaIIIe4ka [5]remi} {Scourges: [6]Piragok [7]zagalex [8]Fade.Killer [9]Ums.Acc [10]upska}
Хостер должен был свериться со списком, и если всё впорядке, то сообщить боту о старте:
/w qdl .start
Игра начиналась, люди играли. В конце игры, люди возвращались на канал и сообщали о результате, кто победил:
.result 1 — победила первая команда The Sentinel
.result 2 — победила вторая команда The Scourge
.result 0 — ничья. Она могла произойти по разным причинам, обычно из-за ливера.
Когда 51%+ игроков проголосовали за какое-то решение, бот производил раздачу очков — отнимал у проигравших, давал победившим, и записывал в статистику к игрокам +1 победу победившим и +1 поражение проигравшим, чтобы вести статистику.
В качестве способа борьбы с ливерами, мы также попросили игроков сообщать о ливерах:
.leaver Username. Игрок терял свои очки, получал бан, а при превышении какого-то значения выгонялся навсегда с лиги.
QDL и QD.
Какие «фишечки» были в боте:
Бывали ситуации, когда, игрок зашел в игру и зарегистрировался у бота, а хостер его кикнул из игры, то игрок автоматически попадал на канал. Когда игрок заходил на канал, бот проверял — не зарегистрирован ли этот игрок в какой-либо игре, и если это так, то автоматически снимал с него регистрацию, и слот в счётчике игроков освобождался.
Хостер, отправляя команду CHECK и получая список из игроков, должен был сверяться — все ли зарегистрировались правильно. Бывало так, что кого-то кикнули, а регистрация не снялась. И чтобы хостеру не вводить длинные и сложные ники вроде y6uBaIIIe4ka, хостер мог ввести лишь порядковый номер «лишнего» игрока, и бот снимал регистрацию.
QDL: QDL012 {Sentinels: [1]Quad.Tims [2]Quad.5min [3]AlfaCriostat [4]y6uBaIIIe4ka [5]remi} {Scourges: [6]Piragok [7]zagalex [8]Fade.Killer [9]Ums.Acc [10]upska}
Hoster: /w qdl .kick 4
Бот вёл таймер для каждой игры, и у хостера было 5минут, чтобы начать игру, иначе игра отменялась, хостер получал штраф, а другой хостер мог объявить новый набор игры. Но это время можно было продлить, отвечая боту на предупреждения командой .continue.
На самом деле бот отправлял не одно длинное сообщение, из-за которого бота часто выкидывало за спам
QDL012 {Sentinels: [1]Quad.Tims [2]Quad.5min [3]AlfaCriostat [4]y6uBaIIIe4ka [5]remi} {Scourges: [6]Piragok [7]zagalex [8]Fade.Killer [9]Ums.Acc [10]upska}
А разбивал его пополам на два. Первое сообщение отправлял первый бот, а второе — второй.
QDL: QDL012 {Sentinels: [1]Quad.Tims [2]Quad.5min [3]AlfaCriostat [4]y6uBaIIIe4ka [5]remi}
QD.: {Scourges: [6]Piragok [7]zagalex [8]Fade.Killer [9]Ums.Acc [10]upska}
Это разгрузили ботов и батл.нет больше их не выкидывал.
Пробуждение силы
Код был написан примерно за 2 месяца. Это был настоящий разрыв мозга и трансформация мышления, я еще никогда не писал столько кода! Еще никогда не делал полноценный проект! Стыдно это признавать (но теперь уже не стыдно, т.к. знаю, что все с чего-то начинали): весь код был написан в обычном notepad.exe Windows, а в качестве хранилища данных использовались обычные текстовые файлы! Тысячи файлов! Никаких БД, никаких запросов! Только хардкор).
Запускаться решили через 2 недели: в ноябре 2006года. За 2 недели разместили информацию на всех Dota-форумах, где смогли, а мои товарищи соклановцы подготовили правила игры и начисления очков.
Остаётся последняя неделя и… мне мой друг сообщает, что меня взломали, какие-то чуваки запустили свою дота-лигу! Сначала я не поверил, что такое возможно, что вообще меня кто-то знает, а тем более смог разобраться в моём коде. Пошел на разведку к ним на канал, и оказалось, что это действительно наши соотечественники, но которые запустили чужого dota-бота, который был копией IRC-дотабота, обслуживающего самую мощную и самую закрытую дота-лигу IHCS (о которой никто среди простых смертных вроде нас и не знал).
Выдохнув с облегчением, что меня никто не взламывал, и уверенностью, что у нас всё равно самый крутой бот, мы не стали менять планов и запустились как положено.
Запуск
И вот мы запустились! В первый день ноября у нас было проведено около 10 игр. Народ вяло-текуче разыгрывался и тянул своих знакомых. Мы всех с радостью добавляли в белые списки и разрешали им играть. Чтобы увеличить поток игроков, мы выдавали сразу целые белые списки на имя Клана, например «FADE» — если на канал заходил игрок, и он состоял в этом клане, то он автоматически попадал в белый список.
А чтобы усилить конкуренцию, мы помимо списка лучших игроков вели список лучших кланов, в котором учитывались очки всех участнико в клане.
Через неделю у нас на канале уже стабильно 20 человек, с которыми можно начать игру.
Так как в Battle.Net было ограничение — максимум 40 человек на канале, то бот со временем научился кикать с канала неактивных пользователей, когда канал заполнялся на 90% чтобы другие могли без труда зайти.
Через 2 недели, можно было в любое время зайти на лигу и в течение 5 минут найти нормальных игроков, которые не ливали.
Эффект очков
Знаете, чего мы не ожидали? А того, что люди, никогда раньше не видавшие виртуальный счётчик очков (points), побед и поражений, что они начали выкладываться в играх на 100%! Они понимали, что если они будут плохо играть, то проиграют. А значит потеряют winrate, очки и снизятся в рейтинге игроков. Эти простые циферки, которые бот говорит в чате — значили для игроков очень многое! Быть топ-50 игроком из 1000 человек — это что-то да значило!
Как итог — на нашем форуме начали вестись горячие споры, кто прав и кто виноват. Мы обнаружили, что наши правила были далеки от совершенства и их приходилось в последствии постоянно совершенствовать — запрещать собирать определенные слишком сильные предметы(запрещён был некромикон, а некоторым героям собирать аганим и рефрешер), расписывать правоту в определенных спорных ситуациях итд. Очень быстро мы набрали помощников-модераторов, которые могли бы каждый день разбирать споры, менять результаты игры и наказывать игроков.
Лига жила полной жизнью сообщества, которое мы объединили! Мы создали дота-лигу, и на ней играет народ, пользуется нашими поделками! Это было настоящее юношеское счастье самореализации!
Перспективы и монетизация
Сейчас довольно забавно это вспоминать, но проект вообще не предусматривал никакой монетизации или коммерции! Тогда мы как пионеры работали просто ради славы в интернете :). Ни я, ни администраторы-соклановцы, ни набранные модераторы не получали ни копейки. Да и времена были такие, что из виртуальных денег были только WebMoney, которыми пользоваться умели немногие.
Со временем, мы подружились с ребятами, которые вперёд нас создали лигу, и начали дружить. Оказалось, что организаторы лично знают всех самых лучших Дотеров, и они рассчитывали создать закрытую лигу, чисто для самых топовых игроков, а нам они обещали скидывать всех остальных, кто им не подходил. Нам — дополнительная реклама, им — возможность вежливо «отказать» неподходящим игрокам.
Договорились, а на деле вышло совсем не так, как задумывалось: так как у них было довольно мало игроков, то чтобы собраться поиграть, игрокам приходилось ждать подолгу, пока соберется 10 топовых дотеров. Такое работало только в самые часы пик — с 18 до 22ч, а в другие часы ждать приходилось минут по 20-30, и чтобы не ждать, они просто шли к нам. Как итог — все играют у нас — и лучшие дотеры, и «не лучшие». Иногда это приводило к скандалам, интригам и расследованием, например они за одно лето(самый неактивный сезон) переманили к себе почти всех наших админов и модераторов. Работать стало некому, приходилось заново набирать команду.
Всё вроде бы шло неплохо, но я чувствовал, что что-то не то. Кажется, я уже не знал, как можно улучшить лигу, в силу своих возможностей. Со временем в лиге выявилось довольно много проблем
Снова проблемы
Прошел 1 год:
— Battle.Net лагал. Игры, которые хостились через Battle.net, вызывали задержки как минимум в 80мс, в то время как по LAN’у задержка была 40мс (это стандартная задержка игры, если игра хостится через официальный клиент Warcraft. Гораздо позже вышел хост-бот: GhostBot, который радикально уменьшил пинг)
— Были читеры. Увы, на каждый новый патч от Blizzard, выходила новая версия MapHacka (видеть всю карту и персонажей вне поля зрения), или DropHack’а(хостер мог выкинуть любого игрока (который ему не нравился, или очень сильно раскачал героя) прямо по среди игры, и тому дали бы бан за ливерство). Модераторам было сложно рассматривать такие случаи, определить читера по реплею очень сложно.
— Метод набора в игру был несовершенен. Очень часто происходили абузы со стороны Хостеров — они набирали в свою команду хороших игроков, а в противниках оставляли самых убогих. Получалось, что если ты хостер, то ты можешь с вероятностью 90% одерживать победы. Волна негодования возрастала.
— Чат был убогим, не позволял ботам слишком много писать личные сообщения или в чат. Тут пришлось запустить 2 бота, и часть сообщений отправлять через второго. Напомню, что боты работали через обычные текстовые файлы — по одному на каждого игрока, и на каждую сыгранную игру.
— HDD тормозил — тогда я даже не знал, что HDD работает медленно, когда ему надо определить лучшего игрока из 1000 игроков, открыть 1000 файлов и выдернуть 3 лучших. Надо было решать эту проблему…
Судьба
Вы верите в судьбу? А я верю. Точнее уверился в ней. Вот вам мой первый пример:
Помните, я выше писал про лигу DCE, которая была довольно простой? Так вот, меня тогда всё же добавил в белый список мой друг-немец, с которым я познакомился в одной из игр. Он как-то узнал, что я пишу ботов, и попросил им сделать апгрейд их бота. Этот парень знал PHP и MySQL, но вот ботов писать не умел(и не хотел). Он попросил, чтобы бот умел работать с базой данных через ODBC-клиент MySQL, и даже нашёл примеры кодов на VBS. Мы провели с ним месяц, он научил меня SQL, объяснил что такое базы данных, и как в них лежат данные. Так-же он показал мне волшебный unixtime, с которым очень просто прибавлять к датам дни, минуты или секунды, особенно, когда нужно было давать бан на время, например полтора часа.
Я сделал ему бота, которого он хотел, который имел прямую связь с БД от сайта, и он смог у себя реализовать управление списками игроков прямо из форума.
Распрощавшись, и вооружившись новой технологией, я за пару недель переписал с нуля своего бота на «новую технологию» — MySQL. Это был настоящий прорыв для меня. Можно было в одну секунду получить лучшего игрока, посчитать очки у всего клана, или вывести статистику по всей игре! Бот начал летать, а игроки получили нового бота с новой механикой набора игр, автобалансировкой команд по очкам.
Так что там на счёт судьбы? Сейчас я понимаю, что я тогда забрёл в тупик, и не знал, куда дальше развиваться. И если бы не этот немец (и не то случайное знакомство с ним во время игры), то он бы не научил меня MySQL, а сам я вряд ли бы вдруг загуглил «как работать с mysql».
Я не могу назвать это обычным совпадением, которое привело к знакомству 2 года назад, и привели к толчку в сторону познания баз данных и понимания, что даже из этого хиленького StealthBot можно цепляться к большим и крутым базам данных!
Развитие
Я нашёл интересный язык AutoIt, с которым написал свою первую программу-клиента для лиги. Встроил в него детектор самых распространённых читов, и сказал, что игроки, которые будут играть с ним, будут получать на 50% больше очков. Желающие нашлись, и это был первый интересный опыт клиент-серверного программирования.
Учитывая все минусы, которые портили хорошее впечатление от игры, я начал искать альтернативные клиенты и платформы, на которых можно было поиграть.
Среди первых испытуемых был Hamachi. Увы, с ним не сложилось — слишком сложно настраивать, требуются админские права (устанавливается виртуальная сетевая карта), но качество связи было хорошее, пинг был ниже, чем в Battle.Net.
Следующим испытуемым была программа Battle Lan(Lancraft) — небольшая программа, которая транслировала широковещательные udp-пакеты разведчики на введённые адреса, и таким образом, если кто-то с белым IP создавал игру прямо в локальной сети, то его могли увидеть другие игроки за NAT’ом. Я встроил и автоматизировал её в своём клиенте, и некоторые игроки смогли играть друг с другом. Увы, решение оказалось нестабильным — часть игроков видела хостера, а другая часть нет.
Среди последних в поле зрения попал некий Good Game Client (GGC, в будущем — Garena). В нём можно было очень легко поиграть как по LAN’у в такие игры как Counter Strike 1.6, или Warcraft 3(гораздо позднее была добавлена DotA). Пинг очень радовал! Коронная фишка была в возможности устанавливать прямые udp-туннели между игроками, находящимися за NAT, чтобы они могли играть друг с другом, даже не имея белого ip, более того, они были ярыми поклонниками обычного Warcraft 3 и у них был встроеный обновляющийся античит. Чтобы играть здесь не требовался официальный ключ от Warcraft III. В целом всё круто, но под него не было написано никаких ботов. Что-ж, я мог быть первым!
Используя свои познания в AutoIt, я смог получать Handle от окна чата, и обычным чтением получать текущий текст. Точно также, я получал handle поля ввода сообщения, мог вводить текст, и отправлять виртуальный клик по кнопке «Send». Осталось только получать список пользователей на канале, и это тоже получилось. Технически, я был готов запустить там бота. Но в этой платформе не было игроков. Никто не играл там, все привыкли к Battle.Net.
Это был 2008й год, вроде не так много времени прошло, но тогда у многих был платный траффик за каждый мегабайт! И это было неприятно — играя через обычный Battle.Net сеанс игры съедал около 1мбайта, а играя через GGC — игра уже стоила 2мбайта (из-за инкапсуляции данных, ходящие в виртуальном туннеле связи), что для некоторых игроков было критично — играть в доту стало дороже!
Я видел перспективы в этой платформе, адаптировал под неё бота, запустил его там, назначил нескольких местных игроков админами, чтобы следили, и объявил переходный период в 1 месяц. Народ тянулся неохотно, и вплоть до последнего дня играл в Battle.net’е. После отключения бота в battle.net’е, народ объявил демарш, и не стал подтягиваться в GGC, вместо этого народ стал играть на той соседней «закрытой лиге» от наших соотечественников.
Я верил в успех, и в течение месяца мы снова стали активно проводить игры на новой платформе. Уже через год в Battle.Net никого небыло, GGC теперь называлась Garena, а игроков у нас стало в 2 раза больше, чем раньше в Battle.Net.
Продолжение следует…
update: Как я Дота-лигу открывал. Часть 2
Источник