Skip to content

fix(ui): досчитать оставшиеся колонки по символам, через fmt (#3797) - #3802

Merged
bylins merged 4 commits into
masterfrom
fix/utf8-column-width-rest
Aug 29, 2026
Merged

fix(ui): досчитать оставшиеся колонки по символам, через fmt (#3797)#3802
bylins merged 4 commits into
masterfrom
fix/utf8-column-width-rest

Conversation

@bylins

@bylins bylins commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Продолжение #3797 после меню OLC (#3798). Те же грабли: ширину поля задавал printf, а он меряет её в байтах — русский текст либо разъезжал столбец, либо резался посреди буквы.

Что разобрано

Игрокам:

  • im.cpp — список рецептов (%30s);
  • modify.cpp — список заклинаний (%30s).

Списки банов (ban.cpp): имя бога в графе «Banned By» (%-16.16s) и адрес (%-25.25s). Формат таблицы вынесен в константы kBanRow и kProxyRow, промежуточный char format[] и sprintf в общий buf больше не нужны — строки собираются fmt::format и сразу уходят в str_add.

Команды богов:

  • do_tabulate%60s под краткое имя предмета, шесть мест;
  • do_stat и dg_scripts — имена переменных триггеров;
  • do_show — названия направлений в списке входов и выходов зоны (%6s, а «северо-восток» это 13 символов).

Лог: mob_stat.cpp%13s под название профессии во множественном числе, столбцы в логе тоже разъезжались.

Что оставлено намеренно

  • do_toggle.cpp — 41 формат %-3s, но все под ON/OFF: ASCII, работает верно;
  • do_levels.cpp — ширины под числа с разделителями разрядов;
  • title.cpp%.*s, где байтовая длина как раз и нужна: печатается ровно один символ, и длина берётся у него же.

После этой правки в src не осталось ни одного формата с шириной, под который подставляется русский текст, — проверил проходом по всем .cpp.

Проверено

Сборка чистая, 673 теста зелёные, малый мир поднимается.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH


Заодно: внум в колонке — семь знаков

kMaxProtoNumber = 9999999, то есть внум семизначный, а поля под него стояли шириной пять. В sight.cpp это поправлено в #3786, но остальные места остались: show, stat, vnum, liblist, users, exits, «воззвать», dg_event и список триггеров в dg_scripts19 мест.

Внумы от 100000 давно в ходу: 39 зон, больше тысячи предметов, самый большой в мире — 1002347. В пятизначном поле такая строка съезжает вправо и ломает колонку ровно так же, как русское имя.

Командный лог (<имя> {комната} [команда], interpreter.cpp) не тронут намеренно: колонок там нет, а формат читают сторонние разборщики.


И ещё: %c — печать одного байта вместо символа

Под UTF-8 русская буква в char не влезает физически, так что %c печатает только первый байт — до игрока доезжает обломок.

Мест с %c в движке 82, но почти все безобидны: служебные метки UID в триггерах (%c%ld с UID_CHAR), буквы флагов, коды команд зоны, разбор sscanf, шестнадцатеричный дамп в логе. Реальных четыре, и все печатают пользовательский ввод:

  • named_stuff.cpp — «Неверный параметр %c!» в ответ игроку;
  • medit, redit, oeditolc_log("%s command %c") пишет в лог букву, которую набрал билдер.

Везде теперь печатается символ целиком: длина берётся у native_text::char_bytes, сообщение игроку собирает fmt::format.

bylins and others added 4 commits August 29, 2026 13:56
Продолжение правки после меню OLC. Те же грабли: ширина поля задавалась
printf-ом, а он меряет её в байтах, и русский текст ломал столбец -- либо
разъезжался, либо резался посреди буквы.

Разобраны все оставшиеся места с русским аргументом:

  * игрокам -- список рецептов (im.cpp) и список заклинаний (modify.cpp),
    оба через %30s;
  * списки банов -- имя бога в графе "Banned By" (%-16.16s) и адрес (%-25.25s);
    формат таблицы вынесен в константы kBanRow и kProxyRow, промежуточный
    char format[] больше не нужен;
  * команды богов -- vnum (%60s под краткое имя предмета), stat и show
    (направления выходов по-русски), имена переменных триггеров;
  * лог статистики по классам (mob_stat.cpp) -- там же, %13s под название
    профессии во множественном числе.

Ложные срабатывания разбора оставлены как есть: %-3s под ON/OFF в do_toggle,
ширины под числа в do_levels и %.*s в title.cpp, где байтовая длина как раз и
нужна -- печатается ровно один символ.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH
kMaxProtoNumber = 9999999, то есть внум семизначный, а поля под него были
шириной пять. В sight.cpp это уже поправлено (#3786), но там же остались
команды богов и всё остальное: show, stat, vnum, liblist, users, exits,
воззвать, dg_event и список триггеров в dg_scripts -- девятнадцать мест.

Внумы от 100000 уже в ходу (39 зон, больше тысячи предметов), самый большой в
мире -- 1002347. В пятизначном поле такая строка съезжает вправо и ломает
колонку.

Командный лог (<имя> {комната} [команда]) не тронут намеренно: там колонок нет,
а формат читают сторонние разборщики.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH
Пропустил при первом проходе: ПК-список (имя игрока в поле %20s),
список кланов по опыту (русская аббревиатура в %5s) и тип зоны в show
(%-20.20s). Везде ширину теперь считает fmt, то есть по символам.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH
Ещё один разрез того же класса: "%c". Под UTF-8 русская буква в char не
влезает физически, поэтому туда попадал только первый байт -- и до игрока
доезжал обломок.

Мест с "%c" в движке 82, но почти все безобидны: служебные метки UID в
триггерах, буквы флагов, коды команд зоны, разбор sscanf. Реальных четыре, и
все печатают пользовательский ввод:

  * named_stuff.cpp -- "Неверный параметр %c!" в ответ игроку;
  * medit, redit, oedit -- olc_log("%s command %c") пишет в лог букву,
    которую набрал билдер.

Везде теперь печатается символ целиком: длину берём у native_text::char_bytes,
сообщение игроку собирает fmt::format.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH
@bylins
bylins merged commit 26b7a09 into master Aug 29, 2026
20 checks passed
@bylins
bylins deleted the fix/utf8-column-width-rest branch August 29, 2026 12:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant