Управление HOF

Документация версии main@63ccaf8Исходник на GitHub

Перевод исходной страницы на английском языке для OmsiLaunch 0.1.0-beta4. Нормативной является английская страница: при расхождениях приоритет имеют английская страница и код.

OMSI читает файлы HOF (*.hof: пункты назначения, номера маршрутов и списки остановок, которые показывает IBIS/указатель маршрута транспортного средства) из каталога каждого транспортного средства. Управление HOF копирует файлы HOF в каталоги транспортных средств на время одного сеанса: карта или дополнение может поставлять HOF, нужные её маршрутам, а пользователь может использовать HOF одного транспортного средства на других, не изменяя ни одно транспортное средство навсегда. Эта страница — нормативный справочник в том виде, в каком управление HOF реализуют HofPlanner в src/OmsiLaunch.Core/HofPlanner.cs, поле HofManagement в LaunchSpec, флаги CLI /hof-source, /hof-target, /hof-file и /hof-mode и блок hofs профилей сеанса.

Стабильность: STABLE_BETA для планирования, правил конфликтов, ограничения путей и транзакционного восстановления (офлайн-гейты hof.plan-sources-and-modes, hof.plan-rejects-unsafe-input, hof.transaction-exact-restore, hof.recovery-after-crash, session-profiles.hofs). Проверено в runtime: сеанс с зеркалированием, точным восстановлением и восстановлением после аварийного завершения через /recover (см. статус проверки в runtime).

Управление HOF — не то же самое, что PlayerVehicle.Hof / /hof:<id>: этот параметр выбирает HOF транспортного средства игрока при запуске и в этой сборке имеет статус UNAVAILABLE.

Модель#

Запрос — это список операций (HofManagementSpec.Operations). Каждая HofOperationSpec содержит:

ПолеЗначение
SourceKind, SourceОткуда берутся файлы HOF (см. таблицу ниже).
TargetVehiclesОдно или несколько установленных транспортных средств: идентичность файла .bus или .ovh (Vehicles\MAN_SD200\MAN_SD77.bus) или каталог транспортного средства (Vehicles\MAN_SD200), в обоих случаях внутри Vehicles\. Несколько идентичностей в одном каталоге адресуют этот каталог один раз.
ModeAdd (по умолчанию): HOF источника копируются в каждый целевой каталог; другие HOF в нём остаются. Mirror: HOF источника копируются, а все остальные .hof целевого каталога на время сеанса удаляются, так что набор HOF каталога совпадает с набором источника.
FilesНеобязательный список имён файлов, которые берутся из источника (без учёта регистра). Если не указан — все *.hof непосредственно в источнике. Указанное имя, которого нет в источнике, даёт OL_E_HOF_SOURCE_NOT_FOUND.
SourceKindSourceРазрешается в
Collectionпростое имя, например berlin<root>\.omsilaunch\hof\<name>\*.hof: коллекция, которую ведёт пользователь или инструмент.
Directoryкаталог относительно установки, например maps\RMG Leste\hof*.hof в этом каталоге: HOF, поставляемые рядом с контентом карты или дополнения.
Vehicleидентичность или каталог транспортного средства, как для целей*.hof в каталоге этого транспортного средства: HOF одного транспортного средства используются на других.
Fileфайл .hof относительно установкиэтот единственный файл.

Используются только файлы, лежащие непосредственно в каталоге источника (без рекурсии). Символические ссылки и точки соединения (junction) никогда не отслеживаются (см. ограничение путей).

Что делает сеанс#

  1. Планирование (PlanSessionAsync, /plan). Каждая операция разрешается: источники читаются, цели проверяются, конфликты обнаруживаются. Каждый файл, который будет изменён, появляется в SessionPlan.PlannedMutations с SemanticKey hof.add или hof.mirror, RequestedValue = идентичность источника и Operation exact-file-overlay (записывается) или session-deletion (удаляется зеркалированием); пути входят в TouchedFiles. Проблема делает план неисполнимым с одним из кодов ниже.
  2. Запуск. После восстановления устаревшего журнала операции снова разрешаются по текущим файлам и передаются транзакции сеанса: записываемые файлы становятся overlay (временная замена файла на время сеанса), удаляемые зеркалированием файлы — удалениями на время сеанса. Целевой файл, байты которого уже совпадают с источником, не трогается и не становится записью транзакции.
  3. Завершение сеанса, сбой, аварийное завершение. Транзакция точно восстанавливает каждый целевой каталог: существовавшие файлы получают обратно исходные байты, метки времени и атрибуты; файлы, созданные сеансом, удаляются; удалённые зеркалированием файлы возвращаются. После аварийного завершения владельца то же восстановление выполняется при следующем запуске или через /recover (см. транзакции и восстановление после сбоя).

За пределами целевых каталогов ничего не записывается. Исходные файлы только читаются. Сеанс никогда не изменяет .omsilaunch\hof\.

Правила конфликтов#

Операции применяются по порядку и должны быть согласованы:

  • Две операции, записывающие один и тот же целевой файл одинаковыми байтами, объединяются; при разных байтах — OL_E_HOF_CONFLICT.
  • Зеркалирование, которое удалило бы файл, записываемый более ранней операцией, или операция, записывающая файл, удаляемый более ранним зеркалированием: OL_E_HOF_CONFLICT.
  • Зеркалирование охватывает набор HOF каталога на время сеанса: существующие файлы плюс файлы, которые туда записывают более ранние операции.
  • Цель HOF, которую также записывает оформление сеанса (заставка или интернет-текстуры (Internet Textures)): OL_E_HOF_CONFLICT (с текущими путями оформления, которые находятся вне Vehicles\, это невозможно).
  • Если в цели уже есть файл с тем же именем в другом регистре, сохраняется существующее написание.

Ограничение путей#

Каждый источник и каждая цель должны оставаться внутри установки: абсолютные пути, сегменты .. и пути, выходящие за корневой каталог, дают OL_E_HOF_PATH_ESCAPE; то же относится к целям (и источникам Vehicle) вне Vehicles\, к именам коллекций, которые не являются простым именем каталога, и к любому каталогу источника или цели, достигаемому через точку соединения (junction) или символическую ссылку. Файлы .hof, которые сами являются точками повторной обработки (reparse points), игнорируются.

Ограничения#

ОграничениеЗначениеОшибка
Размер одного файла HOF8 MiBOL_E_HOF_INVALID
Файлов на операцию256OL_E_HOF_INVALID
Всего байтов, записываемых за сеанс256 MiBOL_E_HOF_INVALID
Целей на операциюне менее 1OL_E_HOF_INVALID

Коды ошибок#

КодПричина
OL_E_HOF_SOURCE_NOT_FOUNDКоллекция, каталог, транспортное средство или файл не существует, не содержит ни одного .hof или в нём нет файла, указанного в Files.
OL_E_HOF_TARGET_NOT_FOUNDФайл или каталог целевого транспортного средства не существует.
OL_E_HOF_PATH_ESCAPEПуть выходит за пределы установки, цель находится не внутри Vehicles\, имя коллекции не является простым именем или путь проходит через junction/символическую ссылку.
OL_E_HOF_CONFLICTДве операции расходятся относительно одного целевого файла (см. правила конфликтов).
OL_E_HOF_INVALIDНет целей, нет источника, источник File не является .hof, цель — файл, отличный от .bus/.ovh, или превышено ограничение.

Использование#

Командная строка (одна операция; для нескольких операций нужен /spec или профиль сеанса):

OmsiLaunch.exe /new /map:maps\Grundorf\global.cfg /entrypoint-index:1 /hof-source:collection:berlin /hof-target:Vehicles\MAN_SD200\MAN_SD77.bus /plan
OmsiLaunch.exe /new /map:maps\Grundorf\global.cfg /entrypoint-index:1 /hof-source:vehicle:Vehicles\MAN_SD200\MAN_SD77.bus /hof-target:Vehicles\MAN_SD202 /hof-mode:mirror

LaunchSpec (JSON для /spec, перечисления в виде целых чисел):

{
  "HofManagement": {
    "Operations": [
      { "SourceKind": 1, "Source": "maps\\Grundorf\\hof", "TargetVehicles": [ "Vehicles\\MAN_SD200\\MAN_SD77.bus" ], "Mode": 0 },
      { "SourceKind": 0, "Source": "berlin", "TargetVehicles": [ "Vehicles\\MAN_SD202" ], "Mode": 1, "Files": [ "Linie5.hof" ] }
    ]
  }
}

Пресет профиля сеанса (источник package — это каталог внутри пакета профиля):

hofs:
  - package: hof
    targets:
      - Vehicles\MAN_SD200\MAN_SD77.bus
    mode: mirror

API: задайте LaunchSpec.HofManagement и вызовите PlanSessionAsync / StartSessionAsync как обычно; /list:Hofs (ContentQueryKind.Hofs) выводит список установленных файлов HOF.

См. также: LaunchSpec, профили сеанса, CLI, ошибки, транзакции и восстановление после сбоя.