6

Ragnarok Online на Godot + Python, часть 4. Следствие ведут колобки⁠⁠

Серия Ragnarok Online
Шеф и Коллега выходят на след

Шеф и Коллега выходят на след

Добро пожаловать в детективное агентство «Лунный свет».

За две недели после прошлого поста к нам пришло больше двадцати жалоб. Монстры нападают без причины, чат пропадает, лучник не может откинуть моба, сервер тормозит. Пришлось поднимать журналы сервера, баг-репорты и скриншоты игроков.

Разбирался я с напарницей — нейросетью, которая пишет мне большую часть кода. Запомните её, она ещё всплывёт в материалах дела.

В любом следствии главное правило — не выйти на себя. Что ж, открываю первую папку.

Агентство на выезде: детектив и Moonlight Flower у ворот замка Гласт Хейма

Агентство на выезде: детектив и Moonlight Flower у ворот замка Гласт Хейма

Дело №1. Мировой чат, который не мировой

Обращение. «Мировой чат работает почему-то не на мир, а на локацию».

Улики. Игрок сидел с двумя окнами на разных картах (да, у нас не запрещено мультиоконить, особенно если ты — самый быстрый Джо в Rock Ridge). В одном писал в мировой чат, во втором себя не видел. Свидетель надёжный: он же и пострадавший, причём дважды.

Rock Ridge, родина самого быстрого Джо на Диком Западе. У нас он тоже скоро появится, следите за анонсами и новостями. Кадр из анонса iRO, Gravity / WarpPortal

Rock Ridge, родина самого быстрого Джо на Диком Западе. У нас он тоже скоро появится, следите за анонсами и новостями. Кадр из анонса iRO, Gravity / WarpPortal

Следствие. Сервер оказался чист: он рассылал «Мир» и «Торговлю» всем, на любую карту. А клиент показывал их только во вкладке «Мир» и не подсвечивал её. Кто сидел на «Общем», сообщения от мира не слышал.

Виновный. Мировой чат делала нейросеть. Она решила, что мировым сообщениям место в отдельной вкладке, и сдала работу с отчётом «сделано по заданию, тесты проходят». Тесты и правда проходили — они проверяли её же задумку. Поправили: мировые сообщения видны и в «Общем», с меткой [Мир].

Дело №2. Grand Peco, который напал первым

Обращение. «Моб атакует без причины на поле Юноны. Моба не трогал 100%».

Улики. Grand Peco мирный. Но у него есть особенность: в бою он навыком включает режим «берсерка», показывает грозную эмоцию и сам начинает нападать на всех игроков в зоне видимости. А потом, по данным rAthena, через какое-то время успокаивается.

Следствие. Злиться наш Grand Peco научился ещё в прошлой части, когда я хвастался, что все монстры пользуются своими навыками. Навыки переносила из rAthena нейросеть: злиться научила, а успокаиваться — нет. Стоило кому-то с ним подраться, и до самой смерти он кидался на всех прохожих. Заявитель действительно его не трогал. Трогал кто-то до него.

Виновный. Нейросеть, которая перенесла половину навыка и доложила, что весь. Автор прошлого поста ей поверил и похвастался. Grand Peco отпущен с извинениями, теперь он остывает. Заодно остыл Clock Tower Manager с той же болезнью.

Grand Peco в ярости. Теперь он хотя бы остывает

Grand Peco в ярости. Теперь он хотя бы остывает

Дело №3. Монстры, которые бросают танка

Обращение. «Моб мгновенно забывает о танке и бежит на дамагера. Если два ханта бьют с разных сторон, моб ни до кого так и не добежит».

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

Виновный. Опять нейросеть. Двух лучников в её тестах не было, а работу она сдала как готовую. Теперь выстрел издалека монстра с танка не снимает.

Из той же компании лучников пришло «Arrow Shower не откидывает мобов». Arrow Shower — это «Град стрел»: залп по площади, который отбрасывает монстров. Отбрасывал, но всех, кроме того, в которого целились. А когда стреляешь в одиночного монстра, он и есть цель, поэтому казалось, что не откидывает вовсе.

Танка нет, так что вся толпа честно бежит к лучнику

Танка нет, так что вся толпа честно бежит к лучнику

Дело №4. Монстры-статуи

Обращение. Баг-репорт игрока Raspad: стреляешь из лука с обрыва на полях Пайона, а монстры стоят и молча впитывают урон. Не обходят и не убегают.

Следствие. Монстр, которого ударили издалека, выбирал лучника целью и искал к нему дорогу. Дороги нет — цель сброшена, монстр снова стоит и думает. Следующая стрела прилетала раньше, чем он успевал додумать, и так до самой смерти.

Свидетель говорил, что монстр должен убегать за край экрана. Я поднял исходники rAthena: такого там нет. Там монстр, который не может дойти до стрелка, просто не берёт его целью и бродит дальше. А если случайно забредёт туда, откуда дорога есть, тогда и пойдёт к лучнику.

Развязка. Сделал так же. Безнаказанно расстреливать с обрыва больше не выйдет, но и убегать монстры не начали. Raspad, спасибо, протокол подшит.

Поля Пайона. Лучник на месте, монстры тоже

Поля Пайона. Лучник на месте, монстры тоже

Дело №5. Монстр, который сбегал из ловушки

Обращение. Охотник ставит «Капкан» (Ankle Snare), монстр попадается, получает первую стрелу и телепортируется. «Мобы, не имея скилла “телепорт”, телепортируются из трапов».

Следствие. У части монстров есть правило: если тебя бьют, а дойти до обидчика не можешь, телепортируйся. Наш сервер считал, что пойманный в ловушку не может дойти, и честно его отпускал.

Виновный. Снова нейросеть. Теперь пойманного, замороженного или усыплённого монстра можно расстреливать спокойно. В том же обращении было про «Воскрешение» (Resurrection): по нежити оно должно бить, как «Изгнание нежити» (Turn Undead). Починили, бьёт.

Капкан стоит, волк уже идёт. Теперь из капкана он никуда не денется

Капкан стоит, волк уже идёт. Теперь из капкана он никуда не денется

Дело №6. Бессмертный Geographer

Обращение. Geographer — это цветок, который лечит. Лечил он в том числе себя, и одиночного Geographer было не добить: бьёшь его, а он хилится.

Следствие. Условие этого навыка звучит как «у соседа мало HP». Сосед — это кто-то другой, а у нас соседом считался и он сам.

Развязка. Теперь лечит только других монстров в радиусе 8 клеток. Одиночку можно добить.

Два Geographer: лечат друг друга, а себя больше нет

Два Geographer: лечат друг друга, а себя больше нет

Дело №7. Наборы, которые ничего не давали

Обращение. Надел все части набора, а бонуса нет.

Следствие. Бонуса не давал ни один из 156 наборов. Вообще ни один. Предметы из rAthena нейросеть перенесла, а наборы забыла. И в отчёте о них ни слова.

Виновный. Нейросеть. Тут даже следствие не понадобилось. Все 156 наборов теперь работают: например, Pantie с Undershirt дают AGI +5 и FLEE +10, как и написано в описании.

Pantie и Undershirt вместе. Смотрите на AGI в окне статов

Pantie и Undershirt вместе. Смотрите на AGI в окне статов

Дело №8. Двойник

Обращение. Пришло от меня самого: «Могут ли люди через нейросеть посмотреть, как идёт трафик, и сделать на его базе ботов?» Клиент на Godot разбирается за вечер, так что ответ я знал заранее: могут. Вопрос был в том, что они после этого натворят.

Следствие. Я взял свой клиент и стал делать то, чего обычный игрок не может. Нашлось вот что:

  • Встаёшь у себя в Пронтере в ту же точку, где в Мороке стоит Kafra, и открываешь хранилище и телепорт Морока. Сервер сверял координаты, а карту нет.

  • Заходишь одним аккаунтом из двух окон одновременно, и в мире появляются два одинаковых персонажа. Один персонаж, две копии.

  • Ты продаёшь вещи, а напарник в этот момент поднимает добычу, которая делится на группу. Проданная стопка могла вернуться обратно в сумку. Классический дюп.

  • На сайте после трёх неверных паролей просят капчу, а в игре пароли можно было перебирать сколько угодно.

Развязка. NPC теперь отвечают только на своей карте. Второе окно получает «С этого аккаунта уже играют в другом окне». Если две записи в инвентарь пришли одновременно, вторая отменяется целиком. После пяти неверных паролей вход в игре встаёт на паузу на 15 минут. Двойник арестован.

Второе окно больше не пускают: двойник задержан на входе

Второе окно больше не пускают: двойник задержан на входе

Дело №9. Кто тормозит сервер

Обращение. Игрок жалуется на подлагивания. Не постоянные, а иногда.

Улики. У сервера есть сторож — маленькая программка. Если мир замирает дольше чем на 200 мс, сторож пишет в журнал, чем сервер в этот момент был занят. На этот раз он показал на вход через Google. Пока сервер ждал ответа от Google, он не обрабатывал вообще никого. Обычно 0,4 секунды, а при медленном ответе до 15.

Виновный. Не Google. Нейросеть спрашивала его прямо в игровом цикле. На тестах такое не ловится: там никто не ждёт ответа от настоящего Google. Теперь проверка идёт в отдельном потоке, и чужой вход больше никому не мешает.

Похожее дело было в начале месяца, всплыло на том же допросе двойника. Мой клиент слал сотни кликов по земле в секунду, сервер на каждый клик искал путь, и игра замирала у всех. Двести кликов в секунду съедали две секунды процессора в секунду. Теперь путь по клику считается не чаще десяти раз в секунду, и тот же поток обходится серверу в 0,15 секунды вместо двух.

Так сторож отмечает в журнале каждый момент, когда мир замер

Так сторож отмечает в журнале каждый момент, когда мир замер

Дело №10. Тихий вечер

Обращение. Вечер 3 ноября. Игроки пишут, что не могут зайти: клиент подключается и висит.

Улики. Игровой сервер работает, а база данных молчит. Диск на виртуалке заполнен на 100 %.

Следствие. Каждый релиз копировал на сервер исходники и базу для патчей, по 2–6 ГБ за раз, и никто за ним не убирал. Набралось больше 50 ГБ старых релизов, ещё 30 ГБ бэкапов, и очередная сборка забила диск до конца.

Виновный. Скрипт сборки. Кто его писал, уточнять не буду. Старые копии удалил, свободно стало 74 ГБ, а сборка теперь отказывается запускаться, если свободно меньше 15 ГБ.

Диск сегодня: занят на 73 %. Вечером 3 ноября было 100 %

Диск сегодня: занят на 73 %. Вечером 3 ноября было 100 %

Дело №11. Подозреваемый, который не спит

Одно дело пока не закрыто. Пришла жалоба: персонаж качается сам, а когда рядом кто-то появляется, перестаёт бить монстров.

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

Но улики косвенные. Это может быть и забытая на втором компьютере игра с плохим интернетом. Приговор пока не вынесен. Зато за ботами теперь присматривает сам сервер, и наш подозреваемый уже на самом дне (рейтинга ботов). Выбираться оттуда ему придётся очень долго. Если читаешь это, подозреваемый, оправдаться просто: напиши в комментариях, сколько колобков на обложке. Бот на такой вопрос ответить не сможет.

Проверка «Вы здесь?»: человек нажмёт морковку, программа задумается

Проверка «Вы здесь?»: человек нажмёт морковку, программа задумается

Дело №12. Письма, которые не доходят

Это дело тоже висяк. Письмо с подтверждением почты не доходит до адресов Microsoft: hotmail, outlook, live. Наш почтовый сервер стоит в диапазоне адресов, который Microsoft заблокировал целиком, и снять блок пока не получилось. Если регистрируетесь, возьмите другую почту: Яндекс и Gmail доходят.

Так Microsoft отвечает на наши письма. Адрес сервера скрыт

Так Microsoft отвечает на наши письма. Адрес сервера скрыт

Главное дело. Кто выгоняет игроков из игры

Обращение. Его никто не подавал. Все привыкли.

Улики. Каждое обновление сервера шло по одному сценарию. За 10 минут в чат приходит «Внимание! Сервер будет перезагружен». Все бросают охоту и выходят. Сервер останавливается, запускается заново и грузит мир: карты, монстров, NPC, квесты. Пауза от 15 до 23 секунд. Потом все заходят обратно, а друзья получают пачку «вышел из игры» и «вошёл в игру».

Главная улика — обновление 0.635. Игрокам пообещали выкладку с 12 до 13. Потом «около 12:45». Потом «13:10–13:20». Потом «13:30–13:35». Патч клиента собирался целый час, и всё это время люди сидели и ждали, когда их выгонят.

Новые фичи у меня появляются по несколько в день, но на сервер они уезжают пачкой. Обычно выкладка одна в день, иногда раз в несколько дней, а две — только если что-то срочное. С 1 по 13 ноября выкладок было десять. Каждая — это десять минут ожидания для всех, кто в игре.

Виновный. Подпись под каждым объявлением: администрация. Администрация — это я. С позволения нейросети, конечно.

На этот раз отпустить себя с извинениями было мало. Идея была такая: поставить перед сервером nginx и запускать новую версию рядом со старой. Новая принимает у старой всех игроков, nginx переключает на неё трафик, а старую гасим.

Схема эстафеты

Схема эстафеты

Разгадка была в тех самых 15–23 секундах. Почти всё это время сервер не сохранял игроков, а грузил мир. Если новая версия загрузит мир заранее, пока старая ещё работает, ждать никому не придётся. Останется только передать игроков из рук в руки.

  • Сервер теперь живёт в docker-контейнере. Обновиться — собрать новый образ, откатиться — запустить старый.

  • Новая версия запускается рядом и грузит мир. Игроки играют на старой.

  • Старая закрывает ворота: пакеты от игроков больше не принимаются, мир останавливается, чтобы между сохранением и передачей ничего не изменилось. Потом она сохраняет всех и закрывает соединения с особым кодом «переезд».

  • Клиент знает этот код. Вместо «Соединение прервано» он через 0,3 секунды переподключается с одноразовым ключом и оказывается на том же месте.

  • Если новая версия не приняла игроков за 30 секунд, всё возвращается к старой, будто ничего не было. Ещё 10 минут старая ждёт в запасе на случай отката.

Сначала проверяли на стенде. На одной машине два контейнера с сервером, nginx перед ними и боты, которые подключаются по тому же протоколу, что и настоящий клиент. С шестью ботами старый сервер сдавал всех за 0,06–0,08 секунды, а через 0,3–0,7 секунды все были снова в мире. Даже бот, который как раз заходил в дом.

Шесть ботов — несерьёзно. Поэтому я попросил: «Протестируй на 50 игроках в разных позициях». Нейросеть расставила 50 ботов по случайным клеткам на четырёх картах: 30 на поле у Пронтеры, 10 в самой Пронтере, 6 в Альберте и 4 в Излюде. Ещё один сидел на выборе персонажа. Каждый второй во время эстафеты куда-то шёл. Результат:

  • вернулись все 51: пятьдесят в мир, один в лобби;

  • каждый оказался ровно там, где его отключили, клетка в клетку. Кто шёл, вернулся посреди шага;

  • старый сервер сдал 51 игрока за 0,49 секунды;

  • перерыв у игроков в мире вырос до 1,8–2,0 секунды, у игрока в лобби — 0,76. При пяти игроках было 0,65.

Больше всего тормозил новый сервер: за эстафету он брался только через 0,4 секунды после того, как старый всех отдал. Две секунды — это уже не «моргнул и не заметил»: надпись «Сервер обновляется» на полсекунды всё-таки мелькнёт. Но это при пятидесяти, а у нас пока пик двенадцать. Когда дорастём до пятидесяти, тогда и буду ускорять.

Что всплыло на допросе

При эстафете старый сервер передаёт игроков новому. Всё, что лежит в базе, новый прочитает сам. А то, что старый держал только у себя в памяти, при передаче пропало бы. Пришлось выписать всё это поштучно. И тут вылезли старые баги, которых раньше никто не замечал:

  • вещи на земле исчезали при каждом перезапуске. Теперь переезжают на то же место, с оставшимся временем и правом поднять первым;

  • перезарядка умений сбрасывалась, если выйти и зайти. Теперь сохраняется, как в оригинале;

  • HP и SP сохранялись только в бою. После перезапуска персонаж мог вернуться с тем здоровьем, что было после последней драки;

  • «Лавка закрыта, непроданное вернулось» терялось, если сервер перезапускался раньше, чем торговец заходил в игру.

Монстров я не передаю: они появляются заново, как после рестарта на официальных серверах. Ещё закрываются диалог с NPC, обмен и склад. Всё остальное остаётся: карта, открытые окна, группа, баффы.

Друзьям при переезде больше не приходит «вышел» и «вошёл», а сообщение дня не показывается второй раз. Надпись «Сервер обновляется» появляется, только если возврат затянулся дольше полутора секунд. Если обновление застало на выборе персонажа, пароль вводить не нужно. Приложение на телефоне тоже переживает переезд.

Приложение во время обновления сервера

Приложение во время обновления сервера

Одну улику журналы не показали. По ним эстафета на стенде прошла идеально. А я зашёл в живой клиент и увидел, как мелькнул экран загрузки и меня «швырнуло» на ту же карту: клиент строил мир с нуля, как при входе. Теперь карта, интерфейс и персонаж остаются, а заново приходят только соседи и монстры. Так что в клиент заходить самому всё равно надо.

А раз сервер больше никого не выгоняет, то и новый клиент не повод выгонять. Теперь приходит окно «Вышло обновление клиента» с кнопками «Обновить сейчас» и «Играть дальше». Когда обновляться, решаете вы.

Окно нового клиента

Окно нового клиента

Попутно закрыл ещё одно дело с форума: «Почему папка с патчами только растёт?» Клиент хранил старые пакеты рядом с текущей версией. Теперь не хранит, и папка худеет примерно с 1,85 до 0,9 ГБ.

Следственный эксперимент

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

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

Оповещение после выкладки. Имена статистов вымышленные

Оповещение после выкладки. Имена статистов вымышленные

Одна шероховатость всё же была: пока новая версия загружала таймеры боссов, мир дважды подвис примерно на 0,28 секунды. Это следующее дело в очереди.

Соучастник

Про напарницу я уже говорил. В главном деле она получила от меня фразу: «Продумай, как мы бы могли деплоить сервер так, чтобы состояние оставалось таким же?» и дальше про nginx и два сервера. Потом вторую: «Напиши полный подробный план. Потом найди несоответствия».

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

Опись изъятого за две недели

В прошлом посте я обещал три вещи. Отчитываюсь.

Остальные вторые профессии. Открыты все тринадцать: к пяти прежним добавились Рыцарь, Крестоносец, Монах, Разбойник, Мудрец, Бард, Танцовщица и Алхимик с гомункулом. У каждой экзамен по оригинальному сценарию. У Мудреца работает Abracadabra со всеми особыми исходами: можно превратить монстра в Поринга или в случайного босса, а можно умереть самому. Как в оригинале, не я придумал.

Все вторые профессии на сайте

Все вторые профессии на сайте

Новые города и подземелья. Горы Мьёльнир и Альдебаран с Часовой башней, Гласт Хейм, Лютия, Черепаший остров, Юнона, Комодо с казино, Умбала и Нифльхейм. Гласт Хейм под прошлым постом я обещал «скоро» — через четыре дня он был готов целиком. Подземелья для своей группы: Orc's Memory, Sealed Shrine и Endless Tower на сто этажей. И Глубины у Пайонской пещеры: подземелье без дна, куда спускаются только ногами.

Нифльхейм. Живых здесь не ждут

Нифльхейм. Живых здесь не ждут

Первый этаж Endless Tower. Осталось девяносто девять

Первый этаж Endless Tower. Осталось девяносто девять

Гильдии. Есть: Emperium, название, до 16 человек, свой чат и склад на 600 ячеек. Окна гильдии, рангов и эмблемы пока нет, это следующий шаг.

Распорядитель гильдий у фонтана Пронтеры

Распорядитель гильдий у фонтана Пронтеры

Ещё появились титулы, достижения, общий чат на весь сервер и скупка на аукционе. Цифры с прошлого поста:

  • пик онлайна был 7 человек, стал 12;

  • версия игры была 0.511, сейчас 0.650, это 139 версий;

  • локаций было 122, стало 264;

  • видов монстров на картах было 186, стало 294;

  • автотестов было около 5 400, стало около 7 100;

  • строк кода на Python было 138 тысяч, стало 198, на GDScript было 100 тысяч, стало 120, на Lua было 33 тысячи, стало 68.

Дело закрыто

В делах о чате, о Grand Peco, о танке, о ловушке, о наборах и о тормозах код писала нейросеть. Google просто стоял рядом. И каждый раз работа сдавалась с одним и тем же отчётом: сделано по заданию, тесты написаны, тесты проходят.

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

Значит, и отвечать за отчёт ей. Тест, который проверяет только то, что код и так делает, — алиби для галочки. Не проверила — так и скажи. А на главном деле я сделал по-другому: сначала план, потом сверка с кодом, стенд с ботами и уже потом прод. И пятеро игроков обновления даже не заметили.

Правило следователя я, кстати, соблюл: на себя не вышел. А вот напарница выходила на себя в каждом деле, и это у неё не впервые. Есть у нас одно архивное дело. Скрипт нейросети ждал, когда закончится сборка обновления, и искал процесс сборки по названию. Сборка давно закончилась, а скрипт ещё полчаса докладывал «идёт». Он находил сам себя: в его собственной командной строке было то же название. Чем кончается следствие, если копать слишком глубоко, она теперь знает. Выходишь на себя.

Если у вас были похожие расследования, где виновным оказался автор кода, расскажите в комментариях. Напарнице будет не так одиноко.

Сайт игры: zeroro.ru, форум: forum.zeroro.ru

Поринги передают привет. У них алиби.

1
Бес Сахара
Автор поста оценил этот комментарий

Хм. Вспомнить чтоль детство =\

раскрыть ветку

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества