diff --git a/.editorconfig b/.editorconfig index 74f895e..4cee979 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,8 +1,18 @@ +#TODO move this to lancache common root = true [*] end_of_line = lf +[*.js] +indent_style = tab +tab_size = 4 +curly_bracket_next_line = true + +[*.py] +indent_style = tab +tab_size = 4 + # .NET formatting rules. See https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/formatting-rules # Resharper Rules. See https://www.jetbrains.com/help/resharper/EditorConfig_Index.html [*.cs] @@ -23,12 +33,16 @@ space_between_attribute_sections = false # CA1002: Do not expose generic lists dotnet_diagnostic.CA1002.severity = none +# CA1008: Enums should have zero value +# - The enums in this case are modeling Steam enums, so I have to match them exactly. +dotnet_diagnostic.CA1008.severity = none # CA1014: Mark assemblies with CLSCompliant dotnet_diagnostic.CA1014.severity = none # CA1031: Modify (method) to catch a more specific allowed exception type, or rethrow the exception dotnet_diagnostic.CA1031.severity = none # CA1034: Nested types should not be visible dotnet_diagnostic.CA1034.severity = none + # CA1051: Do not declare visible instance fields dotnet_diagnostic.CA1051.severity = none # CA1054: URI parameters should not be strings @@ -39,6 +53,7 @@ dotnet_diagnostic.CA1056.severity = none dotnet_diagnostic.CA1062.severity = none # CA1305: The behavior of 'int.Parse(string)' could vary based on the current user's locale settings. dotnet_diagnostic.CA1305.severity = none +# CA1307: Specify StringComparison for clarity dotnet_diagnostic.CA1307.severity = none dotnet_diagnostic.CA1310.severity = none # CA1815: Override equals and operator equals on value types @@ -64,11 +79,22 @@ dotnet_diagnostic.cs1998.severity = error # CS4014: Because this call is not awaited, execution of the current method continues before the call is completed dotnet_diagnostic.cs4014.severity = error +# IDE0028: Simplify collection initialization +# - Not a fan of the syntax, feels a little bit too terse +dotnet_style_prefer_collection_expression = false + # IDE0090 : 'new' expression can be simplified csharp_style_implicit_object_creation_when_type_is_apparent = false +# IDE0290: Use primary constructor +# - I'm a fan of this syntax in Typescript, but it still feels a bit too jarring seeing it C# now +csharp_style_prefer_primary_constructors = false + + # Banned APIs will be bumped up to an error instead of warning dotnet_diagnostic.rs0030.severity = error # The method does not need to use async/await - Introduces annoying 'return' statements for async methods, that hurt code readability. -dotnet_diagnostic.AsyncFixer01.severity = none \ No newline at end of file +dotnet_diagnostic.AsyncFixer01.severity = none + + diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 8c20e65..3378f07 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -6,123 +6,13 @@ on: tags: - '*' -env: - # Used to parameterize these build scripts between LancachePrefill projects - PROJECT_NAME: EpicPrefill - permissions: contents: write # Required to create a release jobs: - # Needed in order to prevent softprops/action-gh-release from creating duplicate releases for each publish target. - # The duplicate releases happen because of a race condition, where each parallel publish job thinks the release has not yet been created. - create-placeholder-release: - runs-on: ubuntu-latest - container: mcr.microsoft.com/dotnet/sdk:8.0 - steps: - - uses: actions/checkout@v3 - with: - submodules: true - # Gets the executable version that will be used later in the uploaded zip file name - - name: Set Version - id: vars - run: | - version=$(grep -Po '(?<=)(.*?)(?=)' $PROJECT_NAME/$PROJECT_NAME.csproj); - echo "version=$version" >> $GITHUB_OUTPUT; - - name: Create Release - uses: softprops/action-gh-release@v1 - if: startsWith(github.ref, 'refs/tags/') - with: - draft: true - name: "v${{ steps.vars.outputs.version }}" - files: "**/*.zip" - generate_release_notes: true - - dotnet-publish: - runs-on: ubuntu-latest - container: mcr.microsoft.com/dotnet/sdk:8.0 - needs: create-placeholder-release - strategy: - matrix: - runtime: ['win-x64', 'linux-x64', 'linux-arm64', 'osx-x64'] - fail-fast: false - steps: - - uses: actions/checkout@v3 - with: - submodules: true - # Gets the executable version that will be used later in the uploaded zip file name - - name: Set Version - id: vars - run: | - version=$(grep -Po '(?<=)(.*?)(?=)' $PROJECT_NAME/$PROJECT_NAME.csproj); - echo "version=$version" >> $GITHUB_OUTPUT; - - run: apt-get update - - run: apt-get install zip -y - - name: Publish - run: > - version=${{ steps.vars.outputs.version }} - - dotnet publish $PROJECT_NAME/$PROJECT_NAME.csproj \ - --nologo \ - -o "publish/$PROJECT_NAME-$version-${{ matrix.runtime }}" \ - -c Release \ - --runtime "${{ matrix.runtime }}"; - - cd publish; - - zip -r $PROJECT_NAME-$version-${{ matrix.runtime }}.zip $PROJECT_NAME-$version-${{ matrix.runtime }}; - cp $PROJECT_NAME-$version-${{ matrix.runtime }}.zip ../; - rm $PROJECT_NAME-$version-${{ matrix.runtime }}.zip; - cd ..; - - name: Upload - uses: actions/upload-artifact@v3 - with: - name: EpicPrefill-${{ steps.vars.outputs.version }}-${{ matrix.runtime }} - path: publish/ - if-no-files-found: error - - name: Create Release - uses: softprops/action-gh-release@v1 - if: startsWith(github.ref, 'refs/tags/') - with: - draft: true - name: "v${{ steps.vars.outputs.version }}" - files: "**/*.zip" - generate_release_notes: true - docker-publish-x64: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - name: Setup .NET - uses: actions/setup-dotnet@v2 - with: - dotnet-version: 8.0.x - - name: Publish - run: > - dotnet publish $PROJECT_NAME/$PROJECT_NAME.csproj \ - --nologo \ - -o publish \ - -c Release \ - --runtime "linux-x64" \ - --self-contained true \ - /p:PublishSingleFile=true \ - /p:PublishReadyToRun=true \ - /p:PublishTrimmed=true - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Extract metadata for Docker - id: meta - uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 - with: - images: tpill90/epic-lancache-prefill - - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file + release-publish: + uses: tpill90/lancache-prefill-common/.github/workflows/release-publish-template.yml@main + secrets: inherit + with: + PROJECT_NAME: EpicPrefill + DOCKERHUB_NAME: epic-lancache-prefill \ No newline at end of file diff --git a/EpicPrefill.sln.DotSettings b/EpicPrefill.sln.DotSettings index c0f67fc..8242741 100644 --- a/EpicPrefill.sln.DotSettings +++ b/EpicPrefill.sln.DotSettings @@ -4,6 +4,7 @@ DO_NOT_SHOW WARNING WARNING + DO_NOT_SHOW WARNING WARNING WARNING @@ -13,6 +14,7 @@ SUGGESTION DO_NOT_SHOW DO_NOT_SHOW + DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW diff --git a/EpicPrefill/EpicGamesManager.cs b/EpicPrefill/EpicGamesManager.cs index ff7adb3..03d9e22 100644 --- a/EpicPrefill/EpicGamesManager.cs +++ b/EpicPrefill/EpicGamesManager.cs @@ -122,16 +122,10 @@ private async Task DownloadSingleAppAsync(GameAsset app) } } - //TODO rename to something like GetAvailableGames? //TODO should this just be merged with GetOwnedAppsAsync? public async Task> GetAllAvailableAppsAsync() { - var ownedApps = await _epicApi.GetOwnedAppsAsync(); - - // Unreal Engine needs to be filtered out as adding even a single version of it spams select-apps with a huge number of entries - return ownedApps.Where(e => !e.Title.Contains("Unreal Engine") && !e.Title.Contains("Quixel Bridge")) - .OrderBy(e => e.Title, StringComparer.OrdinalIgnoreCase) - .ToList(); + return await _epicApi.GetOwnedAppsAsync(); } #region Select Apps diff --git a/EpicPrefill/Handlers/EpicGamesApi.cs b/EpicPrefill/Handlers/EpicGamesApi.cs index 54e4767..5695fe6 100644 --- a/EpicPrefill/Handlers/EpicGamesApi.cs +++ b/EpicPrefill/Handlers/EpicGamesApi.cs @@ -1,7 +1,7 @@ namespace EpicPrefill.Handlers { // TODO document - public class EpicGamesApi + public sealed class EpicGamesApi { private readonly IAnsiConsole _ansiConsole; private readonly HttpClientFactory _httpClientFactory; @@ -19,6 +19,7 @@ public EpicGamesApi(IAnsiConsole ansiConsole, HttpClientFactory httpClientFactor } //TODO comment + //TODO this method has a few too many things going on here between the http request then the metadata population internal async Task> GetOwnedAppsAsync() { //TODO this should probably be a status spinner @@ -38,14 +39,21 @@ internal async Task> GetOwnedAppsAsync() using var responseContent = await response.Content.ReadAsStreamAsync(); var ownedApps = await JsonSerializer.DeserializeAsync(responseContent, SerializationContext.Default.ListGameAsset); - var appMetadata = await LoadAppMetadataAsync(ownedApps); - foreach (var app in ownedApps) + // Removing anything related to unreal engine. We're only interested in actual games + var filteredApps = ownedApps.Where(e => e.Namespace != "ue") + // This namespace is related to unreal assets + .Where(e => e.Namespace != "89efe5924d3d467c839449ab6ab52e7f") + .ToList(); + + var appMetadata = await LoadAppMetadataAsync(filteredApps); + //TODO this part should probably be inside of the load app metadata part + foreach (var app in filteredApps) { app.Title = appMetadata[app.AppId].title; } - _ansiConsole.LogMarkupLine($"Retrieved {Magenta(ownedApps.Count)} owned apps", timer); - return ownedApps; + _ansiConsole.LogMarkupLine($"Retrieved {Magenta(filteredApps.Count)} owned apps", timer); + return filteredApps.OrderBy(e => e.Title, StringComparer.OrdinalIgnoreCase).ToList(); } //TODO comment @@ -61,7 +69,9 @@ private async Task> LoadAppMetadataAsync } // Determine which apps don't already have their metadata loaded - var appsMissingMetadata = apps.Where(e => !metadataDictionary.ContainsKey(e.AppId)).ToList(); + List appsMissingMetadata = apps.Where(e => !metadataDictionary.ContainsKey(e.AppId)) + .OrderBy(e => e.AppId) + .ToList(); // If everything is cached, return if (!appsMissingMetadata.Any()) diff --git a/EpicPrefill/Models/ApiResponses/GameAsset.cs b/EpicPrefill/Models/ApiResponses/GameAsset.cs index b78f945..743d743 100644 --- a/EpicPrefill/Models/ApiResponses/GameAsset.cs +++ b/EpicPrefill/Models/ApiResponses/GameAsset.cs @@ -2,7 +2,7 @@ { //TODO document //TODO rename - public class GameAsset + public sealed class GameAsset { [JsonPropertyName("appName")] public string AppId { get; set; } @@ -21,6 +21,10 @@ public class GameAsset public override string ToString() { + if (Title == null) + { + return $"{AppId} - {Namespace} - {CatalogItemId}"; + } return Title; } } diff --git a/_publish-release.ps1 b/_publish-release.ps1 index f3b7d36..8313e1f 100644 --- a/_publish-release.ps1 +++ b/_publish-release.ps1 @@ -9,6 +9,10 @@ Write-Color "Current version: ", $currentVersion -Color White, Yellow # Getting new version to use $newVersion = Read-Host "Enter new version, with no leading 'v'. Ex. '1.2.3'" +if($newVersion.Contains("v")) +{ + Write-Color $newVersion, " is not a valid version since it has a leading 'v'." -Color Yellow, Red +} # Updating csproj version $currentContent = Get-Content -Path .\EpicPrefill\EpicPrefill.csproj -Raw