diff --git a/LANCommander.SDK.SourceGenerators/CmdletRegistrationGenerator.cs b/LANCommander.SDK.SourceGenerators/CmdletRegistrationGenerator.cs new file mode 100644 index 00000000..c802a825 --- /dev/null +++ b/LANCommander.SDK.SourceGenerators/CmdletRegistrationGenerator.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace LANCommander.SDK.SourceGenerators; + +[Generator] +public class CmdletRegistrationGenerator : IIncrementalGenerator +{ + public void Initialize(IncrementalGeneratorInitializationContext context) + { + var cmdletClasses = context.SyntaxProvider + .ForAttributeWithMetadataName( + "System.Management.Automation.CmdletAttribute", + predicate: static (node, _) => node is ClassDeclarationSyntax, + transform: static (ctx, _) => GetCmdletInfo(ctx)) + .Where(static info => info is not null) + .Select(static (info, _) => info!.Value); + + context.RegisterSourceOutput( + cmdletClasses.Collect(), + static (spc, cmdlets) => Execute(spc, cmdlets)); + } + + private static CmdletInfo? GetCmdletInfo(GeneratorAttributeSyntaxContext context) + { + var typeSymbol = (INamedTypeSymbol)context.TargetSymbol; + + foreach (var attr in typeSymbol.GetAttributes()) + { + if (attr.AttributeClass?.ToDisplayString() != "System.Management.Automation.CmdletAttribute") + continue; + + if (attr.ConstructorArguments.Length < 2) + continue; + + var verb = attr.ConstructorArguments[0].Value?.ToString(); + var noun = attr.ConstructorArguments[1].Value?.ToString(); + + if (verb is null || noun is null) + continue; + + return new CmdletInfo + { + CmdletName = $"{verb}-{noun}", + FullTypeName = typeSymbol.ToDisplayString() + }; + } + + return null; + } + + private static void Execute(SourceProductionContext context, ImmutableArray cmdlets) + { + if (cmdlets.IsDefaultOrEmpty) + return; + + var sorted = cmdlets.OrderBy(c => c.CmdletName).ToList(); + + var sb = new StringBuilder(); + sb.AppendLine("// "); + sb.AppendLine("using System.Management.Automation.Runspaces;"); + sb.AppendLine(); + sb.AppendLine("namespace LANCommander.SDK.PowerShell.Extensions;"); + sb.AppendLine(); + sb.AppendLine("public static class InitialSessionStateExtensions"); + sb.AppendLine("{"); + sb.AppendLine(" public static void AddCustomCmdlets(this InitialSessionState initialSessionState)"); + sb.AppendLine(" {"); + + foreach (var cmdlet in sorted) + { + sb.AppendLine($" initialSessionState.Commands.Add(new SessionStateCmdletEntry(\"{cmdlet.CmdletName}\", typeof({cmdlet.FullTypeName}), null));"); + } + + sb.AppendLine(" }"); + sb.AppendLine("}"); + + context.AddSource("InitialSessionStateExtensions.g.cs", sb.ToString()); + } + + private struct CmdletInfo + { + public string CmdletName; + public string FullTypeName; + } +} diff --git a/LANCommander.SDK.SourceGenerators/LANCommander.SDK.SourceGenerators.csproj b/LANCommander.SDK.SourceGenerators/LANCommander.SDK.SourceGenerators.csproj new file mode 100644 index 00000000..3361c215 --- /dev/null +++ b/LANCommander.SDK.SourceGenerators/LANCommander.SDK.SourceGenerators.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.0 + latest + true + true + + + + + + + diff --git a/LANCommander.SDK/LANCommander.SDK.csproj b/LANCommander.SDK/LANCommander.SDK.csproj index 84762c64..4d3b4d48 100644 --- a/LANCommander.SDK/LANCommander.SDK.csproj +++ b/LANCommander.SDK/LANCommander.SDK.csproj @@ -55,6 +55,9 @@ + diff --git a/LANCommander.SDK/PowerShell/Cmdlets/Get-SanitizedPath.cs b/LANCommander.SDK/PowerShell/Cmdlets/Get-SanitizedPath.cs new file mode 100644 index 00000000..fc35bb1b --- /dev/null +++ b/LANCommander.SDK/PowerShell/Cmdlets/Get-SanitizedPath.cs @@ -0,0 +1,19 @@ +using LANCommander.SDK.Extensions; +using System.IO; +using System.Management.Automation; + +namespace LANCommander.SDK.PowerShell.Cmdlets +{ + [Cmdlet(VerbsCommon.Get, "SanitizedPath")] + [OutputType(typeof(string))] + public class GetSanitizedPathCmdlet : Cmdlet + { + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The path to sanitize.")] + public string Path { get; set; } + + protected override void ProcessRecord() + { + WriteObject(Path.SanitizeFilename()); + } + } +} diff --git a/LANCommander.SDK/PowerShell/Extensions/InitialSessionStateExtensions.cs b/LANCommander.SDK/PowerShell/Extensions/InitialSessionStateExtensions.cs deleted file mode 100644 index 41c92973..00000000 --- a/LANCommander.SDK/PowerShell/Extensions/InitialSessionStateExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Management.Automation.Runspaces; -using LANCommander.SDK.PowerShell.Cmdlets; - -namespace LANCommander.SDK.PowerShell.Extensions; - -public static class InitialSessionStateExtensions -{ - public static void AddCustomCmdlets(this InitialSessionState initialSessionState) - { - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Convert-AspectRatio", typeof(ConvertAspectRatioCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("ConvertFrom-SerializedBase64", typeof(ConvertFromSerializedBase64Cmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("ConvertTo-SerializedBase64", typeof(ConvertToSerializedBase64Cmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("ConvertTo-StringBytes", typeof(ConvertToStringBytesCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Edit-PatchBinary", typeof(EditPatchBinaryCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Edit-PatchGameSpy", typeof(EditPatchGameSpy), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-GameManifest", typeof(GetGameManifestCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-HorizontalFov", typeof(GetHorizontalFovCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-PrimaryDisplay", typeof(GetPrimaryDisplayCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-UserCustomField", typeof(GetUserCustomFieldCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-VerticalFov", typeof(GetVerticalFovCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Out-PlayerAvatar", typeof(OutPlayerAvatarCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Update-IniValue", typeof(UpdateIniValueCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Update-UserCustomField", typeof(UpdateUserCustomFieldCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Write-GameManifest", typeof(WriteGameManifestCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("New-Package", typeof(NewPackageCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Write-ReplaceContentInFile", typeof(ReplaceContentInFileCmdlet), null)); - - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Connect-SteamCmd", typeof(ConnectSteamCmdCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Disconnect-SteamCmd", typeof(DisconnectSteamCmdCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamCmdConnectionStatus", typeof(GetSteamCmdConnectionStatusCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamCmdPath", typeof(GetSteamCmdPathCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamCmdProfile", typeof(GetSteamCmdProfileCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamCmdProfiles", typeof(GetSteamCmdProfilesCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Install-SteamContent", typeof(InstallSteamContentCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Remove-SteamContent", typeof(RemoveSteamContentCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Remove-SteamCmdProfile", typeof(RemoveSteamCmdProfileCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Set-SteamCmdProfile", typeof(SetSteamCmdProfileCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamAppInfo", typeof(GetSteamAppInfoCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamWebAssetUri", typeof(GetSteamWebAssetUriCmdlet), null)); - initialSessionState.Commands.Add(new SessionStateCmdletEntry("Search-SteamGames", typeof(SearchSteamGamesCmdlet), null)); - } -} \ No newline at end of file diff --git a/LANCommander.slnx b/LANCommander.slnx index cf0ba2b3..e3a104fb 100644 --- a/LANCommander.slnx +++ b/LANCommander.slnx @@ -43,4 +43,5 @@ + \ No newline at end of file