Страница 1 из 1

О происхождении глюков (почти по Дарвину)

Добавлено: 09 апр 2018, 12:33
Gorlum
Я вам расскажу небольшую историю одного глюка. История относительно небольшая, но весьма долгая, более чем 10-летней давности, хотя глюк проявился в новейшем (!) коде ОвК

Итак, в один совсем не прекрасный момент я ВДРУГ обнаружил, что по какой-то причине в Статистике появились игроки-боты ивента "Объекты в космосе".
Сказать, что я был удивлён - это было не сказать ничего! Даже в первый момент было непонятно - откуда они там взялись и что нужно искать. Потому что несколько дней всё было нормально и Статистика работала отлично. А по построению ботов ОвК физически не должно быть в статистике! Приглядевшись внимательно, я увидел, что ботов выбило в стату из-за того, что статистика почему-то решила посчитать им строения (100 уровней Базы Альянса - столько нужно по техническим причинам, что бы не лепить специальные исключения в коде).

Тут нужно сделать отступления и объяснить один момент, очень важный для последующего рассказа. Для того, что бы боты не участвовали в статистике, рекордах итд, их ИД помещаются в специальную запись конфигурации: stats_hide_player_list. В БД она хранится как строка (список ИД, разделенных запятой), а в коде PHP несложными процедурами превращается в массив для удобства использования. В ходе этого превращения происходит валидизация - убираются пустые ИД, убираются записи, которые не могут быть ИД, проверяется наличие таких игроков в базе. В общем - в код после процедуры валидизации данные попадают в самом что ни на есть корректном виде.

Еще один нюанс, тоже важный для понимания: ЧЛ вместе с ОвК использует этот список для хранения списка ботов. Кроме того, там есть и отдельные служебные записи, которые нужны мне для чего-нибудь.

Но - вернемся к нашим баранам. Сначала я подумал самое очевидное, но и самое невероятное - глюкнула система статы. С одной стороны - не должна, поскольку ж как-то несколько дней она проработала нормально в Фестивале, да и до этого жалоб не было. Однако, надо быть последовательным. Я проверил систему обсчёта статы и почти сразу же увидел странную фигню - часть ботов в списке на скрытие просто отсутствовала!

Следующий шаг - проверить их наличие в БД. Удивительно - но они отсутствовали и там! Автоматически возникла мысль - может их обрезает БД? Такое уже было в ходе одного из ивентов, когда поле для хранения накопленных данных оказалось слишком коротким и поэтому похерился прогресс одного из ивентов. Но я отчётливо помнил, что тогда же я увеличил длину поля в БД заведомо с резервом! На всякий случай я проверил - нет, поле было очень длинным и его хватало с многократным запасом для хранения хоть всего списка игроков в любой кодировке.

Тут я слегка охренел. По всем раскладам получалось, что из базы просто исчезла часть данных. При чём исчезла не полностью - а кусочком! В принципе, варианты были - но все очень нехорошие и сложные в диагностика. Начиная от взлома и заканчивая сбоем в хранении БД. Эти варианты я решил оставить на крайний случай, а пока тщательно проверить использование переменной - ведь если исключить нехорошее, то обрезаться она могла только при записи в БД. Количество таких мест в игре велико, но ограничено. Да и всё равно больше ничего не оставалось. Я, конечно, параноик, но подозревать в любом сбое хак или системный сбой нерационально. Обычно ошибки имеют более тривиальные корни, хотя несколько раз в истории СН было и обратное.

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

А надо сказать, что все тесты необходимо было проделать на живом сервере Альфа. Потому что ни на Гамме, ни на Бете, ни на Дельте, ни, тем более, на локальном сервере проблемы не было - всё работало как часы! Т.е. это отдельный такой прикол - отлаживать код на живом сервере так, что бы это оказало минимальное влияние на живую игру. Когда я вчера отлаживал тики ОвК, которые ВНЕЗАПНО пошли вразнос удалось спрятать лишь отладку, а вот по остальной игре колбасило сроки постройки и длину очередей. Само собой, тики работали на локальной машине безупречно. Кстати, причину рассинхронизации я точно не нашёл и просто переписал алгоритм на более времяёмкий, но более устойчивый.

Ух. Я уже затянул историю, хотя это всего один мелкий (!) баг - как выяснилось в последствии. В общем, перейду сразу к развязке.

Оказалось, что все эти проблемы вызваны тем, что когда-то, давным-давно в админке в интерфейсе настройки сервера длина поля ввода для списка игроков к скрытию была ограничена 254 символами! При чём, если я правильно помню, это было еще до меня, в том движке, который был использован как база для SN!

Почему не получилось найти это раньше и почему оно не оказывало до этого влияния на игру?
- Раньше это не проявлалось, потому что список игроков не был таким длинным;
- А не был он таким длинным, потому что не было одновременно двух ивентов, которые использовали это поле;
- А на остальных серверах и локальной машине баг не проявлялся, потому что там было меньше активных игроков и, соответственно, меньше ЧЛ и ОвК и, как следствие, меньше ботов.

Вот так решение, принятое 10+ лет назад неизвестным программистом по непонятным причинам может быть пропущено при тщательном тестировании и ВНЕЗАПНО испортить новейший ивент, который уже отработал несколько дней.

Кстати, остался еще открытым вопрос - если всё так, как я сказал - почему несколько дней ивент работал нормально? А вот тут очень интересный момент. Баг возникает только когда при соблюдении всех остальных условий нажимается кнопка "сохранить" в настройках сервера. При этом даже не обязательно что-то менять в этом поле или даже видеть его на экране! Просто - сохранить изменения. И я этого не делал с момента запуска ивента, а сделал только вчера, когда по-живому отлаживал ивент ОвК!
И более того - эти проблемы вылезли не сразу, а лишь после ночного обсчёта статистики! Поэтому увязать сохранение настроек с багом удалось далеко не сразу (это было в опущенной части описания квеста по поиску бага)

Вот такая хуйня, малята...