fix(ui): досчитать оставшиеся колонки по символам, через fmt (#3797) - #3802
Merged
Conversation
Продолжение правки после меню 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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Продолжение #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_scripts— 19 мест.Внумы от 100000 давно в ходу: 39 зон, больше тысячи предметов, самый большой в мире — 1002347. В пятизначном поле такая строка съезжает вправо и ломает колонку ровно так же, как русское имя.
Командный лог (
<имя> {комната} [команда],interpreter.cpp) не тронут намеренно: колонок там нет, а формат читают сторонние разборщики.И ещё:
%c— печать одного байта вместо символаПод UTF-8 русская буква в
charне влезает физически, так что%cпечатает только первый байт — до игрока доезжает обломок.Мест с
%cв движке 82, но почти все безобидны: служебные метки UID в триггерах (%c%ldсUID_CHAR), буквы флагов, коды команд зоны, разборsscanf, шестнадцатеричный дамп в логе. Реальных четыре, и все печатают пользовательский ввод:named_stuff.cpp— «Неверный параметр %c!» в ответ игроку;medit,redit,oedit—olc_log("%s command %c")пишет в лог букву, которую набрал билдер.Везде теперь печатается символ целиком: длина берётся у
native_text::char_bytes, сообщение игроку собираетfmt::format.