From f25b366a4d0fcbca8ce13a2b52075b409a10336c Mon Sep 17 00:00:00 2001 From: That_One_Nerd Date: Mon, 15 May 2023 10:50:58 -0400 Subject: [PATCH] Made a bunch of progress parsing mod info, almost done. --- SrcMod/Shell/Game.cs | 46 ++++++- SrcMod/Shell/Mod.cs | 119 ++++++++++++++++++- SrcMod/Shell/ObjectModels/Source/GameInfo.cs | 55 ++++----- 3 files changed, 177 insertions(+), 43 deletions(-) diff --git a/SrcMod/Shell/Game.cs b/SrcMod/Shell/Game.cs index 1a21734..2e0e23c 100644 --- a/SrcMod/Shell/Game.cs +++ b/SrcMod/Shell/Game.cs @@ -1,6 +1,6 @@ namespace SrcMod.Shell; -public class Game +public class Game : IEquatable { public static readonly Game Portal2 = new() { @@ -8,12 +8,48 @@ public class Game NameId = "portal2", SteamId = 620 }; + public static readonly Game Unknown = new() + { + Name = "Unknown Game", + NameId = "unknown", + SteamId = -1, + IsUnknown = true + }; - public required string Name { get; init; } - public required string NameId { get; init; } - public required int SteamId { get; init; } + public string Name { get; private set; } + public string NameId { get; private set; } + public int SteamId { get; private set; } - private Game() { } + public bool IsUnknown { get; private set; } + + private Game() + { + IsUnknown = false; + Name = string.Empty; + NameId = string.Empty; + } + + public static Game FromSteamId(int id) + { + if (id == Portal2.SteamId) return Portal2; + else + { + Game game = (Game)Unknown.MemberwiseClone(); + game.SteamId = id; + return game; + } + } + + public override bool Equals(object? obj) + { + if (obj is Game game) return Equals(game); + return false; + } + public bool Equals(Game? other) => other is not null && SteamId == other.SteamId; + public override int GetHashCode() => base.GetHashCode(); public override string ToString() => Name; + + public static bool operator ==(Game a, Game b) => a.Equals(b); + public static bool operator !=(Game a, Game b) => !a.Equals(b); } diff --git a/SrcMod/Shell/Mod.cs b/SrcMod/Shell/Mod.cs index 843d51f..5386868 100644 --- a/SrcMod/Shell/Mod.cs +++ b/SrcMod/Shell/Mod.cs @@ -2,15 +2,98 @@ public class Mod { + public Game BaseGame { get; set; } + + public string? Developer { get; set; } + public string? DeveloperUrl { get; set; } + public Dictionary SearchPaths { get; set; } // TODO: Replace the keys with a flags enum. + public string? ManualUrl { get; set; } + + public string? FgdDataPath { get; set; } + public string? IconPath { get; set; } + public string? InstancePath { get; set; } + + public PlayerType PlayerMode { get; set; } + + public CrosshairFlags CrosshairMenuFlags { get; set; } + public bool ShowDifficultyMenu { get; set; } + public bool ShowModelMenu { get; set; } + public bool ShowPortalMenu { get; set; } + public SupportFlags SupportingFlags { get; set; } + + public bool HiResModels { get; set; } + + public string[] HiddenMaps { get; set; } + public string Name { get; set; } + public string? Motto { get; set; } + public TitleDisplay TitleDisplayMode { get; set; } + + public bool BuildMapNodegraphs { get; set; } + + public Dictionary? MapbaseLaunchOptions { get; set; } public string RootDirectory { get; set; } private Mod() { + BaseGame = Game.Unknown; + SearchPaths = new(); + HiddenMaps = Array.Empty(); Name = string.Empty; RootDirectory = string.Empty; } + public static Mod FromInfo(string root, GameInfo info) + { + Mod curMod = new() + { + BaseGame = Game.FromSteamId(info.FileSystem.SteamAppID), + BuildMapNodegraphs = info.Nodegraph is not null && info.Nodegraph.Value, + CrosshairMenuFlags = CrosshairFlags.None, + Developer = info.Developer, + DeveloperUrl = info.Developer_URL, + FgdDataPath = info.GameData, + HiddenMaps = info.Hidden_Maps is null ? Array.Empty() : info.Hidden_Maps.Keys.ToArray(), + HiResModels = info.NoHIModel is null || !info.NoHIModel.Value, + IconPath = info.Icon is null ? null : info.Icon.Trim().Replace('/', '\\') + ".tga", + InstancePath = info.InstancePath, + MapbaseLaunchOptions = info.CommandLine, + ManualUrl = info.Manual, + Motto = info.Title2, + Name = string.IsNullOrEmpty(info.Title) ? "Default Mod" : info.Title, + PlayerMode = info.Type is null ? PlayerType.Both : info.Type.Trim().ToLower() switch + { + "singleplayer_only" => PlayerType.Singleplayer, + "multiplayer_only" => PlayerType.Multiplayer, + _ => throw new ArgumentException($"Unknown type \"{info.Type}\"") + }, + RootDirectory = root, + SearchPaths = info.FileSystem.SearchPaths, + ShowDifficultyMenu = info.NoDifficulty is null || !info.NoDifficulty.Value, + ShowModelMenu = info.NoModels is null || !info.NoModels.Value, + ShowPortalMenu = info.HasPortals is not null && info.HasPortals.Value, + SupportingFlags = SupportFlags.None, + TitleDisplayMode = info.GameLogo is null ? TitleDisplay.Title : + (info.GameLogo.Value ? TitleDisplay.Logo : TitleDisplay.Title) + }; + if (curMod.PlayerMode == PlayerType.Multiplayer && info.NoDifficulty is null) + curMod.ShowDifficultyMenu = false; + + if (info.NoCrosshair is null || !info.NoCrosshair.Value) + curMod.CrosshairMenuFlags |= CrosshairFlags.ShowMultiplayer; + if (info.AdvCrosshair is not null && info.AdvCrosshair.Value) + curMod.CrosshairMenuFlags |= CrosshairFlags.AdvancedMenu; + + if (info.SupportsDX8 is not null && info.SupportsDX8.Value) + curMod.SupportingFlags |= SupportFlags.DirectX8; + if (info.SupportsVR is not null && info.SupportsVR.Value) + curMod.SupportingFlags |= SupportFlags.VirtualReality; + if (info.SupportsXBox360 is not null && info.SupportsXBox360.Value) + curMod.SupportingFlags |= SupportFlags.XBox360; + + return curMod; + } + public static Mod? ReadDirectory(string dir) { dir = dir.Trim().Replace('/', '\\'); @@ -27,12 +110,7 @@ public class Mod GameInfo? modInfo = SerializeVkv.Deserialize(fs); if (modInfo is null) continue; - Mod mod = new() - { - Name = modInfo.Title, - RootDirectory = check - }; - return mod; + return FromInfo(check, modInfo); } check = Path.GetDirectoryName(check) ?? string.Empty; // Go to parent folder. @@ -42,4 +120,33 @@ public class Mod } public override string ToString() => Name; + + [Flags] + public enum CrosshairFlags + { + None = 0, + ShowMultiplayer = 1, + AdvancedMenu = 2 + } + + [Flags] + public enum SupportFlags + { + None, + DirectX8 = 1, + VirtualReality = 2, + XBox360 = 4 + } + + public enum PlayerType + { + Singleplayer = 1, + Multiplayer = 2, + Both = Singleplayer | Multiplayer + } + public enum TitleDisplay + { + Title, + Logo + } } diff --git a/SrcMod/Shell/ObjectModels/Source/GameInfo.cs b/SrcMod/Shell/ObjectModels/Source/GameInfo.cs index 0833a5f..c65396e 100644 --- a/SrcMod/Shell/ObjectModels/Source/GameInfo.cs +++ b/SrcMod/Shell/ObjectModels/Source/GameInfo.cs @@ -6,58 +6,49 @@ public class GameInfo // Name public string Game; public string Title; - public bool GameLogo; + public string? Title2; + public bool? GameLogo; // Options - public string Type; // TODO: Make this an enum. - public bool NoDifficulty; - public bool HasPortals; - public bool NoCrosshair; - public bool AdvCrosshair; - public bool NoModels; - public bool NoHIModel; + public string? Type; + public bool? NoDifficulty; + public bool? HasPortals; + public bool? NoCrosshair; + public bool? AdvCrosshair; + public bool? NoModels; + public bool? NoHIModel; - public Dictionary Hidden_Maps; - public Dictionary CommandLine; + public Dictionary? Hidden_Maps; + public Dictionary? CommandLine; // Steam games list - public string Developer; - public string Developer_URL; - public string Manual; - public string Icon; + public string? Developer; + public string? Developer_URL; + public string? Manual; + public string? Icon; // Engine and tools - public bool Nodegraph; - public string GameData; - public string InstancePath; - public bool SupportsDX8; - public bool SupportsVR; - public bool SupportsXBox360; + public bool? Nodegraph; + public string? GameData; + public string? InstancePath; + public bool? SupportsDX8; + public bool? SupportsVR; + public bool? SupportsXBox360; public FileSystemData FileSystem; public GameInfo() { Game = string.Empty; Title = string.Empty; - Type = string.Empty; - Hidden_Maps = new(); - CommandLine = new(); - Developer = string.Empty; - Developer_URL = string.Empty; - Manual = string.Empty; - Icon = string.Empty; - GameData = string.Empty; FileSystem = new(); - InstancePath = string.Empty; } public class FileSystemData { public int SteamAppID; - public int AdditionalContentId; - public int ToolsAppId; + public int? AdditionalContentId; + public int? ToolsAppId; - // Can't make the keys here enums because they can be strung together, public Dictionary SearchPaths; public FileSystemData()