feat(utf8): cfg записывается в нативной кодировке (#3787) - #3794
Open
bylins wants to merge 2 commits into
Open
Conversation
Читать конфиги движок умеет в обеих кодировках: DataNode берёт файл через read_data_file, а from_disk_text считает валидный UTF-8 уже переведённым. Писал же он всегда в KOI8-R -- через native_text::to_disk и с encoding="koi8-r" в шапке. То есть любой файл, сохранённый через ведуна, возвращался в старую кодировку, и cfg никогда не сошёлся бы к одной: ровно та же history, что была у мира до #3792. Теперь запись -- зеркало чтения: XML пишется как есть, в UTF-8, и объявление в шапке говорит utf-8. Файлы, которые сейчас лежат в KOI8-R, читаются по-прежнему; первое же сохранение через ведуна переводит такой файл в UTF-8. Правка обязана ехать вместе со снятием working-tree-encoding с lib/cfg: пока атрибут стоит, git ждёт в рабочем дереве KOI8-R, и сохранённый ведуном UTF-8 попадёт в блоб перекодированным дважды. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH
Делает две вещи, обе идемпотентно: переводит содержимое из KOI8-R в UTF-8 (по той же логике, что и движок -- валидный UTF-8 считается уже переведённым) и правит объявление кодировки в шапке XML на utf-8. Второе нужно отдельно: объявление -- это содержимое файла, а не его кодировка, поэтому у трекаемых в git файлов оно не поменяется само собой при снятии working-tree-encoding. Проверено на копии lib/cfg: 64 файла переведены, 100 шапок поправлены, повторный прогон ничего не находит, а текст всех 140 файлов совпадает с исходным посимвольно (кроме самого объявления). 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.
Первый шаг перевода
lib/cfgна UTF-8 (#3787) — граница записи. Данные этот PR не трогает.Как сейчас
Чтение уже всеядно:
DataNodeберёт файл черезnative_text::read_data_file, аfrom_disk_textсчитает валидный UTF-8 уже переведённым, всё остальное — KOI8-R.А запись всегда переводила в KOI8-R:
То есть любой конфиг, сохранённый через ведуна, возвращался в старую кодировку. С этим
cfgникогда не сошёлся бы к одной — ровно та же история, что была у мира до #3792.Что сделано
Запись стала зеркалом чтения: XML пишется как есть, в UTF-8, объявление в шапке —
utf-8. Файлы, которые лежат в KOI8-R, читаются по-прежнему; первое сохранение через ведуна переводит такой файл в UTF-8.Порядок выката
Эта правка должна ехать вместе со снятием
working-tree-encodingс/lib/cfg/**. Пока атрибут стоит, git ждёт в рабочем дереве KOI8-R, и файл, сохранённый ведуном в UTF-8, приgit addперекодируется повторно — в блоб уедет каша. До снятия атрибута конфиги через ведуна лучше не править.Что дальше по данным (в этом PR не делается)
lib/cfgтрекается, 19 — нет (privilege.xml,shops.xml,daily_quest.xml,obj_sets.xml,guards.xml,celebrates.xml,cases.xml,craft/metacraft/*), их переводит только конвертация на диске.encoding="koi8-r"— это содержимое, а не кодировка, так что для трекаемых понадобится отдельный коммит с правкой объявления.Отдельно замечено
Шесть мест читают XML сырым
load_file()мимо границы кодировки:craft.cpp(4 раза — как разcraft/metacraft/*),sets_drop.cppиconfig.cpp. Сегодня они получают KOI8-байты как UTF-8; после перевода данных начнут читать правильно сами собой, но привести их кread_data_fileвсё равно стоит — отдельной правкой.Проверено
Сборка чистая, 669 тестов зелёные.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH
Инструкция по переезду
Порядок важен: пока движок пишет cfg в KOI8-R, любая правка через ведуна откатывает файл назад, а пока стоит
working-tree-encoding, git ждёт в рабочем дереве KOI8-R и портит блоб приgit add.Шаг 0. Выкатить движок
Влить этот PR и поставить новый бинарь. До этого конфиги через ведуна не править.
Шаг 1. Бэкап
Шаг 2. Снять атрибут (в репозитории движка)
Только
.gitattributes, через-- путь. Неgit commit -am: в этот момент git считает изменёнными все конфиги, и-aзаписал бы их в блобы в KOI8-R — так мы уже потеряли мир иcommands.hlp.Шаг 3. Перевыкачать трекаемые конфиги
Именно
git ls-files, а неrm -rf lib/cfg: 19 конфигов в git не опубликованы (privilege.xml,shops.xml,shop_item_sets.xml,daily_quest.xml,obj_sets.xml,guards.xml,celebrates.xml,cases.xml,animate_dead.*,craft/metacraft/*), иrm -rfснёс бы их без возврата.Без удаления не обойтись: git смотрит на mtime и размер и считает файлы неизменившимися, поэтому
git checkout -- lib/cfgсам по себе ничего не перезапишет.Шаг 4. Поправить шапки и перевести неопубликованные
Скрипт идемпотентен: содержимое переводит только у файлов в KOI8-R, объявление
encoding="koi8-r"правит везде, где оно есть. На трекаемых файлах после шага 3 остаётся только правка шапки, на неопубликованных — и то, и другое.Закоммитить шапки трекаемых файлов:
Шаг 5. Боевой сервер
Шаг 6. Проверка
И в игре:
ведуноткрыть любой конфиг, сохранить, затемfileна этот файл — должен остаться UTF-8, а в шапкеutf-8.Откат
Данные откатывать не нужно: чтение принимает обе кодировки (
from_disk_text). Если понадобится вернуть старый бинарь — он прочитает UTF-8-конфиги нормально, но при сохранении через ведуна переведёт файл обратно в KOI8-R.Что осталось за рамками
lib.template/cfg— ещё 28 файлов, тот же приём, отдельным заходом;lib/etc/board/**— доски пишет сам движок, там нужен разбор пути записи;load_file()мимо границы кодировки (craft.cpp,sets_drop.cpp,config.cpp).