namespace CVRManager.Models; public class AppConfig { public string LibraryRoot { get; set; } = ""; public string SteamUser { get; set; } = ""; public string SteamToken { get; set; } = ""; public string GitHubToken { get; set; } = ""; public string Theme { get; set; } = "Default"; public bool CacheGuard { get; set; } = true; public bool CheckUpdates { get; set; } = true; public List Installs { get; set; } = new(); public List Mods { get; set; } = new(); public List Unlocked { get; set; } = new(); public List Hooks { get; set; } = new(); public List Accounts { get; set; } = new(); public List Sources { get; set; } = new(); public List SeededSources { get; set; } = new(); } public class GameAccount { public string Id { get; set; } = Guid.NewGuid().ToString("N")[..8]; public string Name { get; set; } = ""; public string Username { get; set; } = ""; public string UserId { get; set; } = ""; public string AccessKey { get; set; } = ""; } public record AccountChoice(string Id, string Name); public class SourceDef { public const string CvrmgId = "cvrmg"; public string Id { get; set; } = Guid.NewGuid().ToString("N")[..8]; public string Name { get; set; } = ""; public string Kind { get; set; } = "github"; public string Repo { get; set; } = ""; public bool Builtin { get; set; } } public class HookDef { public const string BeforeUpdateEvent = "BeforeUpdate"; public const string AfterUpdateEvent = "AfterUpdate"; public const string BeforeLaunchEvent = "BeforeLaunch"; public string Id { get; set; } = Guid.NewGuid().ToString("N")[..8]; public string Name { get; set; } = "New hook"; public string Command { get; set; } = ""; public string Arguments { get; set; } = ""; public bool BeforeUpdate { get; set; } public bool AfterUpdate { get; set; } = true; public bool BeforeLaunch { get; set; } public bool DefaultOn { get; set; } = true; public bool Runs(string evt) => evt switch { BeforeUpdateEvent => BeforeUpdate, AfterUpdateEvent => AfterUpdate, BeforeLaunchEvent => BeforeLaunch, _ => false, }; } public class UnlockedBranch { public string Name { get; set; } = ""; public string Code { get; set; } = ""; public string Key { get; set; } = ""; } public class InstallInfo { public string Id { get; set; } = Guid.NewGuid().ToString("N")[..8]; public string Name { get; set; } = ""; public string Folder { get; set; } = ""; public string Branch { get; set; } = "public"; public string BranchPassword { get; set; } = ""; public string LaunchArgs { get; set; } = ""; public string LaunchMode { get; set; } = "desktop"; public string AccountId { get; set; } = ""; public List Mods { get; set; } = new(); public List HookIds { get; set; } = new(); public Dictionary> Deployed { get; set; } = new(); } public class ModAssignment { public string ModId { get; set; } = ""; public string Version { get; set; } = "latest"; public bool Enabled { get; set; } = true; } public class ModDef { public const string MelonLoaderId = "melonloader"; public string Id { get; set; } = Guid.NewGuid().ToString("N")[..8]; public string Name { get; set; } = ""; public string Repo { get; set; } = ""; public string Type { get; set; } = "Mods"; public string AssetFilter { get; set; } = ""; public bool Local { get; set; } public string Source { get; set; } = "github"; public int CvrmgId { get; set; } public string FileName { get; set; } = ""; public string Author { get; set; } = ""; public string Description { get; set; } = ""; public string LatestVersion { get; set; } = ""; public string Category { get; set; } = ""; public string Status { get; set; } = ""; public string SourceLink { get; set; } = ""; public List Releases { get; set; } = new(); public void SetReleases(List fresh) { var keep = Releases.Where(r => fresh.All(f => f.Tag != r.Tag) && (r.Snapshot || Source == "cvrmg")).ToList(); Releases = fresh.Concat(keep).ToList(); } public string? LatestTag => (Releases.FirstOrDefault(r => !r.Prerelease) ?? Releases.FirstOrDefault())?.Tag; } public class ReleaseInfo { public string Tag { get; set; } = ""; public bool Prerelease { get; set; } public bool Snapshot { get; set; } public string GameVersion { get; set; } = ""; public string LoaderVersion { get; set; } = ""; public DateTime Published { get; set; } public List Assets { get; set; } = new(); } public class AssetInfo { public string Name { get; set; } = ""; public string Url { get; set; } = ""; public long Size { get; set; } public string Hash { get; set; } = ""; } public record BranchInfo(string Name, string BuildId, bool PasswordRequired, string Description); public record BranchChoice(string Name, string Code) { public string Display => Name; } public record LaunchArgOption(string Flag, string Description, bool TakesValue) { public string Insert => TakesValue ? Flag[..(Flag.IndexOf('=') + 1)] : Flag; public static IReadOnlyList All { get; } = new[] { new LaunchArgOption("-vr", "Launch in VR.", false), new LaunchArgOption("--force-openxr", "Force OpenXR for VR sessions.", false), new LaunchArgOption("--no-steam", "Skip Steam API initialization.", false), new LaunchArgOption("--safe-mode", "Load the default Hub world and avatar, and disable OSC.", false), new LaunchArgOption("--profile=", "Profile used to save and load the autologin file.", true), new LaunchArgOption("--affinity=", "CPU cores the game may run on, as a hexadecimal mask.", true), new LaunchArgOption("--content-cache-path=", "Use a different directory for the content cache.", true), new LaunchArgOption("--allow-aggressive-memory-clearing", "Reclaim unused memory when content unloads.", false), new LaunchArgOption("--disable-videoplayers", "Disable video players completely.", false), new LaunchArgOption("--disable-vphd", "Turn off video player hardware decoding.", false), new LaunchArgOption("--enable-libvlc", "Use LibVLC instead of AVPro in video players.", false), new LaunchArgOption("--osc-listener-port=", "UDP port that receives OSC messages.", true), new LaunchArgOption("--osc-sender-port=", "UDP port OSC messages are sent to.", true), new LaunchArgOption("--osc-sender-ip=", "Target address for sent OSC messages.", true), new LaunchArgOption("--osc-query-prefix=", "Prefix for OSC query parameters.", true), new LaunchArgOption("--melonloader.hideconsole", "MelonLoader: hide the console window.", false), new LaunchArgOption("-screen-fullscreen 0", "Unity: start windowed.", false), new LaunchArgOption("-popupwindow", "Unity: borderless window.", false), new LaunchArgOption("-screen-width 1280", "Unity: window width.", false), new LaunchArgOption("-screen-height 720", "Unity: window height.", false), new LaunchArgOption("-monitor 2", "Unity: open on this display (1 is the primary).", false), new LaunchArgOption("-force-d3d11", "Unity: force the Direct3D 11 renderer.", false), new LaunchArgOption("-force-vulkan", "Unity: force the Vulkan renderer.", false), }; } public record LaunchModeOption(string Key, string Label, string Arguments) { public static IReadOnlyList All { get; } = new[] { new LaunchModeOption("desktop", "Desktop", ""), new LaunchModeOption("vr", "VR", "-vr"), new LaunchModeOption("safe", "Safe mode", "--safe-mode"), }; public static LaunchModeOption Find(string key) => All.FirstOrDefault(m => m.Key == key) ?? All[0]; }