# Dokumentacja publicznego API (`OmsiLaunch.Api`)
> Tłumaczenie [oryginalnej strony w języku angielskim](https://github.com/lmonteirotech/OmsiLaunch/blob/v0.1.0-beta.3/docs/reference/public-api.md) dla OmsiLaunch 0.1.0-beta3. Wiążąca jest strona angielska: w razie rozbieżności obowiązują strona angielska i kod.
Ta strona jest normatywną dokumentacją zarządzanego publicznego API OmsiLaunch 0.1.0-beta3: zestawu `OmsiLaunch.Api` (kontrakty) oraz punktu wejścia dla integratorów `OmsiLaunchService` w `OmsiLaunch.Core`. Opisuje wyłącznie to, co robi bieżący kod. Wszystko, co integrator może wywołać, otrzymać lub zaobserwować, jest tu wymienione wraz z poziomem stabilności; to, czego tu nie wymieniono, nie jest powierzchnią integracji.
Generowany [spis publicznego API](https://omsilaunch.omsimods.com.br/pl/docs/reference/public-api-inventory/index.md) wymienia każdy publiczny typ i składową `OmsiLaunch.Api`, `OmsiLaunch.Core` i `OmsiLaunch.Process` wraz z sygnaturą i stabilnością; bramka dokumentacji kończy się niepowodzeniem, gdy spis i zestawy się różnią. Ta strona objaśnia semantykę.
Powiązane strony: [dokumentacja LaunchSpec](https://omsilaunch.omsimods.com.br/pl/docs/reference/launchspec/index.md), [kody błędów](https://omsilaunch.omsimods.com.br/pl/docs/reference/errors/index.md), [cykl życia sesji](https://omsilaunch.omsimods.com.br/pl/docs/concepts/session-lifecycle/index.md), [transakcje i odzyskiwanie](https://omsilaunch.omsimods.com.br/pl/docs/concepts/transactions-and-recovery/index.md), [sterowanie runtime](https://omsilaunch.omsimods.com.br/pl/docs/reference/runtime-control/index.md), [możliwości](https://omsilaunch.omsimods.com.br/pl/docs/reference/capabilities/index.md), [lokalna płaszczyzna sterowania](https://omsilaunch.omsimods.com.br/pl/docs/reference/local-control/index.md), [kody wyjścia](https://omsilaunch.omsimods.com.br/pl/docs/reference/exit-codes/index.md), [stan weryfikacji w runtime](https://omsilaunch.omsimods.com.br/pl/docs/status/runtime-validation-status/index.md).
## Słownik stabilności
| Poziom | Znaczenie na tej stronie |
| --- | --- |
| `STABLE_BETA` | Kontrakt jest zamrożony dla linii protokołu 0.1, a ścieżka jest zweryfikowana w runtime w `research/reports/OMSILAUNCH-RUNTIME-VALIDATION-MATRIX.md`. |
| `EXPERIMENTAL` | Możliwy do wywołania i przetestowany, ale kontrakt lub dowody z runtime mogą się zmienić, zanim stanie się stabilny. |
| `PARTIAL` | Obecny w kontrakcie; zaimplementowana lub zweryfikowana jest tylko część zachowania (tekst określa, która). |
| `INTERNAL` | Publiczny w zestawie z przyczyn technicznych (mostek współdzieli typ), ale nie jest powierzchnią integracji; może się zmienić bez uprzedzenia. |
| `UNAVAILABLE` | Obecny w kontrakcie, ale odrzucany przez bieżący build. |
## Przegląd zestawów
| Zestaw | Rola dla integratorów |
| --- | --- |
| `OmsiLaunch.Api` | Czyste kontrakty: rekordy, typy wyliczeniowe, `IOmsiLaunch`, rejestr możliwości, katalog błędów, formaty przesyłowe (wire), funkcje pomocnicze D3D. Nie zawiera `IntPtr`, `nint`, uchwytów Win32, adresów natywnych ani obiektów procesów. |
| `OmsiLaunch.Core` | `OmsiLaunchService` (implementacja `IOmsiLaunch`), `OmsiLaunchRuntimePaths`, `SessionPlanner`, `LaunchValidation`, `SessionProfileCompiler`. |
| `OmsiLaunch.Process` | `IRuntimePlatform` i `CurrentWindowsX64Platform` (jedyny adapter platformy), `InstallationLease`. Potrzebne do utworzenia usługi. |
| `OmsiLaunch.Configuration`, `OmsiLaunch.Content`, `OmsiLaunch.Interop`, `OmsiLaunch.Plugin`, `OmsiLaunch.Builds.Omsi23004` | Zestawy implementacyjne. Ich typy publiczne są dla integratorów `INTERNAL`. |
## Punkt wejścia: `OmsiLaunchService` i `OmsiLaunchRuntimePaths`
```csharp
public sealed record OmsiLaunchRuntimePaths(string PluginBuildDirectory, string NativeBridgePath, string? ReleaseManifestPath = null);
public sealed class OmsiLaunchService : IOmsiLaunch
{
public OmsiLaunchService(IRuntimePlatform platform, OmsiLaunchRuntimePaths runtimePaths);
}
```
| Parametr | Poprawna wartość | Niepoprawna / domyślna |
| --- | --- | --- |
| `platform` | `new CurrentWindowsX64Platform()` (przestrzeń nazw `OmsiLaunch.Process`). Wykrywa platformę, tworzy proces OMSI za pomocą `CreateProcessW`, czeka na niego i go kończy. | Nie jest dostarczana żadna inna implementacja. Własna implementacja `IRuntimePlatform` ma status `INTERNAL`. |
| `PluginBuildDirectory` | Katalog zawierający pliki referencyjne zestawu plików stałej wtyczki (closure): `OmsiLaunch.Plugin.opl`, `OmsiLaunch.PluginNE.dll`, `OmsiLaunch.Plugin.deps.json`, `OmsiLaunch.Plugin.runtimeconfig.json` oraz każdy `OmsiLaunch.*.dll` zarządzanego zestawu plików (musi obejmować `OmsiLaunch.Plugin.dll`). W zainstalowanym pakiecie jest to `\plugins`. | Brak katalogu lub pliku: `PlanSessionAsync` zwraca plan niemożliwy do uruchomienia z `OL_E_RUNTIME_ARTIFACT_MISSING`. |
| `NativeBridgePath` | Ścieżka pliku `OmsiLaunch.Native.x86.dll` (w pakiecie: `\plugins\OmsiLaunch.Native.x86.dll`). | Jak wyżej. |
| `ReleaseManifestPath` | `release-manifest.json` obok `OmsiLaunch.exe`, jeśli istnieje. Dostarcza oczekiwany SHA-256 każdego pliku w `plugins/` (`plugin.integrity.reference = manifest`). | `null` (układ deweloperski): zainstalowane pliki są sprawdzane jedynie pod kątem obecności i spójności z referencyjnym zestawem plików (`plugin.integrity.reference = self`). Niepoprawny manifest: `OL_E_RELEASE_MANIFEST_INVALID`. |
Usługa odczytuje te ścieżki przy każdym wywołaniu `PlanSessionAsync` i `StartSessionAsync`; nigdy nie kopiuje, nie przygotowuje ani nie usuwa plików wtyczki (zob. [stała wtyczka](https://omsilaunch.omsimods.com.br/pl/docs/concepts/permanent-plugin/index.md)). CLI tworzy usługę dokładnie w ten sposób (`tools/OmsiLaunch.Cli/Program.cs`):
```csharp
using OmsiLaunch.Api;
using OmsiLaunch.Core;
using OmsiLaunch.Process;
var package = AppContext.BaseDirectory; // directory that contains OmsiLaunch.exe
var plugins = Path.Combine(package, "plugins");
var manifest = Path.Combine(package, "release-manifest.json");
IOmsiLaunch launch = new OmsiLaunchService(
new CurrentWindowsX64Platform(),
new OmsiLaunchRuntimePaths(plugins, Path.Combine(plugins, "OmsiLaunch.Native.x86.dll"), File.Exists(manifest) ? manifest : null));
```
Należy utworzyć jedną usługę na proces i ją współdzielić. Stabilność: `STABLE_BETA`.
## Zasady własności sesji
| Zasada | Szczegóły |
| --- | --- |
| Jeden właściciel na instalację | `StartSessionAsync` pozyskuje dzierżawę instalacji – nazwany semafor `Local\OmsiLaunch.Installation.` – i utrzymuje ją, dopóki nadzorca nie przywróci instalacji. Drugie uruchomienie na tym samym katalogu głównym z dowolnego procesu tej samej sesji logowania kończy się błędem `OL_E_INSTALLATION_BUSY` (zgłaszanym jako sesja `Failed`, zob. `StartSessionAsync`). Dzierżawa obowiązuje w obrębie sesji logowania, nie między sesjami logowania, i nie jest zwalniana, dopóki inny proces ma do niej uchwyt (zaakceptowane ryzyko). |
| Uchwyty są lokalne dla procesu | `SessionHandle` opakowuje `Guid` sesji. Ma znaczenie wyłącznie dla instancji `OmsiLaunchService`, która go zwróciła. Uchwyt zbudowany ze znanego `Guid` w innym procesie (lub w innej instancji usługi) powoduje `KeyNotFoundException`. Sterowanie międzyprocesowe odbywa się przez [lokalną płaszczyznę sterowania](https://omsilaunch.omsimods.com.br/pl/docs/reference/local-control/index.md), a nie przez uchwyty. |
| Zawsze wywoływać `CloseAsync` | Od wywołania `StartSessionAsync` proces jest właścicielem trwałej transakcji. `CloseAsync` w razie potrzeby żąda kanonicznego zatrzymania, czeka na nadzorcę (zakończenie procesu, dokładne przywrócenie, zwolnienie dzierżawy) i zapomina sesję. Należy je wywołać na każdej ścieżce wyjścia, także po stanie `Failed`. Bez niego wpis sesji pozostaje w pamięci; samo przywrócenie jest wykonywane przez nadzorcę niezależnie od tego. |
| Nieudane sesje nadal są sesjami | Uruchomienie, które kończy się niepowodzeniem po powrocie z `StartSessionAsync`, zgłasza `SessionState.Failed`; uchwyt pozostaje ważny dla `GetStatusAsync`/`WaitForAsync` aż do `CloseAsync`. |
| Plany są sprawdzane ponownie | `StartSessionAsync` ponownie oblicza skrót `Omsi.exe` i ponownie planuje specyfikację; plan, który nie jest już możliwy do uruchomienia, jest odrzucany z `OL_E_PLAN_NOT_RUNNABLE`. |
## `IOmsiLaunch`
```csharp
public interface IOmsiLaunch
{
Task PlanSessionAsync(LaunchSpec spec, CancellationToken cancellationToken = default);
Task StartSessionAsync(SessionPlan plan, CancellationToken cancellationToken = default);
Task GetStatusAsync(SessionHandle session, CancellationToken cancellationToken = default);
Task WaitForAsync(SessionHandle session, SessionState state, TimeSpan timeout, CancellationToken cancellationToken = default);
Task StopAsync(SessionHandle session, CancellationToken cancellationToken = default);
Task CloseAsync(SessionHandle session, CancellationToken cancellationToken = default);
Task ExecuteRuntimeAsync(SessionHandle session, RuntimeCommand command, TimeSpan timeout, CancellationToken cancellationToken = default);
Task> GetCapabilitiesAsync(InstallationSpec installation, CancellationToken cancellationToken = default);
Task> DiscoverAsync(InstallationSpec installation, ContentQueryKind query, OptionalValue scope = default, CancellationToken cancellationToken = default);
Task RecoverPendingAsync(InstallationSpec installation, bool restore, CancellationToken cancellationToken = default);
}
```
Wspólne zasady dla każdej metody:
- Nieznane lub już zamknięte uchwyty zgłaszają `KeyNotFoundException` („Unknown OmsiLaunch session.”).
- Żadna metoda poza `ExecuteRuntimeAsync` nie wymaga sesji w stanie Running.
- Wyjątki niosące kod OmsiLaunch umieszczają ten kod na początku `Exception.Message` (`"OL_E_PLAN_NOT_RUNNABLE: ..."`). CLI wyodrębnia kody z komunikatów w ten sam sposób (`CliProgram.Classify`).
- Obsługiwany build: tylko `Omsi23004_692EBFBF` (oraz skrót z listy dozwolonych Steam LAA – akceptowany; rozgrywka niezweryfikowana, wymaga prawdziwej instalacji Steam). Zob. [zgodność](https://omsilaunch.omsimods.com.br/pl/docs/reference/compatibility/index.md).
### Kompletny minimalny przykład
```csharp
var none = new Dictionary>();
var spec = new LaunchSpec(
Installation: new InstallationSpec(@"C:\OMSI 2"),
World: new WorldSpec(WorldMode.NewMap, OptionalValue.Set(@"maps\Grundorf\global.cfg"), OptionalValue.Unset, OptionalValue.Set(1)),
Date: new DateSpec(DateTimeMode.Unset, OptionalValue.Unset),
Time: new TimeSpec(DateTimeMode.Unset, OptionalValue.Unset),
PlayerVehicle: OptionalValue.Unset,
Environment: new EnvironmentSpec(none, none, none, none, none, none, none, none),
Behavior: new LaunchBehaviorSpec());
var plan = await launch.PlanSessionAsync(spec);
if (!plan.IsRunnable) { foreach (var d in plan.Diagnostics) Console.WriteLine($"{d.Code}: {d.Message}"); return; }
var session = await launch.StartSessionAsync(plan);
try
{
var status = await launch.WaitForAsync(session, SessionState.Running, TimeSpan.FromSeconds(plan.Spec.Behavior.StartupTimeoutSeconds + 5));
if (status.State == SessionState.Running)
{
var time = await launch.ExecuteRuntimeAsync(session, new RuntimeCommand(session.SessionId, 1, "time.read"), TimeSpan.FromSeconds(5));
Console.WriteLine(time.Succeeded ? $"{time.Values!["hour"]}:{time.Values["minute"]}" : time.ErrorCode);
await launch.StopAsync(session);
}
var final = await launch.WaitForAsync(session, SessionState.Completed, Timeout.InfiniteTimeSpan);
Console.WriteLine(final.State); // Completed, or Failed with diagnostics
}
finally
{
await launch.CloseAsync(session); // always
}
```
### `PlanSessionAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task PlanSessionAsync(LaunchSpec spec, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Kompiluje `LaunchSpec` do `SessionPlan` bez uruchamiania OMSI: waliduje specyfikację, wykrywa platformę, oblicza odcisk `Omsi.exe`, rozwiązuje tożsamości zawartości, wyznacza planowane modyfikacje plików, wymienia wymagane i nieobsługiwane możliwości oraz rozstrzyga `IsRunnable`. Publiczna możliwość `session.plan`. |
| Parametry | `spec`: w pełni wypełniony `LaunchSpec` (zob. [dokumentacja LaunchSpec](https://omsilaunch.omsimods.com.br/pl/docs/reference/launchspec/index.md)). `Installation`, `World`, `Date`, `Time`, `Environment` (wszystkie osiem słowników) i `Behavior` muszą być różne od null; składowe opcjonalne mogą mieć wartość `null`. `RootPath` powinien być ścieżką bezwzględną katalogu; pusty katalog główny jest rejestrowany jako `OL_E_INSTALLATION_NOT_FOUND`, ale sonda platformy dla pustej ścieżki zgłasza `ArgumentException`, zanim plan zostanie zwrócony, dlatego nigdy nie należy przekazywać pustego katalogu głównego. |
| Zwraca | `SessionPlan` z nowym `SessionId`, `BuildProfileId = "Omsi23004_692EBFBF"` (zawsze ta stała, nawet gdy plik wykonywalny nie pasuje), wejściowym `Spec`, `Platform`, `ResolvedContent`, `TouchedFiles`, `RuntimeArtifacts` (ścieżki docelowe `plugins\OmsiLaunch.*` oraz `"OmsiLaunch startup handoff v4"`), `RequiredCapabilities`, `UnsupportedRequestedFeatures`, `PlannedMutations`, `Diagnostics`, `IsRunnable`. `IsRunnable` ma wartość `true` dokładnie wtedy, gdy żaden kod komunikatu diagnostycznego nie zaczyna się od `OL_E_`. Informacyjne komunikaty diagnostyczne (`plugin.integrity.reference` z komunikatem `self` lub `manifest`, `session_profile.selected`) nigdy nie czynią planu niemożliwym do uruchomienia. |
| Błędy przenoszone w wyniku | Każdy błąd planowania jest komunikatem diagnostycznym, a nie wyjątkiem: `OL_E_INSTALLATION_NOT_FOUND`, `OL_E_INSTALLATION_NOT_WRITABLE`, `OL_E_UNSUPPORTED_OPERATING_SYSTEM`, `OL_E_UNSUPPORTED_BUILD`, `OL_E_MAP_NOT_FOUND`, `OL_E_ENTRYPOINT_NOT_FOUND`, `OL_E_ENTRYPOINT_REQUIRED`, `OL_E_SITUATION_NOT_FOUND`, `OL_E_SITUATION_MAP_NOT_FOUND`, `OL_E_VEHICLE_NOT_FOUND`, `OL_E_REPAINT_NOT_FOUND`, `OL_E_HOF_NOT_FOUND`, `OL_E_DATE_TIME_APPLY_FAILED`, `OL_E_INVALID_ARGUMENT`, `OL_E_CAPABILITY_UNAVAILABLE`, `OL_E_UNKNOWN_SETTING`, `OL_E_SETTING_NOT_WRITABLE`, `OL_E_SESSION_PRESENTATION_INVALID` (komunikat zawiera kod ekranu startowego/ITX), `OL_E_PERMANENT_PLUGIN_MISSING`, `OL_E_PERMANENT_PLUGIN_HASH_MISMATCH`, `OL_E_PERMANENT_PLUGIN_MANIFEST_INCOMPLETE` (zainstalowany zestaw plików wtyczki w `plugins\` jest weryfikowany względem manifestu wydania na etapie planowania), `OL_E_RUNTIME_ARTIFACT_MISSING` (komunikat może zawierać `OL_E_RELEASE_MANIFEST_INVALID`). Pełne warunki: [reguły walidacji LaunchSpec](https://omsilaunch.omsimods.com.br/pl/docs/reference/launchspec/index.md#validation-rules-and-non-runnable-diagnostics). |
| Zgłaszane wyjątki | `OperationCanceledException`, jeśli token jest już anulowany przy wejściu (jedyny punkt kontrolny); `ArgumentException`/`NotSupportedException` dla składniowo niepoprawnych ścieżek katalogu głównego; `NullReferenceException`/`ArgumentNullException` dla wymaganych składowych o wartości null; `System.Text.Json.JsonException` dla składniowo niepoprawnego manifestu wydania. |
| Anulowanie | Sprawdzane raz, przy wejściu. Dalsze planowanie to synchroniczne operacje na systemie plików. |
| Wymagana sesja w stanie Running | Nie. |
| Modyfikuje stan OMSI | Nie. |
| Modyfikuje system plików | Nie (odczytuje `Omsi.exe`, pliki zawartości, zestaw plików wtyczki, manifest). Wartości ustawień nie są tu walidowane (tylko istnienie klucza i możliwość zapisu); niepoprawna wartość powoduje błąd przy uruchomieniu z `OL_E_INVALID_SETTING_VALUE`. |
| Transakcja / przywracanie | Brak. |
| Ograniczenia | Zażądanie dowolnego trybu `Date`/`Time`/`Year` innego niż `Unset`, dowolnego trybu `Weather` innego niż `Unset`, dowolnego pola `PlayerVehicle`, dokumentów `Input`, `EntrypointIdentity` lub `WorldMode.LastMapState` powoduje w tym buildzie `OL_E_CAPABILITY_UNAVAILABLE` i plan niemożliwy do uruchomienia (wpisy `STATICALLY_PARTIAL` / `UNSUPPORTED_FOR_CURRENT_PROFILE` w `UnsupportedRequestedFeatures`). |
| Stabilność | `STABLE_BETA`. |
| Przykład | `var plan = await launch.PlanSessionAsync(spec); Console.WriteLine(plan.IsRunnable ? "READY" : string.Join(", ", plan.Diagnostics.Where(d => d.Code.StartsWith("OL_E_")).Select(d => d.Code)));` |
### `StartSessionAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task StartSessionAsync(SessionPlan plan, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Uruchamia transakcyjną, zarządzaną sesję OMSI na podstawie planu możliwego do uruchomienia: pozyskuje dzierżawę instalacji, odzyskuje pozostawiony dziennik, waliduje zestaw plików stałej wtyczki, tworzy migawkę (snapshot) i nakłada nakładki (overlay) na pliki sesji, tworzy przekazanie startowe (startup handoff), slot telemetrii i skrzynkę runtime (mailbox), uruchamia `Omsi.exe`, zapisuje proces w dzienniku i przekazuje sesję nadzorcy działającemu w tle. Publiczna możliwość `session.start`. |
| Parametry | `plan`: `SessionPlan` z `IsRunnable == true`. Specyfikacja zawarta w planie jest planowana ponownie; z planu wywołującego zachowywany jest tylko `plan.SessionId`. `plan.Spec.Behavior.StartupTimeoutSeconds` musi mieścić się w zakresie 1..600. |
| Zwraca | `SessionHandle(plan.SessionId)`, gdy tylko `Omsi.exe` zostanie utworzony i zapisany (stan `WaitingForPlugin`) albo gdy tylko ścieżka uruchamiania zakończy się niepowodzeniem (stan `Failed`). Nie czeka na rozgrywkę; należy użyć `WaitForAsync(session, SessionState.Running, ...)`. |
| Zgłaszane wyjątki | `InvalidOperationException("OL_E_PLAN_NOT_RUNNABLE")`, gdy `plan.IsRunnable` ma wartość false; `InvalidOperationException("OL_E_PLAN_NOT_RUNNABLE: ")`, gdy ponowny plan nie jest możliwy do uruchomienia (na przykład zmienił się `Omsi.exe`, usunięto zawartość, brakuje zestawu plików wtyczki); `InvalidOperationException("Duplicate session id.")`, gdy sesja o tym samym identyfikatorze jest nadal zarejestrowana (najpierw należy wywołać `CloseAsync`); `ArgumentOutOfRangeException`, gdy `StartupTimeoutSeconds` wykracza poza 1..600; `OperationCanceledException` przy anulowaniu przed ponownym planowaniem lub w jego trakcie; a także wszystko, co zgłasza `PlanSessionAsync`. We wszystkich przypadkach zgłoszenia wyjątku żadna sesja nie jest rejestrowana. |
| Błędy przenoszone w wyniku | Każdy błąd po ponownym planowaniu jest przechwytywany wewnątrz ścieżki uruchamiania: sesja jest rejestrowana, jej stan to `Failed`, a jej komunikaty diagnostyczne zawierają `OL_E_START_SESSION`, którego komunikatem jest komunikat wewnętrzny (rozpoczynający się od wewnętrznego kodu, jeśli taki istnieje): `OL_E_INSTALLATION_BUSY` (dzierżawa zajęta lub zapisany w dzienniku proces OMSI nadal działa), `OL_E_PERMANENT_PLUGIN_MISSING`, `OL_E_PERMANENT_PLUGIN_MANIFEST_INCOMPLETE`, `OL_E_PERMANENT_PLUGIN_HASH_MISMATCH`, `OL_E_RELEASE_MANIFEST_INVALID`, `OL_E_SPLASH_ASSET_MISSING`, `OL_E_SPLASH_ASSET_DIRECTORY_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_PATH`, `OL_E_UNKNOWN_SETTING`, `OL_E_SETTING_NOT_WRITABLE`, `OL_E_INVALID_SETTING_VALUE`, `OL_E_CLOSECHECK_REMOVE_FAILED`, `OL_E_RECOVERY_BACKUP_CORRUPT`, `OL_E_RECOVERY_ABSENT_OWNERSHIP_MISMATCH`, `OL_E_RECOVERY_ABSENT_OWNERSHIP_UNVERIFIED` (tylko gdy odroczona ponowna próba z nakładkami tej sesji nadal nie może udowodnić własności), `OL_E_RECOVERY_JOURNAL_REMOVE_FAILED`, `OL_E_PROCESS_START_FAILED`, `OL_E_PROCESS_CREATION_TIME_FAILED`. Sprzątanie może dodać `OL_E_PROCESS_CLEANUP_FAILED`, `OL_E_RESTORE_DEFERRED` (zakończenie OMSI niepotwierdzone; dziennik zachowany) lub `OL_E_RESTORE_FAILED`. Późniejsze błędy zgłasza nadzorca (zob. [cykl życia sesji](https://omsilaunch.omsimods.com.br/pl/docs/concepts/session-lifecycle/index.md)). |
| Anulowanie | Przed ponownym planowaniem lub w jego trakcie: zgłasza wyjątek. Później token jest przekazywany do transakcji i tworzenia procesu; anulowanie na tym etapie jest traktowane jak każdy błąd uruchamiania (`Failed` + `OL_E_START_SESSION: The operation was canceled.`), proces (jeśli został utworzony) jest kończony, a instalacja przywracana. |
| Wymagana sesja w stanie Running | Nie. |
| Modyfikuje stan OMSI | Tak: tworzy proces OMSI ze zmiennymi środowiskowymi `OMSILAUNCH_SESSION_ID`, `OMSILAUNCH_HANDOFF_NAME`, `OMSILAUNCH_TELEMETRY_NAME`, `OMSILAUNCH_RUNTIME_CHANNEL`, `OMSILAUNCH_INTERNET_TEXTURES_MODE`. |
| Modyfikuje system plików | Tak, wewnątrz katalogu głównego instalacji: `.omsilaunch\diagnostics\-host.log` (retencja: 50 najnowszych sesji), `.omsilaunch\journal.json`, `.omsilaunch\backup\\*.bin`, `.omsilaunch\assets\splash\*.bmp` (kopiowane jednorazowo dla zarządzanego ekranu startowego), nakładki sesji (poprawki `options.cfg`, `GUI\NewSplashscreen_*.bmp`, `Texture\standard.itx`), usunięcia na czas sesji (cele ITX, `Texture\standard.ipr`, `closecheck`) oraz trwałe usunięcie istniejącego wcześniej, pozostawionego pliku `closecheck`, gdy `SuppressStaleClosecheckWarning` ma wartość true (komunikat diagnostyczny `closecheck.stale-removed`). |
| Transakcja / przywracanie | Otwiera transakcję (`Prepared` → `Applied` → `RuntimeDeployed` → `HandoffCreated` → `ProcessStarted`). Każda ścieżka wyjścia z sesji kończy się przywróceniem. Zob. [transakcje i odzyskiwanie](https://omsilaunch.omsimods.com.br/pl/docs/concepts/transactions-and-recovery/index.md). |
| Ograniczenia | Do rozgrywki docierają tylko `WorldMode.NewMap` z `PresentedEntrypointIndex` oraz `WorldMode.SavedSituation`. `WorldMode.LastMapState` ma status `UNAVAILABLE`. Żądania daty/czasu/pogody/pojazdu gracza/wejścia nigdy nie docierają do tej metody, ponieważ już na etapie planowania są niemożliwe do uruchomienia. |
| Stabilność | `STABLE_BETA` (cykle życia NEW_MAP i SAVED_SITUATION są zweryfikowane w runtime). |
| Przykład | `var session = await launch.StartSessionAsync(plan); var s = await launch.GetStatusAsync(session); if (s.State == SessionState.Failed) Console.WriteLine(s.Diagnostics.Last(d => d.Code.StartsWith("OL_E_")).Message);` |
### `GetStatusAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task GetStatusAsync(SessionHandle session, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Odczytuje semantyczny stan cyklu życia, zebrane dotąd komunikaty diagnostyczne i ograniczoną listę zdarzeń runtime. Publiczna możliwość `session.status`. |
| Parametry | `session`: uchwyt zwrócony przez `StartSessionAsync` i jeszcze niezamknięty. |
| Zwraca | `SessionStatus(SessionId, State, Diagnostics, RuntimeEvents)`: niezmienna migawka (tablice są kopiowane pod blokadą sesji). `RuntimeEvents` nigdy nie ma wartości `null` dla aktywnej sesji. |
| Zgłaszane wyjątki | `KeyNotFoundException` dla nieznanych/zamkniętych uchwytów. Poza tym nigdy nie zgłasza wyjątków. |
| Anulowanie | Token jest ignorowany (wywołanie kończy się synchronicznie). |
| Wymagana sesja w stanie Running | Nie. |
| Modyfikuje OMSI / system plików / transakcję | Nie / Nie / Brak. |
| Stabilność | `STABLE_BETA`. |
| Przykład | `var status = await launch.GetStatusAsync(session); Console.WriteLine($"{status.State} events={status.RuntimeEvents!.Count}");` |
### `WaitForAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task WaitForAsync(SessionHandle session, SessionState state, TimeSpan timeout, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Odpytuje (co 100 ms), dopóki sesja nie znajdzie się w stanie `state` lub w stanie końcowym (`Completed`, `Failed`) albo nie upłynie limit czasu; następnie zwraca bieżący stan. |
| Parametry | `state`: dowolny `SessionState`. Oczekiwanie na stan przejściowy, który już minął (lub nigdy nie jest ustawiany, zob. [cykl życia sesji](https://omsilaunch.omsimods.com.br/pl/docs/concepts/session-lifecycle/index.md)), trwa do stanu końcowego lub upływu limitu czasu. `timeout`: dowolny nieujemny `TimeSpan` lub `Timeout.InfiniteTimeSpan`. |
| Zwraca | Stan w chwili zakończenia oczekiwania. Po przekroczeniu limitu czasu zwracany jest stan, a nie wyjątek: `State` należy sprawdzić samodzielnie. Oczekiwanie na `Running`, które kończy się stanem `Failed`, zwraca natychmiast wynik z komunikatami diagnostycznymi błędu. |
| Zgłaszane wyjątki | `KeyNotFoundException`; `OperationCanceledException`, gdy token wywołującego zostanie anulowany (propaguje się tylko anulowanie przez wywołującego; wewnętrzny limit czasu nie). |
| Anulowanie | Token wywołującego jest respektowany przy każdym takcie co 100 ms. |
| Wymagana sesja w stanie Running | Nie. |
| Modyfikuje OMSI / system plików / transakcję | Nie / Nie / Brak. |
| Stabilność | `STABLE_BETA`. |
| Przykład | `var running = await launch.WaitForAsync(session, SessionState.Running, TimeSpan.FromSeconds(185)); if (running.State != SessionState.Running) { /* timed out or Failed */ }` |
### `StopAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task StopAsync(SessionHandle session, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Żąda kanonicznego zatrzymania. Ustawia flagę zatrzymania i natychmiast wraca; nadzorca zauważa flagę w swojej pętli 100 ms, wywołuje `TerminateProcess` na `Omsi.exe`, czeka na zakończenie, oznacza dziennik jako `ProcessExited`, przywraca każdy plik należący do sesji i zwalnia dzierżawę. Jest to wymuszone zakończenie: własna procedura zamykania OMSI nie jest wykonywana, a OMSI nie zapisuje ponownie `options.cfg` przy wyjściu (celowo – chroni to transakcję). Kooperacyjne zamykanie przez `WM_CLOSE` nie jest zaimplementowane (decyzja produktowa; w domknięciu weryfikacji w runtime OMSI nie zamknął się w ciągu 30 s od `WM_CLOSE`, `L05b`). Publiczna możliwość `session.stop`. |
| Parametry | `session`. |
| Zwraca | Zakończone zadanie; nie czeka na zakończenie procesu ani przywrócenie. Do zaobserwowania zakończenia należy użyć `WaitForAsync(session, SessionState.Completed, ...)`. |
| Zgłaszane wyjątki | `KeyNotFoundException`. |
| Anulowanie | Token jest ignorowany. |
| Wymagana sesja w stanie Running | Nie. Operacja idempotentna; zatrzymanie zażądane przed uruchomieniem nadzorcy jest respektowane, gdy tylko nadzorca się uruchomi; zatrzymanie sesji w stanie końcowym nic nie robi. |
| Modyfikuje stan OMSI | Tak: kończy proces OMSI (kod wyjścia 1). |
| Modyfikuje system plików | Pośrednio: wyzwala przywrócenie, usunięcie dziennika i usunięcie kopii zapasowych przez nadzorcę. |
| Transakcja / przywracanie | Wyzwala `ProcessExited` → `Restoring` → `Restored`. Zmiany po stronie runtime wprowadzone przez `ExecuteRuntimeAsync` (zapisy zegara, dodane pojazdy, zmienne skryptów, tekstury D3D) nie są przywracane; znikają razem z procesem. |
| Stabilność | `STABLE_BETA`. |
| Przykład | `await launch.StopAsync(session); var done = await launch.WaitForAsync(session, SessionState.Completed, TimeSpan.FromMinutes(1));` |
### `CloseAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task CloseAsync(SessionHandle session, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Zwalnia uchwyt konsumenta bez porzucania transakcji: jeśli sesja nie jest w stanie końcowym, żąda kanonicznego zatrzymania; następnie czeka na zadanie cyklu życia nadzorcy (zakończenie procesu, przywrócenie, zwolnienie dzierżawy); potem zapomina sesję. |
| Parametry | `session`. |
| Zwraca | Kończy się, gdy sesja jest w stanie końcowym i została usunięta. Po powrocie uchwyt jest nieznany (`KeyNotFoundException` przy każdym kolejnym wywołaniu, w tym przy drugim `CloseAsync`). |
| Zgłaszane wyjątki | `KeyNotFoundException`; `OperationCanceledException`, jeśli wywołujący anuluje oczekiwanie na nadzorcę. W takim przypadku sesja nie jest usuwana, a nadzorca działa dalej; należy ponownie wywołać `CloseAsync`. |
| Anulowanie | Dotyczy tylko oczekiwania; nigdy nie anuluje przywracania. |
| Wymagana sesja w stanie Running | Nie. |
| Modyfikuje stan OMSI | Tak, gdy sesja jest nadal aktywna (tak samo jak `StopAsync`). |
| Modyfikuje system plików | Pośrednio (przywracanie przez nadzorcę). |
| Transakcja / przywracanie | Gwarantuje, że transakcja zostanie doprowadzona do końca, zanim uchwyt zostanie zwolniony (gdy nadzorca został uruchomiony). W przypadku sesji, która zakończyła się niepowodzeniem przed uruchomieniem nadzorcy, ścieżka uruchamiania już wykonała przywrócenie lub zgłosiła `OL_E_RESTORE_DEFERRED`. |
| Stabilność | `STABLE_BETA`. |
| Przykład | `try { ... } finally { await launch.CloseAsync(session); }` |
### `ExecuteRuntimeAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task ExecuteRuntimeAsync(SessionHandle session, RuntimeCommand command, TimeSpan timeout, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Wykonuje jedną publiczną operację runtime wewnątrz działającego procesu OMSI przez jednozadaniową (single-flight) skrzynkę runtime sesji (plik mapowany w pamięci, 64 KiB, żądanie powiązane z identyfikatorem sesji i identyfikatorem żądania). Wtyczka wykonuje operację w wątku interfejsu użytkownika OMSI. Katalog operacji: [sterowanie runtime](https://omsilaunch.omsimods.com.br/pl/docs/reference/runtime-control/index.md) i [możliwości](https://omsilaunch.omsimods.com.br/pl/docs/reference/capabilities/index.md). |
| Parametry | `command.SessionId` musi być równy `session.SessionId`. `command.RequestId`: `ulong` wybierany przez wywołującego; należy używać ściśle rosnącego licznika w obrębie procesu (funkcje pomocnicze D3D zaczynają od 30 000, właściciel CLI od 10 001/50 000). `command.Operation`: publiczny identyfikator operacji z `PublicCapabilityRegistry.PublicRuntimeOperationIds` (na przykład `time.read`, `road-vehicle.read`, `d3d.texture.create`). `command.Arguments`: wartości tekstowe indeksowane nazwami porządkowymi; wymagane nazwy dla każdej operacji pochodzą z `PublicCapabilityRegistry.GetRuntimeArguments`. `timeout`: mierzony od chwili umieszczenia żądania w skrzynce (oczekiwanie w kolejce za innym trwającym poleceniem nie jest wliczane). CLI używa 5 s (15 s dla `road-vehicles.spawn`) jako właściciel oraz 8 s / 30 s jako klient. |
| Kolejność sprawdzeń | 1. Walidacja w rejestrze (przed wyszukaniem sesji): nieznana operacja lub operacja `internal.*` → wynik `Succeeded=false, ErrorCode=OL_E_RUNTIME_OPERATION_UNKNOWN`; brak wymaganego argumentu (nieobecny lub złożony z białych znaków) → `OL_E_RUNTIME_ARGUMENT_REQUIRED`. 2. Wyszukanie sesji → `KeyNotFoundException`. 3. `command.SessionId != session.SessionId` → `InvalidOperationException("OL_E_RUNTIME_SESSION_MISMATCH")`. 4. Stan inny niż `Running` → `InvalidOperationException("OL_E_SESSION_NOT_RUNNING")`. 5. Żądanie przez skrzynkę runtime. 6. Wartości wyniku, których klucz zaczyna się od `internal_` lub kończy na `_address`, `_pointer`, `_vmt`, są usuwane. |
| Zwraca | `RuntimeCommandResult(SessionId, RequestId, Succeeded, ErrorCode, Values)`. W razie powodzenia `Values` zawiera semantyczne ciągi znaków operacji (opisane dla każdej operacji w [sterowaniu runtime](https://omsilaunch.omsimods.com.br/pl/docs/reference/runtime-control/index.md)). |
| Błędy przenoszone w wyniku | `OL_E_RUNTIME_OPERATION_UNKNOWN`, `OL_E_RUNTIME_ARGUMENT_REQUIRED` (rejestr); `OL_E_RUNTIME_RESPONSE_TOO_LARGE` (wynik wtyczki przekroczył rozmiar skrzynki; wyniki w postaci list ograniczonych są zamiast tego skracane z `truncated=true`); `OL_E_RUNTIME_SETTING_NOT_PERSISTENT` (`weather.set`, zawsze); każdy kod `OL_E_D3D_*` (z `Values["detail"]` i `Values["native_status"]`); oraz `OL_E_RUNTIME_OPERATION_FAILED` dla każdego innego błędu po stronie wtyczki. W tym ostatnim przypadku konkretny kod nie znajduje się w `ErrorCode`: jest pierwszym tokenem `Values["detail"]` (na przykład `detail = "OL_E_RUNTIME_OBJECT_HANDLE_STALE"`, `exception = "InvalidOperationException"`). Kody przekazywane w ten sposób: `OL_E_RUNTIME_OPERATION_UNAVAILABLE`, `OL_E_RUNTIME_ARGUMENT_REQUIRED` (sprawdzenia po stronie wtyczki), `OL_E_RUNTIME_VALUE_OUT_OF_RANGE`, `OL_E_RUNTIME_VALUE_INVALID`, `OL_E_RUNTIME_OBJECT_HANDLE_REQUIRED`, `OL_E_RUNTIME_OBJECT_HANDLE_STALE`, `OL_E_RUNTIME_SCRIPT_OBJECT_UNAVAILABLE`, `OL_E_RUNTIME_VARIABLE_NOT_FOUND`, `OL_E_RUNTIME_VARIABLE_UNAVAILABLE`, `OL_E_RUNTIME_STRING_VARIABLE_NOT_FOUND`, `OL_E_RUNTIME_CONSTANT_NOT_FOUND`, `OL_E_RUNTIME_CONSTANTS_UNAVAILABLE`, `OL_E_RUNTIME_CURVE_NOT_FOUND`, `OL_E_RUNTIME_CURVE_EMPTY`, `OL_E_RUNTIME_CURVE_DEGENERATE`, `OL_E_RUNTIME_CURVE_INVALID`, `OL_E_RUNTIME_HOF_UNAVAILABLE`, `OL_E_RUNTIME_PLAYER_VEHICLE_UNAVAILABLE`, `OL_E_CAMERA_PRESET_FAMILY_UNSUPPORTED`, `OL_E_TIME_APPLY_FAILED`, `OL_E_RUNTIME_BUS_IDENTITY_INVALID`, `OL_E_MAKEVEHICLE_BUS_NOT_FOUND`, `OL_E_MAKEVEHICLE_DELTA_ZERO`, `OL_E_MAKEVEHICLE_DELTA_MULTIPLE`, `OL_E_MAKEVEHICLE_NATIVE_FAILED`, `OL_E_RUNTIME_CREATED_OBJECT_NOT_IN_COLLECTION`, `OL_E_RUNTIME_CREATED_OBJECT_INVALID`, `OL_E_PLACE_RANDOM_BUS_FAILED`, `OL_E_RUNTIME_SETTING_UNAVAILABLE`. Zob. [kody błędów](https://omsilaunch.omsimods.com.br/pl/docs/reference/errors/index.md). |
| Zgłaszane wyjątki | `KeyNotFoundException`; `InvalidOperationException` z `OL_E_RUNTIME_SESSION_MISMATCH`, `OL_E_SESSION_NOT_RUNNING`, `OL_E_RUNTIME_CHANNEL_CLOSED` (skrzynka już zwolniona przez nadzorcę), `OL_E_RUNTIME_CHANNEL_BUSY` (slot nadal zawiera porzucone żądanie), `OL_E_RUNTIME_REQUEST_ID_REUSED` (w slocie nadal znajduje się nieaktualna odpowiedź dla tego samego identyfikatora żądania); `TimeoutException("OL_E_RUNTIME_REQUEST_TIMEOUT")`; `InvalidDataException("OL_E_RUNTIME_RESPONSE_INVALID")` (uszkodzona, obca lub niepasująca odpowiedź); `ArgumentOutOfRangeException`, gdy zserializowane żądanie przekracza rozmiar skrzynki; `OperationCanceledException`. |
| Anulowanie | Respektowane podczas oczekiwania na bramkę sesji oraz co 20 ms podczas odpytywania o odpowiedź. Anulowanie w trakcie wykonywania nie resetuje slotu: następne wywołanie w tej sesji może kończyć się błędem `OL_E_RUNTIME_CHANNEL_BUSY`, dopóki wtyczka nie opublikuje odpowiedzi (która jest wtedy odrzucana jako nieaktualna). Zalecany jest limit czasu; przekroczenie limitu czasu resetuje slot, a spóźniona odpowiedź jest wykrywana i odrzucana. |
| Wymagana sesja w stanie Running | Tak (`SessionState.Running`); w przeciwnym razie zgłaszany jest `OL_E_SESSION_NOT_RUNNING`. Skrzynka istnieje, dopóki nadzorca nie zwolni jej podczas przywracania. |
| Modyfikuje stan OMSI | Zależy od operacji: operacje `Read` nie modyfikują; operacje `Write`/`Action` (`time.set`, `camera.set`, `camera.lock`, `camera.unlock`, `road-vehicles.spawn`, `road-vehicles.place-random`, `vehicle.variable.set`, `d3d.texture.*`) modyfikują stan wewnątrz procesu, który nie jest przywracany. |
| Modyfikuje system plików | Brak zapisów po stronie hosta. OMSI może w konsekwencji zapisywać własne pliki (nieśledzone). |
| Transakcja / przywracanie | Brak. |
| Ograniczenia | Jedno trwające polecenie na sesję (wywołania w tej samej sesji są serializowane). Żądanie i odpowiedź są każde ograniczone do 64 KiB minus 8 bajtów; dane pikseli D3D do 48 KiB. `internal.road-vehicles.make-basic` ma status `INTERNAL` i jest nieosiągalna. `weather.set` ma status `UNAVAILABLE`. `timetable.logs.read` nie jest ograniczona i przy dużych rozkładach jazdy może zwrócić `OL_E_RUNTIME_RESPONSE_TOO_LARGE`. `camera.lock` ma status `EXPERIMENTAL`; wymaga pojazdu gracza i jest zweryfikowana w runtime (`CAM01`), choć ciąg `RuntimeValidation` w rejestrze nadal brzmi `STATICALLY_VALIDATED`. Uchwyty (`rv-NNNNNN`, `hb-NNNNNN`, `d3dtex--`) mają zasięg sesji. |
| Stabilność | Transport i kontrakt: `STABLE_BETA`; stabilność poszczególnych operacji wynika z `PublicCapabilityRegistry` (`PublicStableBeta` → `STABLE_BETA`, `PublicExperimental` → `EXPERIMENTAL`) z powyższymi wyjątkami. |
| Przykład | `var r = await launch.ExecuteRuntimeAsync(session, new RuntimeCommand(session.SessionId, 42, "road-vehicle.read", new Dictionary { ["handle"] = "rv-000001" }), TimeSpan.FromSeconds(5)); if (!r.Succeeded) Console.WriteLine($"{r.ErrorCode} {r.Values?["detail"]}");` |
### `GetCapabilitiesAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task> GetCapabilitiesAsync(InstallationSpec installation, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Zwraca spis dowodów produktu dla instalacji: stałą listę wpisów `Capability(Name, Available, EvidenceState, Reason)` utrzymywaną w `OmsiLaunchService`. Obliczany jest tylko `runtime.current-windows-x64` (na podstawie wykrywania platformy); każdy inny wpis jest stały. |
| Parametry | `installation.RootPath`: katalog używany do sondy platformy (możliwość zapisu wymaga, aby katalog istniał, nie był tylko do odczytu i zawierał `plugins\`). `ExpectedExecutableSha256` jest ignorowany. |
| Zwraca | 51 wpisów, na przykład `runtime.time.read` (`RUNTIME_VALIDATED`), `runtime.weather.write` (`false`, `RUNTIME_PARTIAL`), `world.last-map-state` (`false`, `UNSUPPORTED_FOR_CURRENT_PROFILE`), `world.date.explicit` (`false`, `STATICALLY_PARTIAL`), `content.maps` (`STATICALLY_VALIDATED`), `runtime.d3d.lifecycle.reset` (`IMPLEMENTED_NOT_RUNTIME_VALIDATED`). |
| Różnica względem `PublicCapabilityRegistry` | `PublicCapabilityRegistry.All` to katalog powierzchni sterowania ustalany w czasie kompilacji (36 deskryptorów z klasyfikacją, rodzajem, ścieżkami API i CLI, wymaganymi argumentami), który egzekwują API i CLI; nie zależy od instalacji. `GetCapabilitiesAsync` to raport dowodów z runtime (stan weryfikacji i uzasadnienia). Rejestr służy do decydowania, co wolno wywołać; ta lista – do decydowania, co zostało udowodnione. Żadna z list nie jest wyprowadzana z drugiej. |
| Zgłaszane wyjątki | `OperationCanceledException` przy wejściu; `ArgumentException` dla pustej ścieżki katalogu głównego. |
| Anulowanie | Sprawdzane raz, przy wejściu. |
| Wymagana sesja w stanie Running | Nie. |
| Modyfikuje OMSI / system plików / transakcję | Nie / Nie / Brak. |
| Stabilność | Kontrakt wywołania: `STABLE_BETA`; zawartość listy jest ręcznie utrzymywanym spisem: `PARTIAL`. |
| Przykład | `foreach (var c in await launch.GetCapabilitiesAsync(new InstallationSpec(root))) Console.WriteLine($"{c.Name} {c.Available} {c.EvidenceState} {c.Reason}");` |
### `DiscoverAsync`
| Aspekt | Szczegóły |
| --- | --- |
| Sygnatura | `Task> DiscoverAsync(InstallationSpec installation, ContentQueryKind query, OptionalValue scope = default, CancellationToken cancellationToken = default)` |
| Przeznaczenie | Wylicza zainstalowaną zawartość i zwraca kanoniczne tożsamości, których można użyć w `LaunchSpec`. Wykrywanie pomija punkty ponownej analizy (reparse points) – cykle połączeń (junction) nie mogą go zawiesić – odczytuje pliki OMSI jako Windows-1252 (respektując UTF-8/UTF-16 oznaczone BOM) i nigdy nie podąża za dowiązaniami symbolicznymi. |
| Parametry | `query` i `scope` zgodnie z poniższą tabelą. `scope` jest wymagany dla `Entrypoints` (tożsamość mapy), `Repaints`, `FleetNumbers`, `Registrations` (tożsamość pojazdu). |
| Zwraca | Posortowaną listę `ContentIdentity(Identity, Kind, DisplayName)`. Tożsamości są ścieżkami względnymi wobec instalacji z ukośnikami odwrotnymi; porównania nie rozróżniają wielkości liter. |
| Zgłaszane wyjątki | `OperationCanceledException` przy wejściu; `ArgumentException`, gdy `Entrypoints` jest odpytywany bez zakresu lub katalog główny jest pusty; `FileNotFoundException` (bez kodu `OL_E_`; CLI mapuje go na `OL_E_NOT_FOUND`), gdy mapa lub pojazd wskazany w zakresie nie jest zainstalowany. Brak katalogu głównego lub katalogu zawartości daje pustą listę, a nie błąd. |
| Anulowanie | Sprawdzane raz, przy wejściu. |
| Wymagana sesja w stanie Running | Nie. |
| Modyfikuje OMSI / system plików / transakcję | Nie / Nie / Brak. |
| Stabilność | `Maps`, `Situations`, `Vehicles`: `STABLE_BETA` (każdy plan zweryfikowany w runtime jest rozwiązywany za ich pośrednictwem). `Entrypoints`, `Repaints`, `Hofs`, `FleetNumbers`, `Registrations`, `Addons`: `EXPERIMENTAL` (wyłącznie dowody statyczne). |
| Przykład | `var maps = await launch.DiscoverAsync(new InstallationSpec(root), ContentQueryKind.Maps); var entries = await launch.DiscoverAsync(new InstallationSpec(root), ContentQueryKind.Entrypoints, OptionalValue.Set(maps[0].Identity));` |
Wartości `ContentQueryKind` i wyniki:
| Wartość | Zakres | `Identity` | `Kind` | `DisplayName` |
| --- | --- | --- | --- | --- |
| `Maps` | brak | `maps\\global.cfg` | `map` | nazwa katalogu mapy |
| `Situations` | brak | `situations\...\.osn` | `situation` | tożsamość mapy wskazanej w `.osn` (może mieć wartość `null`) |
| `Vehicles` | brak | `Vehicles\...\.bus` | `vehicle` | `[friendlyname]` lub nazwa pliku |
| `Repaints` | tożsamość pojazdu (wymagana; bez niej: pusta lista) | `#item:` | `repaint` | nazwa `[item]` |
| `Hofs` | brak | `Vehicles\...\.hof` | `hof` | `null` |
| `FleetNumbers` | tożsamość pojazdu (wymagana; bez niej: pusta lista) | ścieżka źródłowa `[number]` względna wobec pojazdu | `fleet-number` | `null` |
| `Registrations` | tożsamość pojazdu (wymagana; bez niej: pusta lista) | `registration_automatic` / `registration_list` / `registration_free` | `registration` | pierwszy wiersz wartości (`null` dla trybu free) |
| `Addons` | brak | `Addons\` | `addon` | `directory-only` |
| `Entrypoints` | tożsamość mapy (wymagana; bez niej: `ArgumentException`) | `