Горящие дома и жопы игроков в Ultima Online: как чинили баг с дюпом предметов

В честь 25-летия игры разработчики поделились историей одного весьма интересного бага — клонирования предметов.

Горящие дома и жопы игроков в Ultima Online: как чинили баг с дюпом предметов

На годовщину Ultima Online разработчики рассказали про занятный случай c дюпом предметов. Разобрал кратко в Твиттере. Самая вишенка в истории в том, что вместо какого-то фикса нормального, они помечали такие предметы, а потом после выкатки обновления разом их все удалили 😈

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

В итоге у каждого оказывалась копия сундука.

Горящие дома и жопы игроков в Ultima Online: как чинили баг с дюпом предметов

В UO нету типичных зон с подгрузками, вместо них разработчики изобрели прямоугольные бесшовные «подкарты» с методом, позволяющим пройти от одной стороны к другой, в то время как вещи на другой стороне всё ещё видны и обновлялись в режиме реального времени.

Каждый игровой сервер фактически был разделён на районы, и был код, который обрабатывал передачу состояния игры, условий объектов и событий с одной стороны границы на другой. Но пересечение этих границ в качестве игрока иногда заметно тормозило.

Горящие дома и жопы игроков в Ultima Online: как чинили баг с дюпом предметов

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

У игры не было привычной БД. Использовали дампы памяти 🤔

  1. Каждый шард выполнял отключение/резервное копирование в определённое время.
  2. Полное игровое состояние каждого ареасерверы сбрасывалось из памяти в большой двоичный файл.
  3. Как только серверы завершали резервное копирование, они отключились, перезапускались и переходили в режим ожидания, в то время как «игровой сервер» делал то же самое.
  4. Игровой сервер выключался, перезапускался, а затем инструктировал каждый ареасервер загрузить свою последнюю заведомо исправную резервную копию.
  5. Каждый ареасервер загружал бинарную резервную копию и воссоздавал ранее сохранённое состояние игры; он также выполнял любые триггеры/хуки.
  6. Куча других вещей, включая появление новых мобов или ежедневных редких предметов.
  7. Ареасерверы инорфмировали, что всё в порядке, и сообщали игровому серверу, а он повторно объявлял о себе авторизационным серверам, что он доступен для игры.

П.2 был самой большой проблемой. Найти дубли в дампе нереально.

Но п.5 натолкнул разработчиков на идейку: на старте сервака помечать наиболее ценные предметы и сохранять их в глобальный хеш-реестр.

В общем, на ценных предметах висела уникальная метка. Когда по предмету проводилась логика какая-то по копированию, то на копии оставалась метка и можно было свериться с глобальным реестром. Если уже был предмет с такой меткой, то копия потом помечалась тегом «I AM DUPED».

За несколько недель скопилось много таких предметов и стали решать, что же делать.

Но когда начали общаться с директором и QA/КМ'ами, то те сразу дали понять, что дропать все дубли не самая лучшая идея, т. к. вызовет гнев очень большого числа игроков.

В итоге:

  1. Нашли багоюзеров и их хранилища
  2. Нашли всех причастных в «кольце дублирования»
  3. Написал скрипт
  4. Служба поддержки массово забанила мошенников
  5. Остановили соединение gameserv/loginserv с теми же серверами, к каждому жилищу, прикрепили скрипт

Сам скрипт:

  1. Удалить дом и его содержимое. Рекурсивно.
  2. Заполнить область чёрным щебнем.
  3. Создать кучу вечных огненных полей среди щебня.
  4. В центре поставить соломенный манекен с надписью «An Effigy of a Traitor».

Мир игры вспыхнул, как и жопы игроков 😈

Горящие дома и жопы игроков в Ultima Online: как чинили баг с дюпом предметов

Поддержку завалили письмами.

С технической точки зрения, даже с отсутствием БД, странно, что не сделали какие-то программные транзакции с двухфазным коммитом, чтобы избежать клонирования в этих зонах.

132132
25 комментариев

Подожду видео версию от булджать

26
Ответить

Так у него было про ультиму в разных родиках

1
Ответить

Тоже поделюсь историей из UO. Где-то же нужно её описать. Если посмотреть на город Trinsic, там справа есть Barrier Isle, на котором живут два кролика. Это отличное место для тренировки Animal Taming. Но после приручения кроликов, твои кролики там остаются, а потом появляются два новых кролика и так далее. Таким образом этот полуостров можно заселить кроликами почти под завязку. Я не помню сколько у меня их там было, больше 30-40, наверное, т.к. я хотел прокачать этот скилл. В этом месте разрешен PVP. И в один обычный день, туда зашел какой-то игрок, который то ли стал мне угрожать, то ли как-то иначе агрессивно себя вёл. Я ему стал писать типа "Go away, I'm Lord of Rabbits". Но он не уходил, а ударил какого-то кролика, а потом еще одного. В UO нужно действовать быстро, ваншотнуть могут запросто. Я понял, что ситуация плохая и надо спасаться. Написал в чате "All attack", что типа значит приказ животным атаковать. Кролики тут же кинулись в атаку, окружив игрока. Да, кролики умирают с одного удара, но когда их перед тобой несколько слоев, быстро через них не пройдешь из-за КД. Я убежал от туда в зону города и охраны. Когда вернулся через какое-то время, все кролики были мертвы... Я еще немного попытался поиграть и восстановить популяцию кроликов, но так и не смог пережить тот момент... В конце концов просто забросил UO...

18
Ответить

Грустная история

2
Ответить

Спасибо за историю, даже захотелось её нарисовать в виде комикса. Если вдруг нарисую, вы не против?

Ответить

Мне кажется, что там такое легеси, которое не снилось другим конторам.

15
Ответить

Хе-хе я был там 3000 лет назад :)

4
Ответить