LaunchSpec 参考

文档版本 v0.1.0-beta.3在 GitHub 上查看源文件

本页是 OmsiLaunch 0.1.0-beta3 英文原始页面 的译文。英文页面为规范文本:如有出入,以英文页面和代码为准。

本页是 LaunchSpec 的规范性参考。LaunchSpec 是描述单个 OmsiLaunch 会话的请求记录。本页说明:它的 C# 结构(OmsiLaunch.Api);CLI 加载的 JSON 文件形式(/spec:<path>,tools/OmsiLaunch.Cli/LaunchSpecJson.cs);每个属性的类型、默认值、校验规则和当前效果;使计划不可运行的校验规则;以及 CLI 参数、spec 文件和会话配置档之间的优先级。本页只记录当前代码实际执行的行为。

相关页面:公共 API、CLI 参考、会话配置档、错误码、会话生命周期、能力。

LaunchSpec 的来源#

来源如何成为 LaunchSpec
API集成方构造该记录并将其传给 PlanSessionAsync。
CLI 参数CliInput.BuildSpecAsync 从内置默认值(NEW_MAP、所有项均未设置、Behavior 默认值)开始,再应用各参数。
/spec:<path> JSON 文件由 LaunchSpecJson.LoadAsync 加载,然后作为种子,由 CLI 参数覆盖(参见优先级)。
会话配置档(/predefined-profile:<id> /predefined-profile-index:<n>)SessionProfileCompiler.Apply 将配置档的世界、设置项、呈现、网络纹理和行为写入种子,并记录 SessionProfile 元数据。

下文的完整示例已针对记录结构进行核对。最小示例的副本以 examples/release-session.example.json 提供(在发行包中为 .omsilaunch\examples\release-session.example.json)。

JSON 形式#

规则详情
序列化器System.Text.Json,使用 PropertyNameCaseInsensitive = true、ReadCommentHandling = Skip、AllowTrailingCommas = true;未注册任何转换器。
属性名即 C# 属性名(Installation、RootPath 等)。加载时匹配不区分大小写;CLI 写出时使用 PascalCase。
枚举整数(没有字符串枚举转换器)。"Mode": 0 有效;"Mode": "NewMap" 会被当作格式错误的 JSON 拒绝。取值列于枚举。
OptionalValue<T>一个对象 { "Presence": 0 | 1, "Value": <T or null> }。Presence 为 0 表示 Unset(值被忽略),为 1 表示 Set(值必须存在且非 null;Set 而值为 null 的情况不会被校验,其行为等同于无效值)。省略的 OptionalValue 成员即为 Unset。只读成员 IsSet 会出现在 CLI 写出的输出中,加载时被接受并忽略。
可选记录Year、Weather、Input、Diagnostics、Presentation、InternetTextures、SessionProfile 可以为 null 或省略;Effective* 访问器会以默认值替代。
必需记录Installation、World、Date、Time、Environment(须包含全部八个字典,空时使用 {})、Behavior 必须是存在的对象。它们不会被校验:为 null 或缺失时,会在后续因空引用而失败,CLI 将其报告为 OL_E_INTERNAL(exit 10)或 OL_E_INVALID_ARGUMENT(exit 2)。
未知属性在绑定之前即被拒绝:OL_E_SPEC_UNKNOWN_PROPERTY: $.Path.Name(路径使用文件中所写的成员名)。字典内容(Environment.*)不作为属性检查。
根节点必须是 JSON 对象,否则为 OL_E_SPEC_INVALID。最大嵌套深度为 32。
文件大小最多 1 MiB(1 048 576 字节),否则为 OL_E_SPEC_TOO_LARGE。文件不存在:OL_E_SPEC_NOT_FOUND。
注释和尾随逗号接受 // 和 /* */ 注释以及尾随逗号。
格式错误的 JSON解析器异常不会被转换:CLI 报告 OL_E_INTERNAL,退出码为 10。
编码UTF-8(读取器可容忍 BOM)。标识中的反斜杠必须转义("maps\\Grundorf\\global.cfg");地图、情景、车辆和 HOF 标识也接受正斜杠。

完整示例#

{
  // Comments and trailing commas are accepted. Enums are integers.
  "Installation": {
    "RootPath": ".",                          // "." = directory that contains OmsiLaunch.exe (CLI only)
    "ExpectedExecutableSha256": null          // carried, not consumed
  },
  "World": {
    "Mode": 0,                                // 0 NewMap, 1 SavedSituation, 2 LastMapState (unavailable)
    "MapIdentity": { "Presence": 1, "Value": "maps\\Grundorf\\global.cfg" },
    "SituationIdentity": { "Presence": 0, "Value": null },
    "PresentedEntrypointIndex": { "Presence": 1, "Value": 1 },
    "EntrypointIdentity": { "Presence": 0, "Value": null }
  },
  "Date": { "Mode": 0, "Value": { "Presence": 0, "Value": null } },
  "Time": { "Mode": 0, "Value": { "Presence": 0, "Value": null } },
  "Year": null,
  "Weather": null,
  "PlayerVehicle": { "Presence": 0, "Value": null },
  "Environment": {
    "General": {
      "traffic.randomVehicles": { "Presence": 1, "Value": "150" },
      "graphics.maxFPS": { "Presence": 1, "Value": "60" }
    },
    "Advanced": {}, "Graphics": {}, "AdvancedGraphics": {},
    "Sound": {}, "AiPassengers": {}, "Keyboard": {}, "Controllers": {}
  },
  "Behavior": {
    "RestoreConfiguration": true,             // carried, restore always happens
    "SuppressStaleClosecheckWarning": true,
    "StartupTimeoutSeconds": 180,             // 1..600
    "ShutdownTimeoutSeconds": 30              // carried, not consumed
  },
  "Input": null,
  "Diagnostics": null,
  "Presentation": {
    "Splash": 1,                              // 0 Unset/Native (keep OMSI files), 1 Managed
    "Language": { "Presence": 0, "Value": null },
    "CustomAssetDirectory": { "Presence": 0, "Value": null },
    "SuppressTrayIcon": false
  },
  "InternetTextures": {
    "Mode": 0,                                // 0 Native, 1 Disabled, 2 Override
    "OverrideProfilePath": { "Presence": 0, "Value": null }
  },
  "SessionProfile": null
}

在版本(build)支持的情况下,显式日期写作 "Date": { "Mode": 1, "Value": { "Presence": 1, "Value": { "Year": 2024, "Month": 5, "Day": 1 } } },时间写作 { "Mode": 1, "Value": { "Presence": 1, "Value": { "Hour": 7, "Minute": 30, "Second": 0 } } }。在当前版本(build)上,两者都会使计划不可运行(见下文)。

属性参考#

“使用情况”列说明当前代码如何处理该值。稳定性采用公共 API 页面的术语。

LaunchSpec(根)#

属性JSON 类型必需省略时的默认值使用情况稳定性
InstallationInstallationSpec 对象是无是STABLE_BETA
WorldWorldSpec 对象是无是STABLE_BETA
DateDateSpec 对象是无会被校验;除 Unset 外的任何模式均不可运行PARTIAL
TimeTimeSpec 对象是无会被校验;除 Unset 外的任何模式均不可运行PARTIAL
PlayerVehicleOptionalValue<PlayerVehicleSpec>否Unset为诊断信息而解析;设置任何字段均不可运行PARTIAL
EnvironmentEnvironmentSpec 对象是无是(语义化的 options.cfg 覆盖层)STABLE_BETA
BehaviorLaunchBehaviorSpec 对象是无部分使用(参见该记录)STABLE_BETA / PARTIAL
YearYearSpec 对象或 null否null → EffectiveYear = 模式 Unset除 Unset 外的任何模式均不可运行PARTIAL
WeatherWeatherSpec 对象或 null否null → EffectiveWeather = 模式 Unset除 Unset 外的任何模式均不可运行PARTIAL
InputInputSpec 对象或 null否null → EffectiveInput = 两者均未设置设置任何文档均不可运行PARTIAL
DiagnosticsDiagnosticsSpec 对象或 null否null → EffectiveDiagnostics = 默认值仅携带PARTIAL
PresentationSessionPresentationSpec 对象或 null否null → EffectivePresentation = 托管启动画面、无语言、无自定义目录、显示托盘是STABLE_BETA
InternetTexturesInternetTexturesSpec 对象或 null否null → EffectiveInternetTextures = Native是STABLE_BETA / EXPERIMENTAL
SessionProfileSessionProfileMetadata 对象或 null否null仅用于来源记录(session_profile.selected 计划诊断信息)STABLE_BETA

只读访问器(出现在 CLI 的 JSON 输出中,加载时被忽略):EffectiveYear、EffectiveWeather、EffectiveInput、EffectiveDiagnostics、EffectivePresentation、EffectiveInternetTextures。

InstallationSpec#

属性类型默认值有效值使用情况稳定性
RootPathstring必需包含 Omsi.exe 和 plugins\ 的目录。参见路径规则。为空或仅含空白 → OL_E_INSTALLATION_NOT_FOUND。是STABLE_BETA
ExpectedExecutableSha256string 或 nullnull任意字符串。当前代码中没有使用方:主机总是对 Omsi.exe 计算哈希并与构建配置比较,从不与此值比较。PARTIAL(仅携带,当前无效果)

WorldSpec#

属性类型默认值有效值使用情况稳定性
ModeWorldMode int必需0 NewMap、1 SavedSituation、2 LastMapState(LastSituation 是值同为 2 的已过时别名)。是;LastMapState → OL_E_CAPABILITY_UNAVAILABLENewMap、SavedSituation:STABLE_BETA;LastMapState:UNAVAILABLE
MapIdentityOptionalValue<string>Unset对于 NewMap:必需,形式为 maps\<dir>\global.cfg(不区分大小写,接受 /,不得含 ..),且必须已安装。对于 SavedSituation 被忽略(地图由 .osn 提供)。是(交接)STABLE_BETA
SituationIdentityOptionalValue<string>Unset对于 SavedSituation:必需,为已安装的 situations\...\<file>.osn 标识(即 DiscoverAsync(Situations) / /list:situations 返回的标识)。是(交接)STABLE_BETA
PresentedEntrypointIndexOptionalValue<int>Unset对于未设置 EntrypointIdentity 的 NewMap:必需,>= 0,是该地图在 OMSI 所呈现的入口点列表中的索引。未设置时以 -1 发送给插件。是(交接)STABLE_BETA
EntrypointIdentityOptionalValue<string>Unset原始入口点标签或发现标识。设置它会使计划不可运行(world.entrypoint-identity、RUNTIME_PARTIAL、OL_E_CAPABILITY_UNAVAILABLE)。仅携带PARTIAL
EntrypointEntrypointSpec(只读)计算得出设置了 EntrypointIdentity 时 Mode = Identity,否则设置了索引时为 PresentedIndex,否则为 Unset;PresentedIndex、Identity 与输入一致。派生STABLE_BETA

DateSpec、TimeSpec、YearSpec#

属性类型默认值有效值使用情况稳定性
ModeDateTimeMode int必需(Year:记录为 null 时为 0)0 Unset、1 Explicit、2 System。Explicit/System → unsupported 条目(world.explicit-date、world.explicit-time、world.explicit-year,STATICALLY_PARTIAL)以及 OL_E_CAPABILITY_UNAVAILABLE。这些模式也会被复制到启动交接中,模式不为 Unset 时插件会拒绝(由于计划不可运行,实际不会执行到这一步)。PARTIAL
ValueOptionalValue<SemanticDate> / OptionalValue<SemanticTime> / OptionalValue<int>UnsetSemanticDate:Year、Month 1..12、Day 1..31;SemanticTime:Hour 0..23、Minute 0..59、Second 0..59。Mode 为 Explicit 时必须设置(否则为 OL_E_DATE_TIME_APPLY_FAILED),Mode 不为 Explicit 时必须不设置(否则为 OL_E_INVALID_ARGUMENT)。YearSpec.Value 不会被校验。仅校验PARTIAL

WeatherSpec#

属性类型默认值有效值使用情况稳定性
ModeWeatherMode int记录为 null 时为 00 Unset、1 Preset、2 Icao、3 RealCurrent。除 Unset 外的任何模式 → weather 不支持条目以及 OL_E_CAPABILITY_UNAVAILABLE。PARTIAL
PresetOptionalValue<string>Unset预设名称(不校验)。仅携带PARTIAL
IcaoOptionalValue<string>UnsetICAO 代码(不校验)。仅携带PARTIAL

PlayerVehicleSpec(位于 PlayerVehicle 内)#

属性类型默认值有效值使用情况稳定性
ModelOptionalValue<string>Unset已安装的 Vehicles\...\<file>.bus 标识,否则为 OL_E_VEHICLE_NOT_FOUND。解析到 ResolvedContent 中;随后 player-vehicle.model 不支持 → OL_E_CAPABILITY_UNAVAILABLEPARTIAL
RepaintOptionalValue<string>UnsetModel 的涂装标识(<cti>#item:<n>),否则为 OL_E_REPAINT_NOT_FOUND;仅在设置了 Model 时检查。同上PARTIAL
HofOptionalValue<string>Unset已安装的 Vehicles\...\<file>.hof,否则为 OL_E_HOF_NOT_FOUND。同上PARTIAL
FleetNumberOptionalValue<string>Unset任意字符串。OL_E_CAPABILITY_UNAVAILABLEPARTIAL
RegistrationOptionalValue<string>Unset任意字符串。OL_E_CAPABILITY_UNAVAILABLEPARTIAL
Enabledbool(只读)计算得出设置了 Model 时为 true。交接中作为 PlayerVehicleEnabled 携带的是 PlayerVehicle.IsSet。派生PARTIAL

Presence 为 1 但所有字段均未设置的 PlayerVehicle 会被接受,且不产生任何效果。在当前版本(build)上,设置任何字段都会使计划不可运行(STATICALLY_PARTIAL)。

EnvironmentSpec#

属性类型默认值使用情况稳定性
General、Advanced、Graphics、AdvancedGraphics、Sound、AiPassengers、Keyboard、Controllers各为 IReadOnlyDictionary<string, OptionalValue<string>>,必需(为空时用 {})无是STABLE_BETA

八个分组会被合并;键放在哪个分组中没有影响。每个 Presence 为 1 的条目都是 ConfigurationCatalog(src/OmsiLaunch.Configuration/ConfigurationCatalog.cs)中的一个语义设置项;键决定目标文件(当前所有键均为 options.cfg)和令牌。规划时会检查键是否存在(OL_E_UNKNOWN_SETTING)以及是否可写(OL_E_SETTING_NOT_WRITABLE);值仅在启动时校验(OL_E_INVALID_SETTING_VALUE,报告为带 OL_E_START_SESSION 的 Failed 会话)。键不区分大小写。未设置的条目被忽略。CLI 参数 /set:<key>=<value> 写入 General;会话配置档的 settings 也合并到 General 中。

键值说明
general.languagestring[language] 令牌
general.radiostring
general.alternateView、general.showOwnDriver、general.showErrorMessages、general.autoSave、general.currentTime、general.currentDate、general.currentYeartrue / false存在性令牌(autoSave 是 noAutoSave 的反向)
graphics.screenRatiostring
graphics.maxFPS整数 10..200
graphics.tileDistance整数 1..20
graphics.maxObjectDistanceMeters数值 20..5000
graphics.minObjectScreenPercent数值 0..10存储时除以 100
graphics.minReflectionObjectScreenPercent数值 0..50存储时除以 100
graphics.maxObjectComplexity整数 0..3
graphics.maxMapComplexity整数 0..2
graphics.sunGlow、graphics.loadAllTiles、graphics.stencilBuffer、graphics.rainReflections、graphics.humansInRainReflectionstrue / false存在性令牌
graphics.stencilShadowstrue / false写为 on / off
graphics.realTimeReflectionseconomy / fullSTATICALLY_PARTIAL
graphics.particlesenabled,maxPerEmitter,playerVehicleOnly,inReflections(bool,int>=0,bool,bool)一个 smokesystems 块
simulation.collision、simulation.collisionTerrain、simulation.collisionVehicles、simulation.collisionPedestrians、simulation.disableAutomaticScheduleAnalysisPopup、simulation.ticketInfo、simulation.automaticClutchtrue / false存在性令牌
simulation.ticketSelling整数 0..2
simulation.maintenance整数 0..4
advanced.reducedMultithreadingtrue / false同时对应两个 OMSI 令牌(RUNTIME_PROVEN)
view.driverSmooth、view.driverMoving、controls.autoCenter、controls.reducedSteeringSpeedtrue / false存在性令牌
traffic.randomVehicles整数 0..1000多行 AIMaxCountRandom 块的第 0 个分量(经运行时验证,矩阵 RV-005)
traffic.humans整数 0..1000AIMaxCountRandom 的第 1 个分量
traffic.factorPercent数值 1..300
traffic.parkedVehiclesPercent数值 0..100
traffic.scheduledVehicles数值 0..1000
traffic.scheduledLinePriority数值 1..4
traffic.passengerFactorPercent数值 0..200
sound.stereo数值 0..100
sound.maxSimultaneousSounds数值 5..1000
sound.masterVolume数值 0..1
advanced.multithreadingCalculate、advanced.multithreadingTextureLoad、graphics.texture、graphics.textureFilter拒绝已知但不可写 → OL_E_SETTING_NOT_WRITABLE

被修补的文件保留其编码(保留 Windows-1252 字节;遵循带 BOM 的 UTF-8/UTF-16)和换行符。

LaunchBehaviorSpec#

属性类型默认值有效值使用情况稳定性
RestoreConfigurationbooltrue任意没有使用方:会话拥有的文件总是被精确还原。PARTIAL(仅携带,当前无效果)
SuppressStaleClosecheckWarningbooltrue任意true:会话开始前已存在的 closecheck 文件会在启动时被永久删除(诊断信息 closecheck.stale-removed 附带其 SHA-256;失败时为 OL_E_CLOSECHECK_REMOVE_FAILED)。false:已存在的 closecheck 保持不动,且不算作会话删除项。OMSI 在会话期间写入的 closecheck 总是在还原时被删除。STABLE_BETA
StartupTimeoutSecondsint1801..600(否则 StartSessionAsync 抛出 ArgumentOutOfRangeException;CLI /startup-timeout 强制 1..600;配置档要求 > 0)。这是从监管器启动到 Running 的时间预算;超时后会话以 OL_E_STARTUP_TIMEOUT(插件已启动)或 OL_E_PLUGIN_NOT_LOADED 失败。是STABLE_BETA
ShutdownTimeoutSecondsint30任意 int(CLI /shutdown-timeout 为 1..600)没有使用方:监管器立即用 TerminateProcess 终止 OMSI;不存在协作式关闭的等待。PARTIAL(仅携带,当前无效果)

InputSpec#

属性类型默认值使用情况稳定性
KeyboardDocumentOptionalValue<string>Unset设置后 → input.keyboard 不支持(STATICALLY_PARTIAL)以及 OL_E_CAPABILITY_UNAVAILABLE。键盘 PATCH/REPLACE 执行未实现。PARTIAL
ControllerDocumentOptionalValue<string>Unset设置后 → input.controller 不支持以及 OL_E_CAPABILITY_UNAVAILABLE。PARTIAL

DiagnosticsSpec#

属性类型默认值使用情况稳定性
Logbooltruesrc/ 中没有使用方。主机跟踪 <root>\.omsilaunch\diagnostics\<sessionId>-host.log 总是会被写入。PARTIAL(仅携带,当前无效果)
Verboseboolfalse没有使用方。PARTIAL
OmsiLogAllboolfalse没有使用方。PARTIAL
ProcessTraceboolfalse没有使用方。PARTIAL
PluginTraceboolfalse没有使用方。PARTIAL
NativeTraceboolfalse没有使用方。PARTIAL

CLI 参数 /log、/logall、/omsi-logall、/verbose、/trace、/trace-process、/trace-plugin、/trace-native 会填充这些布尔值(/logall 设置 Verbose、ProcessTrace、PluginTrace、NativeTrace);它们与 spec 中的值做逻辑或(OR)运算。

SessionPresentationSpec#

属性类型默认值有效值使用情况稳定性
SplashSplashMode int1(Managed)0 Unset(别名 Native):OMSI 自己的启动画面文件保持不变。1 Managed:OmsiLaunch 在会话期间以覆盖层替换 GUI\NewSplashscreen_ENG.bmp 和 GUI\NewSplashscreen_<LANG>.bmp(之后精确还原)。是STABLE_BETA(矩阵 RV-006)
LanguageOptionalValue<string>UnsetPTB/PT-BR、ENG/EN、DEU/DE、FRA/FR(不区分大小写);其他任何值都会规范化为 ENG。未设置时,读取 options.cfg 中的 [language] 值并以同样方式规范化。是(仅托管启动画面)STABLE_BETA
CustomAssetDirectoryOptionalValue<string>Unset包含 ENG.bmp 和 <LANG>.bmp(640×480,24 位 BMP)的目录。参见路径规则。目录不存在:OL_E_SPLASH_ASSET_DIRECTORY_MISSING;文件不存在:OL_E_SPLASH_ASSET_MISSING;格式错误:OL_E_SPLASH_FORMAT_UNSUPPORTED。未设置时使用 <root>\.omsilaunch\assets\splash(从包中一次性初始化),否则使用包内的 assets\splash。是(仅托管启动画面)STABLE_BETA
SuppressTrayIconboolfalsetrue 会隐藏 CLI 所有者的独立 Windows 托盘指示器。仅 CLI 所有者;API 没有托盘。没有对应的 CLI 参数,只能来自 spec 文件。STABLE_BETA

InternetTexturesSpec#

属性类型默认值有效值使用情况稳定性
ModeInternetTexturesMode int0(Native)0 Native:不做任何更改。1 Disabled:插件抑制 OMSI 进程内的下载器(遥测 internet-textures.suppressed / internet-textures.suppression.failed)。2 Override:.itx 配置文件以覆盖层形式替换为 Texture\standard.itx;其目标文件和 Texture\standard.ipr 成为会话删除项。是Native:STABLE_BETA;Disabled、Override:EXPERIMENTAL
OverrideProfilePathOptionalValue<string>UnsetOverride 时必需(OL_E_ITX_PROFILE_REQUIRED)。一个由成对行组成的文本文件:先是绝对的 http/https URL,然后是相对于安装根目录的目标路径;该路径必须包含 Texture\ 组成部分、不是根路径、不含 ..、不以 \ 开头,且不经过任何 junction/symlink(OL_E_ITX_PROFILE_INVALID、OL_E_ITX_TARGET_OUTSIDE_TEXTURE_PATH)。参见路径规则。是EXPERIMENTAL

SessionProfileMetadata#

属性类型使用情况稳定性
Id、Name、Version、Author、PresetId、PresetIndex、PresetName、PackagePath字符串 / int记录在计划诊断信息 session_profile.selected 中(Data["session_profile.*"])。此外不被使用;通常由会话配置档编译器填写,而非手工填写。STABLE_BETA

枚举#

枚举取值(JSON 整数)
WorldModeNewMap = 0、SavedSituation = 1、LastMapState = 2、LastSituation = 2(已过时的别名;它是 OMSI 原生的“上次地图状态”分支,绝不是最新的 .osn)
DateTimeModeUnset = 0、Explicit = 1、System = 2
WeatherModeUnset = 0、Preset = 1、Icao = 2、RealCurrent = 3
SplashModeUnset = 0、Native = 0(别名)、Managed = 1
InternetTexturesModeNative = 0、Disabled = 1、Override = 2
PresenceUnset = 0、Set = 1
EntrypointMode(只读 Entrypoint.Mode)Unset = 0、PresentedIndex = 1、Identity = 2

超出声明范围的整数会被序列化器原样存储,并表现为未知值(例如,未知的 WorldMode 既不是 NEW_MAP 也不是 SAVED_SITUATION,得到的计划没有世界能力;插件会拒绝它,但 CLI 无论如何都会替换该模式,参见优先级)。

校验规则与不可运行诊断信息#

PlanSessionAsync 先运行 LaunchValidation.Validate,再运行 SessionPlanner.PlanAsync。当且仅当没有任何诊断代码以 OL_E_ 开头时,计划才可运行。完整列表:

诊断信息条件来源
OL_E_INSTALLATION_NOT_FOUNDInstallation.RootPath 为空或仅含空白LaunchValidation
OL_E_DATE_TIME_APPLY_FAILEDDate.Mode = Explicit 但未设置值,或月/日超出范围;Time.Mode = Explicit 但未设置值,或时/分/秒超出范围LaunchValidation
OL_E_INVALID_ARGUMENT模式不为 Explicit 时设置了 Date.Value 或 Time.ValueLaunchValidation
OL_E_MAP_NOT_FOUNDNewMap 的 MapIdentity 未设置或不符合 maps\...\global.cfg 形式(校验);NewMap 的标识未安装(规划器)两者
OL_E_ENTRYPOINT_NOT_FOUNDNewMap 未设置 EntrypointIdentity,且 PresentedEntrypointIndex 未设置或为负数LaunchValidation
OL_E_ENTRYPOINT_REQUIREDNewMap,地图已安装,没有 EntrypointIdentity,PresentedEntrypointIndex 未设置(world.presented-entrypoint 不可用)SessionPlanner
OL_E_SITUATION_NOT_FOUNDSavedSituation 没有 SituationIdentity(校验),或其标识未安装(规划器)两者
OL_E_SITUATION_MAP_NOT_FOUNDSavedSituation:.osn 中指定的地图未安装SessionPlanner
OL_E_UNSUPPORTED_OPERATING_SYSTEM不是 x64 操作系统上以 x64 主机进程运行的 Windows 10+(runtime.current-windows-x64)SessionPlanner
OL_E_INSTALLATION_NOT_WRITABLE根目录不存在、设置了只读属性,或没有 plugins\ 子目录(transaction.exact-restore)SessionPlanner
OL_E_UNSUPPORTED_BUILDOmsi.exe 不存在,或其大小/SHA-256 既不是配置指纹(692EBFBF...,8 503 440 字节),也不是允许列表中的哈希(omsi.profile.OMSI23004)SessionPlanner
OL_E_CAPABILITY_UNAVAILABLEWorld.Mode = LastMapState;设置了 EntrypointIdentity;Date/Time/Year 模式不为 Unset;Weather 模式不为 Unset;设置了任何 PlayerVehicle 字段;设置了 Input.KeyboardDocument 或 Input.ControllerDocumentSessionPlanner
OL_E_VEHICLE_NOT_FOUND、OL_E_REPAINT_NOT_FOUND、OL_E_HOF_NOT_FOUNDPlayerVehicle.Model / Repaint / Hof 未安装(在 OL_E_CAPABILITY_UNAVAILABLE 之外额外报告)SessionPlanner
OL_E_UNKNOWN_SETTING、OL_E_SETTING_NOT_WRITABLEEnvironment 中的某个键不在目录中 / 不可写SessionPlanner
OL_E_SESSION_PRESENTATION_INVALID构建启动画面/ITX 计划时抛出异常;消息中携带 OL_E_SPLASH_ASSET_DIRECTORY_MISSING、OL_E_SPLASH_ASSET_MISSING、OL_E_SPLASH_FORMAT_UNSUPPORTED、OL_E_ITX_PROFILE_REQUIRED、OL_E_ITX_PROFILE_MISSING、OL_E_ITX_PROFILE_INVALID 或 OL_E_ITX_TARGET_OUTSIDE_TEXTURE_PATHSessionPlanner
OL_E_RUNTIME_ARTIFACT_MISSING无法加载插件闭包引用(OmsiLaunchRuntimePaths)或发行清单(消息中可能携带 OL_E_RELEASE_MANIFEST_INVALID)OmsiLaunchService.PlanSessionAsync

规划时不校验(在启动时作为带 OL_E_START_SESSION 的 Failed 会话失败):设置项的值(OL_E_INVALID_SETTING_VALUE)、永久插件完整性(OL_E_PERMANENT_PLUGIN_*)、租约可用性(OL_E_INSTALLATION_BUSY)、StartupTimeoutSeconds 范围(由 StartSessionAsync 抛出)。

信息性计划诊断信息:plugin.integrity.reference(消息为 manifest 或 self)、session_profile.selected。

优先级:CLI 参数、spec 文件与会话配置档#

CliInput.BuildSpecAsync(tools/OmsiLaunch.Cli/Program.cs)按以下顺序构建生效的 spec:

  1. 种子 = 内置默认值;如果提供了 /spec 文件,则为该文件。
  2. 安装根目录 = 若提供了显式安装参数则使用它,否则使用种子的 RootPath;然后 ./空值 → 可执行文件所在目录,再经 Path.GetFullPath 处理。显式安装参数总是优先于 spec 的 RootPath。
  3. 会话配置档(/predefined-profile + /predefined-profile-index):涉及配置档所拥有字段的显式 CLI 参数会以 OL_E_SESSION_PROFILE_OVERRIDE_CONFLICT 被拒绝(世界字段仅在 NEW_MAP 模式下;预设中存在的 /set 键;预设含 presentation 时的启动画面参数;预设含 internet-textures 时的网络纹理参数;预设含 behavior 时的超时参数)。种子的 World 被替换为一个全新的对象(只保留 CLI 世界模式),然后依次应用配置档的 new: 块(仅 NEW_MAP)、settings(写入 General)、presentation、internet-textures、behavior 以及 SessionProfile 元数据。compatibility.maps 对 NEW_MAP 和 SAVED_SITUATION 强制执行。
  4. 世界:CLI 世界模式总是优先(默认 /new、/saved:<osn>、/last);spec 文件的 World.Mode 会被替换。要从 spec 运行已保存情景,请传入 /saved:。/map 和 /entrypoint//entrypoint-index 覆盖种子;CLI 的 /entrypoint 标识会清除索引;/saved 与 /map 或入口点参数同时使用时为 OL_E_INVALID_ARGUMENT。
  5. 提供了 /date、/time、/year、/weather* 时,它们覆盖种子(system 选择 DateTimeMode.System)。
  6. /no-vehicle 清除 PlayerVehicle;单独的 /vehicle、/repaint、/hof、/fleet、/registration 覆盖种子中玩家车辆的对应字段。
  7. /set:<key>=<value> 条目被加入 Environment.General(检查键,不检查值);其他七个分组原样来自种子。
  8. /startup-timeout 和 /shutdown-timeout 仅在提供时覆盖种子;否则依次采用 spec、配置档,最后是默认值 180 s / 30 s。ShutdownTimeoutSeconds 对监管器而言是 ACCEPTED_FOR_COMPATIBILITY / CURRENTLY_NO_EFFECT。
  9. 提供了 /splash、/splash-language、/splash-assets、/internet-textures、/internet-textures-profile 时,它们覆盖种子;SuppressTrayIcon 仅来自种子。
  10. 诊断参数与种子做逻辑或(OR)运算。

结果:显式 CLI 参数 > 会话配置档 > spec 文件 > 内置默认值;例外是与配置档所拥有字段冲突的 CLI 参数会导致错误,而不是覆盖。

路径规则#

路径API 行为CLI 行为
Installation.RootPath按原样使用:在文件操作中,相对路径以进程工作目录为基准解析。请传入绝对路径。租约、事务日志和内容目录会用 Path.GetFullPath 将其规范化。. 或空值 = 包含 OmsiLaunch.exe 的目录,绝不是调用方的工作目录;显式安装参数优先于 spec;结果会被转换为绝对路径。
Presentation.CustomAssetDirectory绝对路径,或相对于 Installation.RootPath 的路径。必须存在。相同(/splash-assets)。会话配置档中的 assets 路径被限制在配置档包内,并以绝对路径存储。
InternetTextures.OverrideProfilePath用 Path.GetFullPath 解析,即相对于进程工作目录,而不是安装根目录。必须存在。相同(/internet-textures-profile)。会话配置档中的 profile 路径被限制在包内,并以绝对路径存储。
ITX 目标行相对于安装根目录;必须包含 Texture\ 组成部分;不得有根、不得含 ..、不得以 \ 开头、不得包含 junction/symlink 组成部分。相同。
内容标识(MapIdentity、SituationIdentity、PlayerVehicle.*)相对于安装实例,不区分大小写,接受 /;绝不是绝对路径。相同。

仅携带而不应用的字段#

字段当前效果稳定性
Installation.ExpectedExecutableSha256无(主机依据构建配置对 Omsi.exe 计算哈希)PARTIAL
Behavior.RestoreConfiguration无(还原总是执行)PARTIAL
Behavior.ShutdownTimeoutSeconds无(强制终止;ACCEPTED_FOR_COMPATIBILITY / CURRENTLY_NO_EFFECT)PARTIAL
Diagnostics.*无(主机跟踪总是写入)PARTIAL
Input.KeyboardDocument、Input.ControllerDocument设置后计划不可运行PARTIAL
Date、Time、Year(模式不为 Unset)计划不可运行(STATICALLY_PARTIAL)PARTIAL
Weather(模式不为 Unset)计划不可运行(STATICALLY_PARTIAL)PARTIAL
PlayerVehicle.*(设置了任何字段)为诊断信息解析内容,计划不可运行(STATICALLY_PARTIAL)PARTIAL
World.EntrypointIdentity计划不可运行(RUNTIME_PARTIAL)PARTIAL
World.Mode = LastMapState / LastSituation计划不可运行(UNSUPPORTED_FOR_CURRENT_PROFILE)UNAVAILABLE
SessionProfile仅来源诊断信息STABLE_BETA