Compare commits

...

72 Commits

Author SHA1 Message Date
renovate[bot]
d679bf9307 chore(deps): update asf-ui digest to cd1f819 2025-12-13 02:47:37 +00:00
renovate[bot]
564d0bf9a4 chore(deps): update github artifact actions (#3525)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-12 22:26:26 +01:00
renovate[bot]
2f848fe585 chore(deps): update dessant/lock-threads action to v6 (#3524)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-12 22:24:35 +01:00
renovate[bot]
bf34d2e91e chore(deps): update dependency scalar.aspnetcore to 2.11.6 2025-12-12 17:14:56 +00:00
renovate[bot]
83e4c7f63a chore(deps): update asf-ui digest to ab86669 2025-12-12 05:56:06 +00:00
ArchiBot
1e2e52943d Automatic translations update 2025-12-12 02:30:16 +00:00
Łukasz Domeradzki
4a9ecc52c1 Bump 2025-12-11 20:22:46 +01:00
Łukasz Domeradzki
10fc914ac1 Add Winter Sale 2025 to SalesBlacklist 2025-12-11 20:22:25 +01:00
renovate[bot]
7e9c49cc79 chore(deps): update dependency scalar.aspnetcore to 2.11.5 2025-12-11 06:32:14 +00:00
renovate[bot]
ab58886d29 chore(deps): update asf-ui digest to c703223 2025-12-11 02:38:02 +00:00
ArchiBot
a5740a43db Automatic translations update 2025-12-11 02:30:45 +00:00
renovate[bot]
223f2b98cb chore(deps): update dotnet monorepo to 10.0.1 2025-12-10 06:31:16 +00:00
renovate[bot]
69b150c8a0 chore(deps): update dependency scalar.aspnetcore to 2.11.3 2025-12-10 02:52:39 +00:00
ArchiBot
f4ea1d44ac Automatic translations update 2025-12-10 02:29:24 +00:00
renovate[bot]
d02504b914 chore(deps): update dependency scalar.aspnetcore to 2.11.2 2025-12-09 03:35:28 +00:00
ArchiBot
c363af8c3a Automatic translations update 2025-12-09 02:27:11 +00:00
Łukasz Domeradzki
c06a22ec93 Bump 2025-12-08 23:33:24 +01:00
Łukasz Domeradzki
ed19d7e3bf Misc, bump 2025-12-08 23:32:17 +01:00
Łukasz Domeradzki
4eee2e2ac7 Fix authentication flow when reaching max failures in credentials provider
This one is tricky, previously we've properly handled max failures, and told SK2 to abort the request with operation canceled exception, which we even handled back in bot flow, so it looked OK at first, but the bot didn't do anything with that, which resulted in forced TryAnotherCM disconnection after 1 minute of inactivity.

Since we need to be informed what to do in such case, simple cancellation of flow is not enough, we require a custom exception to handle, which will tell us the precise reason for failure + possible count of them, and that will in result allow us to react accordingly in the bot flow, e.g. by stopping the bot if needed.
2025-12-08 23:25:15 +01:00
Łukasz Domeradzki
90fe1a9448 Bump 2025-12-08 21:55:29 +01:00
Łukasz Domeradzki
8c26dcb7c2 Misc 2025-12-08 21:55:24 +01:00
ArchiBot
ba8150b27a Automatic translations update 2025-12-08 02:28:30 +00:00
ArchiBot
612b3dd3ef Automatic translations update 2025-12-06 02:23:51 +00:00
renovate[bot]
a551568f2b chore(deps): update dependency scalar.aspnetcore to 2.11.1 2025-12-04 20:53:14 +00:00
renovate[bot]
31615ef64d chore(deps): update asf-ui digest to 00bfe2e 2025-12-03 13:05:45 +00:00
renovate[bot]
0f0f1bfcd3 chore(deps): update actions/setup-node action to v6.1.0 2025-12-03 08:41:07 +00:00
renovate[bot]
702e27c466 chore(deps): update asf-ui digest to 93e8a77 2025-12-03 04:40:17 +00:00
renovate[bot]
921263674d chore(deps): update actions/checkout action to v6.0.1 2025-12-02 17:32:57 +00:00
renovate[bot]
5110d6d9f9 chore(deps): update crowdin/github-action action to v2.13.0 2025-12-02 10:40:58 +00:00
ArchiBot
5f622128e4 Automatic translations update 2025-11-30 02:33:42 +00:00
ArchiBot
6eee3fb4d9 Automatic translations update 2025-11-29 02:23:49 +00:00
ArchiBot
0aa777734a Automatic translations update 2025-11-28 02:24:18 +00:00
renovate[bot]
be789d706b chore(deps): update wiki digest to afb2ccd 2025-11-27 15:36:14 +00:00
renovate[bot]
03bfc169bb chore(deps): update dependency jetbrains.annotations.sources to 2025.2.4 2025-11-27 03:43:34 +00:00
ArchiBot
12d26bfd60 Automatic translations update 2025-11-27 02:23:56 +00:00
ArchiBot
cb31836c34 Automatic translations update 2025-11-26 02:25:47 +00:00
renovate[bot]
f091707b0d chore(deps): update dependency markdig.signed to 0.44.0 2025-11-25 09:44:27 +00:00
renovate[bot]
f4467fcd38 chore(deps): update actions/setup-dotnet action to v5.0.1 2025-11-25 05:45:11 +00:00
ArchiBot
f00b6bfdf1 Automatic translations update 2025-11-25 02:25:49 +00:00
Łukasz Domeradzki
bbfe0e40c5 Misc 2025-11-24 12:03:28 +01:00
Łukasz Domeradzki
e1e928c4ca Misc
Thanks @xPaw
2025-11-24 11:12:30 +01:00
Pavel Djundik
29cb094430 Optimize generating totp codes (#3512) 2025-11-24 11:11:46 +01:00
Łukasz Domeradzki
dfd2bd9ac4 Add additional OSes to test CI for 2025-11-24 10:42:52 +01:00
ArchiBot
c65ffa44d9 Automatic translations update 2025-11-24 02:30:30 +00:00
Łukasz Domeradzki
cf84c19a1a Bump 2025-11-23 23:48:18 +01:00
renovate[bot]
252e498d8b chore(deps): update asf-ui digest to e2d9422 2025-11-23 05:43:21 +00:00
ArchiBot
1e3a5a5176 Automatic translations update 2025-11-23 02:35:10 +00:00
ArchiBot
c21ca7dbb3 Automatic translations update 2025-11-22 02:22:37 +00:00
renovate[bot]
f7b5699172 chore(deps): update asf-ui digest to 5456569 2025-11-21 18:35:58 +00:00
renovate[bot]
2793775f26 chore(deps): update asf-ui digest to 64ee4fe 2025-11-20 18:29:23 +00:00
renovate[bot]
ab54040d3b chore(deps): update actions/checkout action to v6 (#3509)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-20 19:28:43 +01:00
renovate[bot]
36225c5b93 chore(deps): update dependency humanizer to 3.0.1 2025-11-20 05:06:44 +00:00
renovate[bot]
647dcb5834 chore(deps): update dependency scalar.aspnetcore to 2.11.0 2025-11-19 21:48:11 +00:00
renovate[bot]
12e59a649a chore(deps): update dependency microsoft.identitymodel.jsonwebtokens to 8.15.0 2025-11-19 09:59:04 +00:00
renovate[bot]
f85c36e8ee chore(deps): update actions/checkout action to v5.0.1 2025-11-19 06:02:04 +00:00
ArchiBot
7e4878a3f1 Automatic translations update 2025-11-19 02:24:20 +00:00
renovate[bot]
35aeee1b63 chore(deps): update asf-ui digest to e0c8543 2025-11-18 13:10:03 +00:00
ArchiBot
6f1dffbc01 Automatic translations update 2025-11-18 02:24:16 +00:00
ArchiBot
f6ae839a2f Automatic translations update 2025-11-17 02:26:06 +00:00
renovate[bot]
4d97862ec8 chore(deps): update wiki digest to 8dfa02f 2025-11-16 18:13:49 +00:00
renovate[bot]
84a0b59aba chore(deps): update opentelemetry-dotnet-contrib monorepo to 1.14.0 2025-11-14 05:02:20 +00:00
ArchiBot
1c9a3dbf36 Automatic translations update 2025-11-14 02:24:47 +00:00
renovate[bot]
4540b4a2da chore(deps): update dependency nlog.web.aspnetcore to 6.1.0 2025-11-13 10:02:31 +00:00
renovate[bot]
1e814a63cc chore(deps): update dependency anglesharp to 1.4.0 2025-11-13 08:03:50 +00:00
ArchiBot
f4f70ec802 Automatic translations update 2025-11-13 02:26:29 +00:00
renovate[bot]
41656011a6 chore(deps): update opentelemetry-dotnet monorepo 2025-11-12 18:46:30 +00:00
renovate[bot]
f061be0798 chore(deps): update asf-ui digest to e91078e 2025-11-12 04:50:09 +00:00
ArchiBot
c0a253213d Automatic translations update 2025-11-12 02:24:45 +00:00
Łukasz Domeradzki
67757178c1 Silence yet another warn 2025-11-11 22:42:07 +01:00
Łukasz Domeradzki
03350ce879 Misc 2025-11-11 22:22:06 +01:00
Łukasz Domeradzki
55bc802d59 Misc Rider improvements 2025-11-11 22:13:13 +01:00
Łukasz Domeradzki
a436c053a3 Bump 2025-11-11 20:30:15 +01:00
30 changed files with 296 additions and 173 deletions

View File

@@ -15,19 +15,19 @@ jobs:
fail-fast: false
matrix:
configuration: [Debug, Release]
os: [macos-latest, ubuntu-latest, windows-latest]
os: [macos-latest, macos-15-intel, ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
submodules: recursive
- name: Setup .NET Core
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5.0.0
uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
with:
dotnet-version: ${{ env.DOTNET_SDK_VERSION }}

View File

@@ -14,13 +14,13 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
submodules: recursive
- name: Upload latest strings for translation on Crowdin
uses: crowdin/github-action@08713f00a50548bfe39b37e8f44afb53e7a802d4 # v2.12.0
uses: crowdin/github-action@60debf382ee245b21794321190ad0501db89d8c1 # v2.13.0
with:
crowdin_branch_name: main
config: '.github/crowdin.yml'

View File

@@ -19,7 +19,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
submodules: recursive

View File

@@ -18,7 +18,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
submodules: recursive

View File

@@ -19,7 +19,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
submodules: recursive

View File

@@ -19,7 +19,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
submodules: recursive

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Lock inactive threads
uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1
uses: dessant/lock-threads@7266a7ce5c1df01b1c6db85bf8cd86c737dadbe7 # v6.0.0
with:
discussion-inactive-days: 90
issue-inactive-days: 60

View File

@@ -19,13 +19,13 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
submodules: recursive
- name: Setup Node.js with npm
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
check-latest: true
node-version: ${{ env.NODE_JS_VERSION }}
@@ -43,7 +43,7 @@ jobs:
run: npm run-script deploy --no-progress --prefix ASF-ui
- name: Upload ASF-ui
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
compression-level: 1
if-no-files-found: error
@@ -82,12 +82,12 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
- name: Setup .NET Core
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5.0.0
uses: actions/setup-dotnet@2016bd2012dba4e32de620c46fe006a3ac9f0602 # v5.0.1
with:
dotnet-version: ${{ env.DOTNET_SDK_VERSION }}
@@ -95,7 +95,7 @@ jobs:
run: dotnet --info
- name: Download previously built ASF-ui
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ASF-ui
path: ASF-ui/dist
@@ -367,7 +367,7 @@ jobs:
subject-path: out/ASF-${{ matrix.variant }}.zip
- name: Upload ASF-${{ matrix.variant }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
compression-level: 1
if-no-files-found: error
@@ -416,7 +416,7 @@ jobs:
- name: Upload ArchiSteamFarm.OfficialPlugins.Monitoring
if: ${{ matrix.os == 'ubuntu-latest' && matrix.variant == 'generic' }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
compression-level: 1
if-no-files-found: error
@@ -436,60 +436,60 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
- name: Download ASF-generic artifact from ubuntu-latest
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ubuntu-latest_ASF-generic
path: out
- name: Download ASF-linux-arm artifact from ubuntu-latest
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ubuntu-latest_ASF-linux-arm
path: out
- name: Download ASF-linux-arm64 artifact from ubuntu-latest
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ubuntu-latest_ASF-linux-arm64
path: out
- name: Download ASF-linux-x64 artifact from ubuntu-latest
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ubuntu-latest_ASF-linux-x64
path: out
- name: Download ASF-osx-arm64 artifact from macos-latest
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: macos-latest_ASF-osx-arm64
path: out
- name: Download ASF-osx-x64 artifact from macos-latest
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: macos-latest_ASF-osx-x64
path: out
- name: Download ASF-win-arm64 artifact from windows-latest
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: windows-latest_ASF-win-arm64
path: out
- name: Download ASF-win-x64 artifact from windows-latest
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: windows-latest_ASF-win-x64
path: out
- name: Download ArchiSteamFarm.OfficialPlugins.Monitoring artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: ArchiSteamFarm.OfficialPlugins.Monitoring
path: out
@@ -514,7 +514,7 @@ jobs:
subject-path: out/SHA512SUMS
- name: Upload SHA512SUMS
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
compression-level: 1
if-no-files-found: error
@@ -527,7 +527,7 @@ jobs:
subject-path: out/SHA512SUMS.sign
- name: Upload SHA512SUMS.sign
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
compression-level: 1
if-no-files-found: error

View File

@@ -15,7 +15,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
show-progress: false
submodules: recursive
@@ -31,7 +31,7 @@ jobs:
git reset --hard origin/master
- name: Download latest translations from Crowdin
uses: crowdin/github-action@08713f00a50548bfe39b37e8f44afb53e7a802d4 # v2.12.0
uses: crowdin/github-action@60debf382ee245b21794321190ad0501db89d8c1 # v2.13.0
with:
upload_sources: false
download_translations: true

2
ASF-ui

Submodule ASF-ui updated: 184a7a2686...cd1f819f04

View File

@@ -122,7 +122,6 @@
<value>Kunne ikke sende inn data fordi det ikke er gyldig SteamID satt som vi kan klassifisere som bidragsyter. Vurder å sette opp {0} egenskapen.</value>
<comment>{0} will be replaced by the name of the config property (e.g. "SteamOwnerID") that the user is expected to set</comment>
</data>
<data name="SubmissionFailedTooManyRequests" xml:space="preserve">
<value>Innsendingen mislyktes på grunn av for mange forespørsler sendt, vi prøver igjen om lag {0} nå.</value>
<comment>{0} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>

View File

@@ -45,6 +45,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTrailingCommaInSinglelineLists/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeMemberModifiers/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeModifiers/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AsyncVoidEventHandlerMethod/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AsyncVoidMethod/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=BadAttributeBracketsSpaces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=BadBracesSpaces/@EntryIndexedValue">WARNING</s:String>
@@ -189,6 +190,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToLambdaExpressionWhenPossible/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DuplicatedChainedIfBodies/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DuplicatedSequentialIfBodies/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DuplicatedSwitchExpressionArms/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DuplicatedSwitchSectionBodies/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DuplicateResource/@EntryIndexedValue">DO_NOT_SHOW</s:String>
@@ -241,6 +243,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MissingSpace/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MoveLocalFunctionAfterJumpStatement/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MoveToExistingPositionalDeconstructionPattern/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MoveToExtensionBlock/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MultipleSpaces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MultipleStatementsOnOneLine/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MultipleTypeMembersOnOneLine/@EntryIndexedValue">WARNING</s:String>

View File

@@ -4,6 +4,11 @@
<OutputType>Exe</OutputType>
</PropertyGroup>
<!-- TODO: It seems CA1515 is no longer respected inside editorconfig, might be possible to remove later -->
<PropertyGroup>
<NoWarn>$(NoWarn),CA1515</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AngleSharp" />
<PackageReference Include="CryptSharpStandard" />

View File

@@ -887,10 +887,12 @@ public static class ASF {
MemoryStream memoryStream = new(responseBytes);
await using (memoryStream.ConfigureAwait(false)) {
using ZipArchive zipArchive = new(memoryStream);
ZipArchive zipArchive = new(memoryStream);
if (!await UpdateFromArchive(newVersion, channel.Value, updateOverride, forced, zipArchive).ConfigureAwait(false)) {
ArchiLogger.LogGenericError(Strings.WarningFailed);
await using (zipArchive.ConfigureAwait(false)) {
if (!await UpdateFromArchive(newVersion, channel.Value, updateOverride, forced, zipArchive).ConfigureAwait(false)) {
ArchiLogger.LogGenericError(Strings.WarningFailed);
}
}
}
} catch (Exception e) {

View File

@@ -169,18 +169,6 @@ public static class Utilities {
}
}
[PublicAPI]
public static bool IsClientErrorCode(this HttpStatusCode statusCode) => statusCode is >= HttpStatusCode.BadRequest and < HttpStatusCode.InternalServerError;
[PublicAPI]
public static bool IsRedirectionCode(this HttpStatusCode statusCode) => statusCode is >= HttpStatusCode.Ambiguous and < HttpStatusCode.BadRequest;
[PublicAPI]
public static bool IsServerErrorCode(this HttpStatusCode statusCode) => statusCode is >= HttpStatusCode.InternalServerError and < (HttpStatusCode) 600;
[PublicAPI]
public static bool IsSuccessCode(this HttpStatusCode statusCode) => statusCode is >= HttpStatusCode.OK and < HttpStatusCode.Ambiguous;
[PublicAPI]
public static bool IsValidCdKey(string key) {
ArgumentException.ThrowIfNullOrEmpty(key);
@@ -525,4 +513,20 @@ public static class Utilities {
return prefixes.Any(prefix => !string.IsNullOrEmpty(prefix) && (directory.Length > prefix.Length) && DirectorySeparators.Contains(directory[prefix.Length]) && directory.StartsWith(prefix, StringComparison.Ordinal));
}
#pragma warning disable CA1034 // False positive, there's no other way we can declare this block
extension(HttpStatusCode statusCode) {
[PublicAPI]
public bool IsClientErrorCode() => statusCode is >= HttpStatusCode.BadRequest and < HttpStatusCode.InternalServerError;
[PublicAPI]
public bool IsRedirectionCode() => statusCode is >= HttpStatusCode.Ambiguous and < HttpStatusCode.BadRequest;
[PublicAPI]
public bool IsServerErrorCode() => statusCode is >= HttpStatusCode.InternalServerError and < (HttpStatusCode) 600;
[PublicAPI]
public bool IsSuccessCode() => statusCode is >= HttpStatusCode.OK and < HttpStatusCode.Ambiguous;
}
#pragma warning restore CA1034 // False positive, there's no other way we can declare this block
}

View File

@@ -83,7 +83,9 @@
<value>{0} és invàlid!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorNoBotsDefined" xml:space="preserve">
<value>No s'ha definit cap agent. Potser t'ha passat per alt configurar l'ASF? Segueix la guia "posada en marxa" al wiki si tens dificultats.</value>
</data>
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
@@ -148,8 +150,13 @@
<data name="UpdateFinished" xml:space="preserve">
<value>Procés d'actualització finalitzat!</value>
</data>
<data name="UpdateNewVersionAvailable" xml:space="preserve">
<value>Disponible una nova versió de l'ASF! Sospesa una actualització!</value>
</data>
<data name="UpdateVersionInfo" xml:space="preserve">
<value>Versió local: {0} | Versió remota: {1}</value>
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
@@ -188,26 +195,64 @@
<data name="CheckingOtherBadgePages" xml:space="preserve">
<value>Comprovant les altres pàgines d'insígnies...</value>
</data>
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
<value>Algorisme de cultiu escollit: {0}</value>
<comment>{0} will be replaced by the name of chosen farming algorithm</comment>
</data>
<data name="Done" xml:space="preserve">
<value>Fet!</value>
</data>
<data name="GamesToIdle" xml:space="preserve">
<value>Hi ha un total de {0} jocs ({1} targetes) restants per cultivar (queden ~{2})...</value>
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
</data>
<data name="IdlingFinished" xml:space="preserve">
<value>Cultiu finalitzat!</value>
</data>
<data name="IdlingFinishedForGame" xml:space="preserve">
<value>Cultiu finalitzat: {0} ({1}) després de {2} de temps de joc!</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
</data>
<data name="IdlingStatusForGame" xml:space="preserve">
<value>Estat del cultiu per {0} ({1}): Queden {2} targetes</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to farm</comment>
</data>
<data name="IdlingStopped" xml:space="preserve">
<value>Cultiu aturat!</value>
</data>
<data name="NothingToIdle" xml:space="preserve">
<value>No hi ha res per cultivar en aquest compte!</value>
</data>
<data name="NowIdling" xml:space="preserve">
<value>Cultivant en aquest moment: {0} ({1})</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="NowIdlingList" xml:space="preserve">
<value>Cultivant en aquest moment: {0}</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
</data>
<data name="StillIdling" xml:space="preserve">
<value>Encara cultivant: {0} ({1})</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StillIdlingList" xml:space="preserve">
<value>Encara cultivant: {0}</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
</data>
<data name="StoppedIdling" xml:space="preserve">
<value>Cultiu aturat: {0} ({1})</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StoppedIdlingList" xml:space="preserve">
<value>Cultiu aturat: {0}</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
</data>
<data name="UnknownCommand" xml:space="preserve">
<value>Ordre desconeguda!</value>
</data>
@@ -228,10 +273,18 @@
</data>
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
<value>El cultiu automàtic està en pausa!</value>
</data>
<data name="BotAutomaticIdlingNowResumed" xml:space="preserve">
<value>El cultiu automàtic s'ha reprès!</value>
</data>
<data name="BotAutomaticIdlingPausedAlready" xml:space="preserve">
<value>El cultiu automàtic ja està en pausa!</value>
</data>
<data name="BotAutomaticIdlingResumedAlready" xml:space="preserve">
<value>El cultiu automàtic ja s'ha reprès!</value>
</data>
<data name="BotConnected" xml:space="preserve">
<value>Connectat a Steam!</value>
</data>
@@ -305,7 +358,10 @@
<data name="TranslationIncomplete" xml:space="preserve">
<value>L'ASF intentarà utilitzar el teu idioma preferit, {0}, però aquesta traducció està completa en un {1}. Potser t'agradaria ajudar a completar o millorar la traducció de l'ASF a la teva llengua?</value>
<comment>{0} will be replaced by culture code, such as "en-US", {1} will be replaced by completeness percentage, such as "78.5%"</comment>
</data>
<data name="BotVersion" xml:space="preserve">
@@ -335,21 +391,35 @@
<data name="PluginLoaded" xml:space="preserve">
<value>{0} s'ha carregat correctament!</value>
<comment>{0} will be replaced by the name of the custom ASF plugin</comment>
</data>
<data name="PluginLoading" xml:space="preserve">
<value>Inicialitzant {0} V{1}...</value>
<comment>{0} will be replaced by the name of the custom ASF plugin, {1} will be replaced by its version</comment>
</data>
<data name="PleaseWait" xml:space="preserve">
<value>Si us plau, espera...</value>
</data>
<data name="EnterCommand" xml:space="preserve">
<value>Introdueix l'ordre: </value>
</data>
<data name="Executing" xml:space="preserve">
<value>Executant...</value>
</data>
<data name="InteractiveConsoleEnabled" xml:space="preserve">
<value>La consola interactiva ja està activa, prem "c" per entrar al mode d'introducció d'ordres.</value>
</data>
<data name="UpdateCleanup" xml:space="preserve">
<value>Fent neteja dels arxius antics després de l'actualització...</value>
</data>
@@ -373,7 +443,9 @@
<data name="PatchingFiles" xml:space="preserve">
<value>Apedaçant els arxius de l'ASF...</value>
</data>

View File

@@ -206,7 +206,7 @@ StackTrace:
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamParentalCode" xml:space="preserve">
<value>Bitte geben Sie Ihre Steam-Familienansicht-PIN ein: </value>
<value>Bitte geben Sie Ihre Steam-Familienansicht (PIN) ein: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamPassword" xml:space="preserve">
@@ -545,7 +545,7 @@ StackTrace:
<value>Zugriff verweigert!</value>
</data>
<data name="WarningPreReleaseVersion" xml:space="preserve">
<value>Sie verwenden eine Version, die neuer ist als die zuletzt veröffentlichte Version Ihres Aktualisierungskanals. Bitte bedenken Sie, dass Vorabversionen nur für Benutzer gedacht sind, die wissen wie man Fehler meldet, mit Problemen umgeht und Rückmeldung gibt es wird keine technische Unterstützung geben.</value>
<value>Sie verwenden eine Version, die neuer ist als die zuletzt veröffentlichte Version Ihres Aktualisierungskanals. Bitte bedenken Sie, dass Vorabversionen nur an Benutzer gerichtet sind, die bereit sind, Fehlern korrek zu melden, mit Problemen umgehen und Rückmeldungen geben es wird keine technische Unterstützung geben.</value>
</data>
<data name="BotStats" xml:space="preserve">
<value>Aktuelle Speichernutzung: {0} MB.

View File

@@ -769,8 +769,6 @@ StackTrace:
<value>Βρέθηκε ενημέρωση του πρόσθετου {0} από την έκδοση {1} σε {2}...</value>
<comment>{0} will be replaced by plugin name (string), {1} will be replaced by current plugin's version, {2} will be replaced by remote plugin's version.</comment>
</data>
<data name="PluginUpdateInProgress" xml:space="preserve">
<value>Ενημέρωση του πρόσθετου {0}...</value>
<comment>{0} will be replaced by plugin name (string).</comment>

View File

@@ -230,7 +230,6 @@ StackTrace:
<value>Kunne ikke finne noen bot som heter {0}!</value>
<comment>{0} will be replaced by bot's name query (string)</comment>
</data>
<data name="BotStatusIdling" xml:space="preserve">
<value>Bot dyrkingsspill: {0} ({1}, {2} kort dråper igjen) fra totalt {3} spill ({4} kort) igjen til gården (~{5} igjen).</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to farm, {3} will be replaced by total number of games to farm, {4} will be replaced by total number of cards to farm, {5} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
@@ -284,7 +283,6 @@ StackTrace:
<value>Nærliggende nå: {0} ({1})</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="PlayingNotAvailable" xml:space="preserve">
<value>Å spille er utilgjengelig for øyeblikket, vi vil prøve igjen senere!</value>
</data>
@@ -421,8 +419,6 @@ StackTrace:
<data name="BotReconnecting" xml:space="preserve">
<value>Kobler til på nytt...</value>
</data>
<data name="BotRemovedExpiredLoginKey" xml:space="preserve">
<value>Fjernet utgått innloggingsnøkkel!</value>
</data>
@@ -568,12 +564,10 @@ prosess oppgang: {1}</value>
<data name="BotHasNoWallet" xml:space="preserve">
<value>Bot har ingen lommebok.</value>
</data>
<data name="BotInventory" xml:space="preserve">
<value>{0}/{1} ({2}/{3}): {4} ressurser</value>
<comment>{0} will be replaced by appID (number), {1} will be replaced by contextID (number), {2} will be replaced by app's name (string), {3} will be replaced by name of the context (string), {4} will be replaced by number of assets in the specified inventory (number).</comment>
</data>
<data name="DoneActivelyMatchingItems" xml:space="preserve">
<value>Samsvarer med Steam-elementer, fra omkring #{0}.</value>
<comment>{0} will be replaced by round number</comment>
@@ -585,7 +579,6 @@ prosess oppgang: {1}</value>
<value>Du har flere personlige bot kontoer enn vår øvre anbefalte grense ({0}). Vær oppmerksom på at dette oppsettet ikke støttes og kan forårsake forskjellige Steam-relaterte problemer, inkludert kontosuspensjoner. Sjekk ut FAQ for mer detaljer.</value>
<comment>{0} will be replaced by our maximum recommended bots count (number)</comment>
</data>
<data name="PluginLoading" xml:space="preserve">
<value>Laster {0} V{1}...</value>
<comment>{0} will be replaced by the name of the custom ASF plugin, {1} will be replaced by its version</comment>

View File

@@ -891,14 +891,16 @@ public static class PluginsCore {
MemoryStream memoryStream = new(responseBytes);
await using (memoryStream.ConfigureAwait(false)) {
using ZipArchive zipArchive = new(memoryStream);
ZipArchive zipArchive = new(memoryStream);
await plugin.OnPluginUpdateProceeding().ConfigureAwait(false);
await using (zipArchive.ConfigureAwait(false)) {
await plugin.OnPluginUpdateProceeding().ConfigureAwait(false);
if (!await Utilities.UpdateFromArchive(zipArchive, assemblyDirectory).ConfigureAwait(false)) {
ASF.ArchiLogger.LogGenericError(Strings.WarningFailed);
if (!await Utilities.UpdateFromArchive(zipArchive, assemblyDirectory).ConfigureAwait(false)) {
ASF.ArchiLogger.LogGenericError(Strings.WarningFailed);
return false;
return false;
}
}
}
} catch (Exception e) {

View File

@@ -2770,20 +2770,23 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
return;
}
string machineNameFormat = !string.IsNullOrEmpty(BotConfig.MachineName) ? BotConfig.MachineName : "{0} ({1}/{2})";
string machineName = string.Format(CultureInfo.CurrentCulture, machineNameFormat, Environment.MachineName, SharedInfo.PublicIdentifier, SharedInfo.Version);
ArchiLogger.LogGenericInfo(Strings.BotLoggingIn);
InitConnectionFailureTimer();
if (string.IsNullOrEmpty(RefreshToken)) {
BotCredentialsProvider botCredentialsProvider = new(this);
AuthPollResult pollResult;
try {
using CancellationTokenSource authCancellationTokenSource = new();
CredentialsAuthSession authSession = await SteamClient.Authentication.BeginAuthSessionViaCredentialsAsync(
new AuthSessionDetails {
Authenticator = new BotCredentialsProvider(this, authCancellationTokenSource),
DeviceFriendlyName = SharedInfo.PublicIdentifier,
Authenticator = botCredentialsProvider,
DeviceFriendlyName = machineName,
GuardData = BotConfig.UseLoginKeys ? BotDatabase.SteamGuardData : null,
IsPersistentSession = true,
Password = password,
@@ -2791,10 +2794,12 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
}
).ConfigureAwait(false);
pollResult = await authSession.PollingWaitForResultAsync(authCancellationTokenSource.Token).ConfigureAwait(false);
pollResult = await authSession.PollingWaitForResultAsync().ConfigureAwait(false);
} catch (AsyncJobFailedException e) {
ArchiLogger.LogGenericWarningException(e);
LoginFailures += botCredentialsProvider.LoginFailures;
await HandleLoginResult(EResult.Timeout, EResult.Timeout).ConfigureAwait(false);
ReconnectOnUserInitiated = true;
@@ -2804,6 +2809,17 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
} catch (AuthenticationException e) {
ArchiLogger.LogGenericWarningException(e);
LoginFailures += botCredentialsProvider.LoginFailures;
await HandleLoginResult(e.Result, e.Result).ConfigureAwait(false);
ReconnectOnUserInitiated = true;
SteamClient.Disconnect();
return;
} catch (BotAuthenticationException e) {
LoginFailures += botCredentialsProvider.LoginFailures;
await HandleLoginResult(e.Result, e.Result).ConfigureAwait(false);
ReconnectOnUserInitiated = true;
@@ -2811,10 +2827,18 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
return;
} catch (OperationCanceledException) {
// This is okay, we already took care of that and can ignore it here
LoginFailures += botCredentialsProvider.LoginFailures;
await HandleLoginResult(EResult.Timeout, EResult.Timeout).ConfigureAwait(false);
ReconnectOnUserInitiated = true;
SteamClient.Disconnect();
return;
}
LoginFailures += botCredentialsProvider.LoginFailures;
if (!string.IsNullOrEmpty(pollResult.NewGuardData) && BotConfig.UseLoginKeys) {
BotDatabase.SteamGuardData = pollResult.NewGuardData;
}
@@ -2842,8 +2866,6 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
UpdateTokens(pollResult.AccessToken, pollResult.RefreshToken);
}
string machineNameFormat = !string.IsNullOrEmpty(BotConfig.MachineName) ? BotConfig.MachineName : "{0} ({1}/{2})";
SteamUser.LogOnDetails logOnDetails = new() {
AccessToken = RefreshToken,
CellID = ASF.GlobalDatabase?.CellID,
@@ -2851,7 +2873,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
ClientLanguage = CultureInfo.CurrentCulture.ToSteamClientLanguage(),
GamingDeviceType = BotConfig.GamingDeviceType,
LoginID = LoginID,
MachineName = string.Format(CultureInfo.CurrentCulture, machineNameFormat, Environment.MachineName, SharedInfo.PublicIdentifier, SharedInfo.Version),
MachineName = machineName,
ShouldRememberPassword = BotConfig.UseLoginKeys,
UIMode = BotConfig.UserInterfaceMode,
Username = username

View File

@@ -56,7 +56,7 @@ public sealed class CardsFarmer : IAsyncDisposable, IDisposable {
private const byte HoursToIgnore = 1; // How many hours we ignore unreleased appIDs and don't bother checking them again
[PublicAPI]
public static readonly FrozenSet<uint> SalesBlacklist = [267420, 303700, 335590, 368020, 425280, 480730, 566020, 639900, 762800, 876740, 991980, 1195670, 1343890, 1465680, 1658760, 1797760, 2021850, 2243720, 2459330, 2640280, 2861690, 2861720, 3558920];
public static readonly FrozenSet<uint> SalesBlacklist = [267420, 303700, 335590, 368020, 425280, 480730, 566020, 639900, 762800, 876740, 991980, 1195670, 1343890, 1465680, 1658760, 1797760, 2021850, 2243720, 2459330, 2640280, 2861690, 2861720, 3558920, 3558940];
private static readonly ConcurrentDictionary<uint, DateTime> GloballyIgnoredAppIDs = new(); // Reserved for unreleased games

View File

@@ -69,8 +69,9 @@ public sealed class Confirmation {
Generic,
Trade,
Market,
PhoneNumberChange = 5,
AccountRecovery = 6,
FeatureOptOut,
PhoneNumberChange,
AccountRecovery,
ApiKeyRegistration = 9,
FamilyJoin = 11,
AccountSecurity = 12

View File

@@ -23,10 +23,10 @@
using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.Localization;
using ArchiSteamFarm.Steam.Security;
using ArchiSteamFarm.Storage;
using SteamKit2;
using SteamKit2.Authentication;
@@ -34,19 +34,16 @@ using SteamKit2.Authentication;
namespace ArchiSteamFarm.Steam.Integration;
internal sealed class BotCredentialsProvider : IAuthenticator {
private const byte MaxLoginFailures = 5;
private const byte MaxLoginFailures = 3;
private readonly Bot Bot;
private readonly CancellationTokenSource CancellationTokenSource;
private byte LoginFailures;
internal byte LoginFailures { get; private set; }
internal BotCredentialsProvider(Bot bot, CancellationTokenSource cancellationTokenSource) {
internal BotCredentialsProvider(Bot bot) {
ArgumentNullException.ThrowIfNull(bot);
ArgumentNullException.ThrowIfNull(cancellationTokenSource);
Bot = bot;
CancellationTokenSource = cancellationTokenSource;
}
public async Task<bool> AcceptDeviceConfirmationAsync() {
@@ -75,24 +72,26 @@ internal sealed class BotCredentialsProvider : IAuthenticator {
throw new InvalidEnumArgumentException(nameof(inputType), (int) inputType, typeof(ASF.EUserInputType));
}
if (previousCodeWasIncorrect && (++LoginFailures >= MaxLoginFailures)) {
EResult reason = inputType == ASF.EUserInputType.TwoFactorAuthentication ? EResult.TwoFactorCodeMismatch : EResult.InvalidLoginAuthCode;
EResult reason = inputType == ASF.EUserInputType.TwoFactorAuthentication ? EResult.TwoFactorCodeMismatch : EResult.InvalidLoginAuthCode;
if (previousCodeWasIncorrect) {
Bot.ArchiLogger.LogGenericWarning(Strings.FormatBotUnableToLogin(reason, reason));
await CancellationTokenSource.CancelAsync().ConfigureAwait(false);
return "";
if (++LoginFailures >= MaxLoginFailures) {
throw new BotAuthenticationException(reason);
}
}
string? result = await Bot.RequestInput(inputType, previousCodeWasIncorrect).ConfigureAwait(false);
string? input = await Bot.RequestInput(inputType, previousCodeWasIncorrect).ConfigureAwait(false);
if (string.IsNullOrEmpty(result)) {
await CancellationTokenSource.CancelAsync().ConfigureAwait(false);
if (string.IsNullOrEmpty(input)) {
Bot.ArchiLogger.LogGenericWarning(Strings.FormatErrorIsEmpty(nameof(input)));
return "";
LoginFailures = MaxLoginFailures;
throw new BotAuthenticationException(reason);
}
return result;
return input;
}
}

View File

@@ -0,0 +1,42 @@
// ----------------------------------------------------------------------------------------------
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// ----------------------------------------------------------------------------------------------
// |
// Copyright 2015-2025 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.ComponentModel;
using SteamKit2;
namespace ArchiSteamFarm.Steam.Security;
#pragma warning disable CA1032 // This type is internal and we don't require additional constructors
internal sealed class BotAuthenticationException : Exception {
internal readonly EResult Result;
internal BotAuthenticationException(EResult result) {
if (!Enum.IsDefined(result)) {
throw new InvalidEnumArgumentException(nameof(result), (int) result, typeof(EResult));
}
Result = result;
}
}
#pragma warning restore CA1032 // This type is internal and we don't require additional constructors

View File

@@ -23,6 +23,7 @@
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
@@ -101,53 +102,33 @@ public sealed class MobileAuthenticator : IDisposable {
throw new InvalidOperationException(nameof(SharedSecret));
}
byte[] sharedSecret;
Span<byte> sharedSecret = stackalloc byte[32];
try {
sharedSecret = Convert.FromBase64String(SharedSecret);
} catch (FormatException e) {
Bot.ArchiLogger.LogGenericException(e);
if (!Convert.TryFromBase64String(SharedSecret, sharedSecret, out int bytesWritten)) {
Bot.ArchiLogger.LogGenericError(Strings.FormatErrorIsInvalid(nameof(SharedSecret)));
return null;
}
byte[] timeArray = BitConverter.GetBytes(time / CodeInterval);
sharedSecret = sharedSecret[..bytesWritten];
if (BitConverter.IsLittleEndian) {
Array.Reverse(timeArray);
}
Span<byte> timeArray = stackalloc byte[sizeof(long)];
BinaryPrimitives.WriteInt64BigEndian(timeArray, (long) (time / CodeInterval));
Span<byte> hash = stackalloc byte[HMACSHA1.HashSizeInBytes];
#pragma warning disable CA5350 // This is actually a fair warning, but there is nothing we can do about Steam using weak cryptographic algorithms
byte[] hash = HMACSHA1.HashData(sharedSecret, timeArray);
HMACSHA1.HashData(sharedSecret, timeArray, hash);
#pragma warning restore CA5350 // This is actually a fair warning, but there is nothing we can do about Steam using weak cryptographic algorithms
// The last 4 bits of the mac say where the code starts
int start = hash[^1] & 0x0f;
uint fullCode;
// Extract those 4 bytes
byte[] bytes = ArrayPool<byte>.Shared.Rent(4);
Span<byte> bytes = hash[start..(start + 4)];
try {
Array.Copy(hash, start, bytes, 0, 4);
Span<byte> span;
if (BitConverter.IsLittleEndian) {
Array.Reverse(bytes);
span = bytes.AsSpan()[^4..];
} else {
span = bytes.AsSpan()[..4];
}
// Build the alphanumeric code
fullCode = BitConverter.ToUInt32(span) & 0x7fffffff;
} finally {
ArrayPool<byte>.Shared.Return(bytes);
}
// Build the alphanumeric code
uint fullCode = BinaryPrimitives.ReadUInt32BigEndian(bytes) & 0x7fffffff;
return string.Create(
CodeDigits, fullCode, static (buffer, state) => {

View File

@@ -542,7 +542,7 @@ public sealed class BotConfig {
return (false, Strings.FormatErrorConfigPropertyInvalid(nameof(GamesPlayedWhileIdle), $"{nameof(GamesPlayedWhileIdle.Count)} {GamesPlayedWhileIdle.Count} > {ArchiHandler.MaxGamesPlayedConcurrently}"));
}
if (GamingDeviceType == EGamingDeviceType.Unknown || !Enum.IsDefined(GamingDeviceType)) {
if ((GamingDeviceType == EGamingDeviceType.Unknown) || !Enum.IsDefined(GamingDeviceType)) {
return (false, Strings.FormatErrorConfigPropertyInvalid(nameof(GamingDeviceType), GamingDeviceType));
}

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>6.3.0.1</Version>
<Version>6.3.1.3</Version>
</PropertyGroup>
<PropertyGroup>

View File

@@ -1,25 +1,25 @@
<Project>
<ItemGroup>
<PackageVersion Include="AngleSharp" Version="1.3.1" />
<PackageVersion Include="AngleSharp" Version="1.4.0" />
<PackageVersion Include="CryptSharpStandard" Version="1.0.0" />
<PackageVersion Include="Humanizer" Version="3.0.0-rc.30" />
<PackageVersion Include="JetBrains.Annotations.Sources" Version="2025.2.2" />
<PackageVersion Include="Markdig.Signed" Version="0.43.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0" />
<PackageVersion Include="Humanizer" Version="3.0.1" />
<PackageVersion Include="JetBrains.Annotations.Sources" Version="2025.2.4" />
<PackageVersion Include="Markdig.Signed" Version="0.44.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.ResxSourceGenerator" Version="5.0.0-1.25277.114" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.14.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.15.0" />
<PackageVersion Include="MSTest" Version="4.0.2" />
<PackageVersion Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
<PackageVersion Include="NLog.Web.AspNetCore" Version="6.0.6" />
<PackageVersion Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.13.1-beta.1" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.13.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.13.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.13.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.13.0" />
<PackageVersion Include="Scalar.AspNetCore" Version="2.10.3" />
<PackageVersion Include="NLog.Web.AspNetCore" Version="6.1.0" />
<PackageVersion Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.14.0-beta.1" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.14.0" />
<PackageVersion Include="Scalar.AspNetCore" Version="2.11.6" />
<PackageVersion Include="SteamKit2" Version="3.3.1" />
<PackageVersion Include="System.Composition" Version="10.0.0" />
<PackageVersion Include="System.Composition.AttributedModel" Version="10.0.0" />
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="10.0.0" />
<PackageVersion Include="System.Composition" Version="10.0.1" />
<PackageVersion Include="System.Composition.AttributedModel" Version="10.0.1" />
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="10.0.1" />
</ItemGroup>
</Project>

2
wiki

Submodule wiki updated: a85f4ae9e7...7854f32a69