11-=test

23.02.2026

Призрак «слитых кодов»: почему локализация ломается во всех эмуляторах

«Лирико-инженерная заметка о старой легенде, новых серверах и древнем баге, который путешествует между проектами как чемодан без ручки…»

Есть у админов MMO-серверов особая музыка. Не та, что в рейде под вайпы, а другая — тихий скрип табличек в базе данных, шелест дампов и тяжёлый вздох, когда очередной NPC снова улыбается тебе на английском.

Легенда и реальность

Многие верят, что причина всех бед — в «слитых кодах Blizzard». Но чаще всего за мистикой скрывается обычная ошибка индекса. Одинаковые шаблоны решения кочуют из ядра в ядро, превращаясь в одинаковые шаблоны проблем.

Один маленький индекс, который ломал ruRU

Финальная развязка оказалась классической: неправильный доступ к строке. Код пытался взять данные так, будто локали лежат в массиве строго по порядку. Для английского (0) это работало, но на русской локали (8) система «промахивалась».

Файл: GossipDef.cpp | БЫЛО (ОШИБКА)
// Ошибка: прямой доступ по индексу [8]
if (questGreeting->Greeting.size() > (locale))
strGreeting = questGreeting->Greeting[locale];
else
strGreeting = questGreeting->Greeting[DEFAULT_LOCALE];

Решение: Возвращение к здравому смыслу

Мы заставили сервер использовать стандартный механизм ядра ObjectMgr, который умеет правильно извлекать нужную локаль из контейнера.

Файл: GossipDef.cpp | СТАЛО (ФИКС)
LocaleConstant locale = _session->GetSessionDbLocaleIndex();
strGreeting = questGreeting->Greeting[DEFAULT_LOCALE];

if (locale != LOCALE_enUS)
ObjectMgr::GetLocaleString(questGreeting->Greeting, locale, strGreeting);

Итог

Когда «английские хвосты» снова полезут из всех щелей, не ищите заговор. Ищите источник. Quest Greeting, Gossip или BroadcastText? Как только вы найдете источник, у вас появится власть над сервером.