mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-16 06:20:34 +00:00
Compare commits
208 Commits
6.2.2.0
...
9510514fe5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9510514fe5 | ||
|
|
b3683d39e3 | ||
|
|
23f9f58f6c | ||
|
|
f0dfbc5ee4 | ||
|
|
8ac4efe392 | ||
|
|
d4691ced51 | ||
|
|
d679bf9307 | ||
|
|
564d0bf9a4 | ||
|
|
2f848fe585 | ||
|
|
bf34d2e91e | ||
|
|
83e4c7f63a | ||
|
|
1e2e52943d | ||
|
|
4a9ecc52c1 | ||
|
|
10fc914ac1 | ||
|
|
7e9c49cc79 | ||
|
|
ab58886d29 | ||
|
|
a5740a43db | ||
|
|
223f2b98cb | ||
|
|
69b150c8a0 | ||
|
|
f4ea1d44ac | ||
|
|
d02504b914 | ||
|
|
c363af8c3a | ||
|
|
c06a22ec93 | ||
|
|
ed19d7e3bf | ||
|
|
4eee2e2ac7 | ||
|
|
90fe1a9448 | ||
|
|
8c26dcb7c2 | ||
|
|
ba8150b27a | ||
|
|
612b3dd3ef | ||
|
|
a551568f2b | ||
|
|
31615ef64d | ||
|
|
0f0f1bfcd3 | ||
|
|
702e27c466 | ||
|
|
921263674d | ||
|
|
5110d6d9f9 | ||
|
|
5f622128e4 | ||
|
|
6eee3fb4d9 | ||
|
|
0aa777734a | ||
|
|
be789d706b | ||
|
|
03bfc169bb | ||
|
|
12d26bfd60 | ||
|
|
cb31836c34 | ||
|
|
f091707b0d | ||
|
|
f4467fcd38 | ||
|
|
f00b6bfdf1 | ||
|
|
bbfe0e40c5 | ||
|
|
e1e928c4ca | ||
|
|
29cb094430 | ||
|
|
dfd2bd9ac4 | ||
|
|
c65ffa44d9 | ||
|
|
cf84c19a1a | ||
|
|
252e498d8b | ||
|
|
1e3a5a5176 | ||
|
|
c21ca7dbb3 | ||
|
|
f7b5699172 | ||
|
|
2793775f26 | ||
|
|
ab54040d3b | ||
|
|
36225c5b93 | ||
|
|
647dcb5834 | ||
|
|
12e59a649a | ||
|
|
f85c36e8ee | ||
|
|
7e4878a3f1 | ||
|
|
35aeee1b63 | ||
|
|
6f1dffbc01 | ||
|
|
f6ae839a2f | ||
|
|
4d97862ec8 | ||
|
|
84a0b59aba | ||
|
|
1c9a3dbf36 | ||
|
|
4540b4a2da | ||
|
|
1e814a63cc | ||
|
|
f4f70ec802 | ||
|
|
41656011a6 | ||
|
|
f061be0798 | ||
|
|
c0a253213d | ||
|
|
67757178c1 | ||
|
|
03350ce879 | ||
|
|
55bc802d59 | ||
|
|
a436c053a3 | ||
|
|
8547097e78 | ||
|
|
a8d9844b01 | ||
|
|
867b7270ec | ||
|
|
970998fb4b | ||
|
|
1ac4dfd6c8 | ||
|
|
ea2bec2f3e | ||
|
|
ee0eef3761 | ||
|
|
fc7ac69fb1 | ||
|
|
a32e7639ed | ||
|
|
c8e8cd27b8 | ||
|
|
245daec72e | ||
|
|
02d18aecf4 | ||
|
|
469dee4595 | ||
|
|
2e0df5c82b | ||
|
|
677a5503e2 | ||
|
|
566195129f | ||
|
|
b872340c5d | ||
|
|
1c4fba6b2e | ||
|
|
2adb552618 | ||
|
|
59e27bc41d | ||
|
|
5d1234e2d6 | ||
|
|
1f74f9c721 | ||
|
|
fb2dcb04ae | ||
|
|
abdaa38389 | ||
|
|
0830678526 | ||
|
|
cb827c7ab5 | ||
|
|
e7ae287f38 | ||
|
|
ffb5322ecb | ||
|
|
1ec78cf6a2 | ||
|
|
681bd7abcf | ||
|
|
1a906aac74 | ||
|
|
57553fbbb3 | ||
|
|
738d949f1f | ||
|
|
b362408704 | ||
|
|
32238ba07c | ||
|
|
2172f8b9eb | ||
|
|
609b4914bd | ||
|
|
e23e507a68 | ||
|
|
f69ee6364d | ||
|
|
a468f9301d | ||
|
|
efa541d68d | ||
|
|
068ad1b06a | ||
|
|
f3bec05e1f | ||
|
|
a84dc1b01e | ||
|
|
ca4a3ee972 | ||
|
|
1c817426b8 | ||
|
|
5ec9bc14a9 | ||
|
|
67f451069a | ||
|
|
4eb73af250 | ||
|
|
ef60e23a53 | ||
|
|
2b57d0a9e6 | ||
|
|
ae183ae3ad | ||
|
|
725a3a5106 | ||
|
|
289f573b00 | ||
|
|
a8a6e658e2 | ||
|
|
797bb6fc98 | ||
|
|
41f61503fb | ||
|
|
764c979560 | ||
|
|
a0531ff1f3 | ||
|
|
30d5a4cdc2 | ||
|
|
750ff1a09a | ||
|
|
c5cc247e2d | ||
|
|
813bac5e52 | ||
|
|
267cf1597e | ||
|
|
4716312c3f | ||
|
|
31b735c3d3 | ||
|
|
e9baae4d03 | ||
|
|
f97142200f | ||
|
|
34bc25b023 | ||
|
|
ede24b9fd5 | ||
|
|
c656b61ce2 | ||
|
|
3fb804fbd1 | ||
|
|
eb5f126c76 | ||
|
|
815d0732c3 | ||
|
|
a517cf216d | ||
|
|
e5a6eede24 | ||
|
|
7a3c28f3f6 | ||
|
|
49381cea84 | ||
|
|
9afa92a22d | ||
|
|
6719903012 | ||
|
|
2f0047e6c0 | ||
|
|
71a708b515 | ||
|
|
50b9011323 | ||
|
|
e4bd4e2371 | ||
|
|
f662dc29ed | ||
|
|
e4ffd5c6ab | ||
|
|
588bc9e691 | ||
|
|
3e98887954 | ||
|
|
78319f65eb | ||
|
|
c467fd39c1 | ||
|
|
896bd82f97 | ||
|
|
3a87d7536b | ||
|
|
1b245a568f | ||
|
|
95eb6b2c63 | ||
|
|
616d5d2cdb | ||
|
|
9e1edc58ab | ||
|
|
7df227b584 | ||
|
|
be0f2ab537 | ||
|
|
885c679033 | ||
|
|
0575e714ae | ||
|
|
d1f3074c90 | ||
|
|
3f3a3b161b | ||
|
|
c5af29ddde | ||
|
|
40dd6100ab | ||
|
|
42cd1a85d9 | ||
|
|
c196b46337 | ||
|
|
e5e133475b | ||
|
|
67d191bbf3 | ||
|
|
c9502f8462 | ||
|
|
3dbc3b1c5a | ||
|
|
c54928bb64 | ||
|
|
d40d7f0566 | ||
|
|
b73ddab2e2 | ||
|
|
069523adcd | ||
|
|
fc310ee24c | ||
|
|
b53d9a0f6f | ||
|
|
035ff7dfe7 | ||
|
|
2bbf197108 | ||
|
|
5d2665207a | ||
|
|
8618b01800 | ||
|
|
d59d51ae33 | ||
|
|
a313a19cec | ||
|
|
c5f7565ac0 | ||
|
|
f52486528b | ||
|
|
d17399d98b | ||
|
|
1eadaad9bd | ||
|
|
22e424a78c | ||
|
|
712b57e46b | ||
|
|
bc914f0a09 | ||
|
|
1da2ccbb1c |
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -5,7 +5,7 @@ on: [push, pull_request]
|
||||
env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
||||
DOTNET_NOLOGO: true
|
||||
DOTNET_SDK_VERSION: 9.0
|
||||
DOTNET_SDK_VERSION: 10.0
|
||||
|
||||
permissions: {}
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
|
||||
4
.github/workflows/crowdin-ci.yml
vendored
4
.github/workflows/crowdin-ci.yml
vendored
@@ -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@0749939f635900a2521aa6aac7a3766642b2dc71 # v2.11.0
|
||||
uses: crowdin/github-action@60debf382ee245b21794321190ad0501db89d8c1 # v2.13.0
|
||||
with:
|
||||
crowdin_branch_name: main
|
||||
config: '.github/crowdin.yml'
|
||||
|
||||
2
.github/workflows/docker-ci.yml
vendored
2
.github/workflows/docker-ci.yml
vendored
@@ -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
|
||||
|
||||
6
.github/workflows/docker-publish-latest.yml
vendored
6
.github/workflows/docker-publish-latest.yml
vendored
@@ -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
|
||||
@@ -27,14 +27,14 @@ jobs:
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
8
.github/workflows/docker-publish-main.yml
vendored
8
.github/workflows/docker-publish-main.yml
vendored
@@ -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
|
||||
@@ -28,14 +28,14 @@ jobs:
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
push: true
|
||||
|
||||
- name: Update DockerHub repository description
|
||||
uses: peter-evans/dockerhub-description@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4.0.2
|
||||
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
@@ -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
|
||||
@@ -28,14 +28,14 @@ jobs:
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
2
.github/workflows/lock-threads.yml
vendored
2
.github/workflows/lock-threads.yml
vendored
@@ -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
|
||||
|
||||
42
.github/workflows/publish.yml
vendored
42
.github/workflows/publish.yml
vendored
@@ -6,7 +6,7 @@ env:
|
||||
CONFIGURATION: Release
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
||||
DOTNET_NOLOGO: true
|
||||
DOTNET_SDK_VERSION: 9.0
|
||||
DOTNET_SDK_VERSION: 10.0
|
||||
NODE_JS_VERSION: 'lts/*'
|
||||
PLUGINS_BUNDLED: ArchiSteamFarm.OfficialPlugins.ItemsMatcher ArchiSteamFarm.OfficialPlugins.MobileAuthenticator ArchiSteamFarm.OfficialPlugins.SteamTokenDumper
|
||||
PLUGINS_INCLUDED: ArchiSteamFarm.OfficialPlugins.Monitoring # Apart from declaring them here, there is certain amount of hardcoding needed below for uploading
|
||||
@@ -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@a0853c24544627f65ddf259abe73b1d18a591444 # v5.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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
compression-level: 1
|
||||
if-no-files-found: error
|
||||
|
||||
4
.github/workflows/translations.yml
vendored
4
.github/workflows/translations.yml
vendored
@@ -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@0749939f635900a2521aa6aac7a3766642b2dc71 # v2.11.0
|
||||
uses: crowdin/github-action@60debf382ee245b21794321190ad0501db89d8c1 # v2.13.0
|
||||
with:
|
||||
upload_sources: false
|
||||
download_translations: true
|
||||
|
||||
2
ASF-ui
2
ASF-ui
Submodule ASF-ui updated: 62ed8b8146...9e1d5e33d4
@@ -5,6 +5,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations.Sources" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" IncludeAssets="compile" />
|
||||
<PackageReference Include="SteamKit2" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations.Sources" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AngleSharp" IncludeAssets="compile" />
|
||||
<PackageReference Include="JetBrains.Annotations.Sources" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations.Sources" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" IncludeAssets="compile" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.ResxSourceGenerator" PrivateAssets="all" />
|
||||
<PackageReference Include="SteamKit2" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Linq.Async" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -121,7 +121,7 @@ internal static class Commands {
|
||||
|
||||
IList<string?> results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => ResponseMatch(Steam.Interaction.Commands.GetProxyAccess(bot, access, steamID), bot)))).ConfigureAwait(false);
|
||||
|
||||
List<string> responses = [..results.Where(static result => !string.IsNullOrEmpty(result))!];
|
||||
List<string> responses = [..results.Where(static result => !string.IsNullOrEmpty(result)).Select(static result => result!)];
|
||||
|
||||
return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null;
|
||||
}
|
||||
|
||||
@@ -233,6 +233,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable {
|
||||
HashSet<EAssetType> acceptedMatchableTypes = Bot.BotConfig.MatchableTypes.Where(AcceptedMatchableTypes.Contains).ToHashSet();
|
||||
|
||||
if (acceptedMatchableTypes.Count == 0) {
|
||||
// Should never happen, since IsEligibleForListing() check above ensured we have at least one matchable type
|
||||
throw new InvalidOperationException(nameof(acceptedMatchableTypes));
|
||||
}
|
||||
|
||||
@@ -905,9 +906,8 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable {
|
||||
HashSet<EAssetType> acceptedMatchableTypes = Bot.BotConfig.MatchableTypes.Where(AcceptedMatchableTypes.Contains).ToHashSet();
|
||||
|
||||
if (acceptedMatchableTypes.Count == 0) {
|
||||
Bot.ArchiLogger.LogNullError(acceptedMatchableTypes);
|
||||
|
||||
return;
|
||||
// Should never happen, since IsEligibleForMatching() check above ensured we have at least one matchable type
|
||||
throw new InvalidOperationException(nameof(acceptedMatchableTypes));
|
||||
}
|
||||
|
||||
if (!await MatchActivelySemaphore.WaitAsync(0).ConfigureAwait(false)) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations.Sources" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" IncludeAssets="compile" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.ResxSourceGenerator" PrivateAssets="all" />
|
||||
<PackageReference Include="SteamKit2" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
|
||||
@@ -192,7 +192,7 @@ internal static class Commands {
|
||||
|
||||
IList<string?> results = await Utilities.InParallel(bots.Select(bot => ResponseTwoFactorFinalize(Steam.Interaction.Commands.GetProxyAccess(bot, access, steamID), bot, activationCode))).ConfigureAwait(false);
|
||||
|
||||
List<string> responses = [..results.Where(static result => !string.IsNullOrEmpty(result))!];
|
||||
List<string> responses = [..results.Where(static result => !string.IsNullOrEmpty(result)).Select(static result => result!)];
|
||||
|
||||
return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null;
|
||||
}
|
||||
@@ -289,7 +289,7 @@ internal static class Commands {
|
||||
|
||||
IList<string?> results = await Utilities.InParallel(bots.Select(bot => ResponseTwoFactorFinalized(Steam.Interaction.Commands.GetProxyAccess(bot, access, steamID), bot, activationCode))).ConfigureAwait(false);
|
||||
|
||||
List<string> responses = [..results.Where(static result => !string.IsNullOrEmpty(result))!];
|
||||
List<string> responses = [..results.Where(static result => !string.IsNullOrEmpty(result)).Select(static result => result!)];
|
||||
|
||||
return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null;
|
||||
}
|
||||
@@ -362,7 +362,7 @@ internal static class Commands {
|
||||
|
||||
IList<string?> results = await Utilities.InParallel(bots.Select(bot => ResponseTwoFactorInit(Steam.Interaction.Commands.GetProxyAccess(bot, access, steamID), bot))).ConfigureAwait(false);
|
||||
|
||||
List<string> responses = [..results.Where(static result => !string.IsNullOrEmpty(result))!];
|
||||
List<string> responses = [..results.Where(static result => !string.IsNullOrEmpty(result)).Select(static result => result!)];
|
||||
|
||||
return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations.Sources" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" IncludeAssets="compile" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" />
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations.Sources" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" IncludeAssets="compile" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.ResxSourceGenerator" PrivateAssets="all" />
|
||||
<PackageReference Include="SteamKit2" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -54,12 +54,28 @@ internal sealed class ArchiCryptoHelper {
|
||||
|
||||
[TestMethod]
|
||||
internal async Task CanEncryptDecryptProtectedDataForCurrentUser() {
|
||||
// Not supported on other platforms than Windows
|
||||
if (!OperatingSystem.IsWindows()) {
|
||||
// Not supported on other platforms than Windows
|
||||
return;
|
||||
Assert.Inconclusive($"!{nameof(OperatingSystem.IsWindows)}");
|
||||
}
|
||||
|
||||
await CanEncryptDecrypt(ECryptoMethod.ProtectedDataForCurrentUser).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[DataRow(EHashingMethod.PlainText, TestPassword)]
|
||||
[DataRow(EHashingMethod.Pbkdf2, "WlS48GNrs1hAhcNHPfV09TPTLhf03gExb6zpaKiwX5A=")]
|
||||
[DataRow(EHashingMethod.SCrypt, "9LjhjyugakDQ7Haq/ufyTZDfIGeeWbLcE+/9IeKm8gc=")]
|
||||
[TestMethod]
|
||||
internal void CanHash(EHashingMethod hashingMethod, string expectedHash) {
|
||||
if (!Enum.IsDefined(hashingMethod)) {
|
||||
throw new InvalidEnumArgumentException(nameof(hashingMethod), (int) hashingMethod, typeof(EHashingMethod));
|
||||
}
|
||||
|
||||
ArgumentException.ThrowIfNullOrEmpty(expectedHash);
|
||||
|
||||
string hashed = Hash(hashingMethod, TestPassword);
|
||||
|
||||
Assert.AreEqual(expectedHash, hashed);
|
||||
}
|
||||
}
|
||||
#pragma warning restore CA1812 // False positive, the class is used during MSTest
|
||||
|
||||
@@ -526,7 +526,7 @@ internal sealed class Bot {
|
||||
ArgumentNullException.ThrowIfNull(itemsToSend);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), long> realResult = itemsToSend.GroupBy(static asset => (asset.RealAppID, asset.ContextID, asset.ClassID)).ToDictionary(static group => group.Key, static group => group.Sum(static asset => asset.Amount));
|
||||
Assert.AreEqual(expectedResult.Count, realResult.Count);
|
||||
Assert.HasCount(expectedResult.Count, realResult);
|
||||
Assert.IsTrue(expectedResult.All(expectation => realResult.TryGetValue(expectation.Key, out long reality) && (expectation.Value == reality)));
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ internal sealed class IGitHubPluginUpdates {
|
||||
|
||||
private readonly TestContext TestContext;
|
||||
|
||||
private CancellationToken CancellationToken => TestContext.CancellationTokenSource.Token;
|
||||
private CancellationToken CancellationToken => TestContext.CancellationToken;
|
||||
|
||||
[UsedImplicitly]
|
||||
public IGitHubPluginUpdates(TestContext testContext) {
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace ArchiSteamFarm.Tests;
|
||||
internal sealed class SteamChatMessage {
|
||||
private readonly TestContext TestContext;
|
||||
|
||||
private CancellationToken CancellationToken => TestContext.CancellationTokenSource.Token;
|
||||
private CancellationToken CancellationToken => TestContext.CancellationToken;
|
||||
|
||||
[UsedImplicitly]
|
||||
public SteamChatMessage(TestContext testContext) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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" />
|
||||
@@ -18,8 +23,8 @@
|
||||
<PackageReference Include="Scalar.AspNetCore" />
|
||||
<PackageReference Include="SteamKit2" />
|
||||
<PackageReference Include="System.Composition" />
|
||||
<PackageReference Include="System.Linq.Async" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" />
|
||||
<PackageReference Include="Tmds.DBus.Protocol" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -355,8 +355,8 @@ public static class ASF {
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.IPCConfigChanged);
|
||||
await ArchiKestrel.Stop().ConfigureAwait(false);
|
||||
await ArchiKestrel.Start().ConfigureAwait(false);
|
||||
|
||||
await ArchiKestrel.Restart().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task OnChangedFile(string name, string fullPath) {
|
||||
@@ -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) {
|
||||
|
||||
@@ -37,6 +37,8 @@ using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using ArchiSteamFarm.Web;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using Tmds.DBus.Protocol;
|
||||
|
||||
namespace ArchiSteamFarm.Core;
|
||||
|
||||
@@ -69,13 +71,20 @@ internal static class OS {
|
||||
}
|
||||
}
|
||||
|
||||
private static SafeHandle? InhibitLock;
|
||||
private static Mutex? SingleInstance;
|
||||
|
||||
internal static void CoreInit(bool minimized, bool systemRequired) {
|
||||
internal static async Task CoreInit(bool minimized, bool systemRequired) {
|
||||
if (minimized) {
|
||||
MinimizeConsoleWindow();
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsLinux()) {
|
||||
if (systemRequired) {
|
||||
await LinuxKeepSystemActive().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsWindows()) {
|
||||
if (systemRequired) {
|
||||
WindowsKeepSystemActive();
|
||||
@@ -181,6 +190,12 @@ internal static class OS {
|
||||
// Instead, we'll dispose the mutex which should automatically release it by the CLR
|
||||
SingleInstance.Dispose();
|
||||
SingleInstance = null;
|
||||
|
||||
// Release the inhibit lock as well, if needed
|
||||
if (InhibitLock != null) {
|
||||
InhibitLock.Dispose();
|
||||
InhibitLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool VerifyEnvironment() {
|
||||
@@ -261,6 +276,79 @@ internal static class OS {
|
||||
NativeMethods.FlashWindowEx(ref flashInfo);
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("Linux")]
|
||||
private static async Task LinuxKeepSystemActive() {
|
||||
if (!OperatingSystem.IsLinux()) {
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
// Docs: https://systemd.io/INHIBITOR_LOCKS
|
||||
string? systemAddress = Address.System;
|
||||
|
||||
if (string.IsNullOrEmpty(systemAddress)) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.FormatWarningFailedWithError(nameof(systemAddress)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
using Connection connection = new(systemAddress);
|
||||
|
||||
try {
|
||||
await connection.ConnectAsync().ConfigureAwait(false);
|
||||
} catch (ConnectException e) {
|
||||
// Possible if no DBus is available at all
|
||||
ASF.ArchiLogger.LogGenericDebuggingException(e);
|
||||
ASF.ArchiLogger.LogGenericWarning(Strings.WarningNoSystemRequiredLinuxDependencies);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
MessageWriter writer = connection.GetMessageWriter();
|
||||
|
||||
writer.WriteMethodCallHeader(
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
"Inhibit",
|
||||
"ssss"
|
||||
);
|
||||
|
||||
// Colon-separated list of lock types
|
||||
writer.WriteString("idle");
|
||||
|
||||
// Human-readable, descriptive string of who is taking the lock
|
||||
writer.WriteString(SharedInfo.PublicIdentifier);
|
||||
|
||||
// Human-readable, descriptive string of why the lock is taken
|
||||
writer.WriteString("--system-required");
|
||||
|
||||
// Mode
|
||||
writer.WriteString("block");
|
||||
|
||||
MessageBuffer message = writer.CreateMessage();
|
||||
|
||||
try {
|
||||
// Inhibit() returns a single value, a file descriptor that encapsulates the lock
|
||||
InhibitLock = await connection.CallMethodAsync(
|
||||
message, static (response, _) => {
|
||||
Reader reader = response.GetBodyReader();
|
||||
|
||||
return reader.ReadHandle<SafeFileHandle>();
|
||||
}
|
||||
).ConfigureAwait(false);
|
||||
} catch (DBusException e) {
|
||||
// Possible if login manager does not support inhibit, although that should be super rare
|
||||
ASF.ArchiLogger.LogGenericDebuggingException(e);
|
||||
ASF.ArchiLogger.LogGenericWarning(Strings.WarningNoSystemRequiredLinuxDependencies);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (InhibitLock == null) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.FormatWarningFailedWithError(nameof(InhibitLock)));
|
||||
}
|
||||
}
|
||||
|
||||
private static void MinimizeConsoleWindow() {
|
||||
(_, int top) = Console.GetCursorPosition();
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -313,7 +301,7 @@ public static class Utilities {
|
||||
// Now extract the zip file to entirely new location, this decreases chance of corruptions if user kills the process during this stage
|
||||
string updateDirectory = Path.Combine(targetDirectory, SharedInfo.UpdateDirectoryNew);
|
||||
|
||||
zipArchive.ExtractToDirectory(updateDirectory, true);
|
||||
await zipArchive.ExtractToDirectoryAsync(updateDirectory, true).ConfigureAwait(false);
|
||||
|
||||
// Now, critical section begins, we're going to move all files from target directory to a backup directory
|
||||
string backupDirectory = Path.Combine(targetDirectory, SharedInfo.UpdateDirectoryOld);
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -86,7 +86,11 @@ internal sealed class CrossProcessFileBasedSemaphore : IAsyncDisposable, ICrossP
|
||||
try {
|
||||
while (true) {
|
||||
if (!await EnsureFileExists().ConfigureAwait(false)) {
|
||||
throw new IOException(Strings.FormatWarningFailedWithError(nameof(EnsureFileExists)));
|
||||
ASF.ArchiLogger.LogGenericError(Strings.FormatWarningFailedWithError(nameof(EnsureFileExists)));
|
||||
|
||||
await Task.Delay(SpinLockDelay * 25, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -103,7 +107,9 @@ internal sealed class CrossProcessFileBasedSemaphore : IAsyncDisposable, ICrossP
|
||||
}
|
||||
} catch (FileNotFoundException) {
|
||||
throw;
|
||||
} catch (IOException) {
|
||||
} catch (IOException e) {
|
||||
ASF.ArchiLogger.LogGenericDebuggingException(e);
|
||||
|
||||
await Task.Delay(SpinLockDelay, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -128,7 +134,7 @@ internal sealed class CrossProcessFileBasedSemaphore : IAsyncDisposable, ICrossP
|
||||
try {
|
||||
stopwatch.Stop();
|
||||
|
||||
if (stopwatch.ElapsedMilliseconds >= millisecondsTimeout) {
|
||||
if (stopwatch.ElapsedMilliseconds > millisecondsTimeout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -136,7 +142,18 @@ internal sealed class CrossProcessFileBasedSemaphore : IAsyncDisposable, ICrossP
|
||||
|
||||
while (true) {
|
||||
if (!await EnsureFileExists().ConfigureAwait(false)) {
|
||||
throw new IOException(Strings.FormatWarningFailedWithError(nameof(EnsureFileExists)));
|
||||
ASF.ArchiLogger.LogGenericError(Strings.FormatWarningFailedWithError(nameof(EnsureFileExists)));
|
||||
|
||||
if (millisecondsTimeout <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int sleep = Math.Min(millisecondsTimeout, SpinLockDelay * 25);
|
||||
|
||||
await Task.Delay(sleep, cancellationToken).ConfigureAwait(false);
|
||||
millisecondsTimeout -= sleep;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -153,13 +170,17 @@ internal sealed class CrossProcessFileBasedSemaphore : IAsyncDisposable, ICrossP
|
||||
}
|
||||
} catch (FileNotFoundException) {
|
||||
throw;
|
||||
} catch (IOException) {
|
||||
if (millisecondsTimeout <= SpinLockDelay) {
|
||||
} catch (IOException e) {
|
||||
ASF.ArchiLogger.LogGenericDebuggingException(e);
|
||||
|
||||
if (millisecondsTimeout <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await Task.Delay(SpinLockDelay, cancellationToken).ConfigureAwait(false);
|
||||
millisecondsTimeout -= SpinLockDelay;
|
||||
int sleep = Math.Min(millisecondsTimeout, SpinLockDelay);
|
||||
|
||||
await Task.Delay(sleep, cancellationToken).ConfigureAwait(false);
|
||||
millisecondsTimeout -= sleep;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -184,20 +205,26 @@ internal sealed class CrossProcessFileBasedSemaphore : IAsyncDisposable, ICrossP
|
||||
}
|
||||
|
||||
if (!Directory.Exists(directoryPath)) {
|
||||
if (OperatingSystem.IsWindows()) {
|
||||
DirectoryInfo directoryInfo = Directory.CreateDirectory(directoryPath);
|
||||
try {
|
||||
if (OperatingSystem.IsWindows()) {
|
||||
DirectoryInfo directoryInfo = Directory.CreateDirectory(directoryPath);
|
||||
|
||||
try {
|
||||
DirectorySecurity directorySecurity = new(directoryPath, AccessControlSections.All);
|
||||
try {
|
||||
DirectorySecurity directorySecurity = new(directoryPath, AccessControlSections.All);
|
||||
|
||||
directoryInfo.SetAccessControl(directorySecurity);
|
||||
} catch (PrivilegeNotHeldException e) {
|
||||
// Non-critical, user might have no rights to manage the resource
|
||||
ASF.ArchiLogger.LogGenericDebuggingException(e);
|
||||
directoryInfo.SetAccessControl(directorySecurity);
|
||||
} catch (PrivilegeNotHeldException e) {
|
||||
// Non-critical, user might have no rights to manage the resource
|
||||
ASF.ArchiLogger.LogGenericDebuggingException(e);
|
||||
}
|
||||
} else if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) {
|
||||
// We require global access from all users, as other ASFs might need to put additional files in there
|
||||
Directory.CreateDirectory(directoryPath, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.GroupRead | UnixFileMode.GroupWrite | UnixFileMode.GroupExecute | UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute);
|
||||
}
|
||||
} else if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) {
|
||||
// We require global access from all users, as other ASFs might need to put additional files in there
|
||||
Directory.CreateDirectory(directoryPath, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.GroupRead | UnixFileMode.GroupWrite | UnixFileMode.GroupExecute | UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute);
|
||||
} catch (IOException e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,11 +255,21 @@ internal sealed class CrossProcessFileBasedSemaphore : IAsyncDisposable, ICrossP
|
||||
await new FileStream(FilePath, fileStreamOptions).DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignored, if the file was already created in the meantime by another instance, this is fine
|
||||
ASF.ArchiLogger.LogGenericDebuggingException(e);
|
||||
if (i == 0) {
|
||||
// Ignored, if the file was already created in the meantime by another instance, this is fine
|
||||
ASF.ArchiLogger.LogGenericDebuggingException(e);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// It's not fine if the same issue happened again
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
// It's also not fine if we failed to create the file twice in a row
|
||||
return File.Exists(FilePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace ArchiSteamFarm.Helpers;
|
||||
|
||||
[PublicAPI]
|
||||
public interface ICrossProcessSemaphore {
|
||||
void Release();
|
||||
Task WaitAsync(CancellationToken cancellationToken = default);
|
||||
Task<bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken = default);
|
||||
public void Release();
|
||||
public Task WaitAsync(CancellationToken cancellationToken = default);
|
||||
public Task<bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ using System.Reflection;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -116,12 +117,15 @@ public static class JsonUtilities {
|
||||
|
||||
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "We don't care about trimmed assemblies, as we need it to work only with the known (used) ones")]
|
||||
private static JsonSerializerOptions CreateDefaultJsonSerializerOptions(bool writeIndented = false) =>
|
||||
new() {
|
||||
new(JsonSerializerDefaults.Strict) {
|
||||
AllowTrailingCommas = true,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
IndentCharacter = '\t',
|
||||
IndentSize = 1,
|
||||
PropertyNamingPolicy = null,
|
||||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { ApplyCustomModifiers } },
|
||||
UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip,
|
||||
WriteIndented = writeIndented
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Helpers.Json;
|
||||
@@ -55,7 +56,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using NLog.Web;
|
||||
using Scalar.AspNetCore;
|
||||
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
|
||||
using IPNetwork = System.Net.IPNetwork;
|
||||
|
||||
namespace ArchiSteamFarm.IPC;
|
||||
|
||||
@@ -64,6 +65,8 @@ internal static class ArchiKestrel {
|
||||
|
||||
internal static HistoryTarget? HistoryTarget { get; private set; }
|
||||
|
||||
private static readonly SemaphoreSlim StateSemaphore = new(1, 1);
|
||||
|
||||
private static WebApplication? WebApplication;
|
||||
|
||||
internal static void OnNewHistoryTarget(HistoryTarget? historyTarget = null) {
|
||||
@@ -78,43 +81,43 @@ internal static class ArchiKestrel {
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task Start() {
|
||||
if (WebApplication != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.IPCStarting);
|
||||
|
||||
// Init history logger for /Api/Log usage
|
||||
Logging.InitHistoryLogger();
|
||||
|
||||
WebApplication webApplication = await CreateWebApplication().ConfigureAwait(false);
|
||||
internal static async Task Restart() {
|
||||
await StateSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
// Start the server
|
||||
await webApplication.StartAsync().ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
await webApplication.DisposeAsync().ConfigureAwait(false);
|
||||
await StopInternally().ConfigureAwait(false);
|
||||
await StartInternally().ConfigureAwait(false);
|
||||
} finally {
|
||||
StateSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task Start() {
|
||||
if (IsRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
WebApplication = webApplication;
|
||||
await StateSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.IPCReady);
|
||||
try {
|
||||
await StartInternally().ConfigureAwait(false);
|
||||
} finally {
|
||||
StateSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task Stop() {
|
||||
if (WebApplication == null) {
|
||||
if (!IsRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
await WebApplication.StopAsync().ConfigureAwait(false);
|
||||
await WebApplication.DisposeAsync().ConfigureAwait(false);
|
||||
await StateSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
WebApplication = null;
|
||||
try {
|
||||
await StopInternally().ConfigureAwait(false);
|
||||
} finally {
|
||||
StateSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "PathString is a primitive, it's unlikely to be trimmed to the best of our knowledge")]
|
||||
@@ -248,6 +251,11 @@ internal static class ArchiKestrel {
|
||||
// Add support for websockets that we use e.g. in /Api/NLog
|
||||
app.UseWebSockets();
|
||||
|
||||
// Add support for output caching
|
||||
if (ASF.GlobalConfig?.OptimizationMode != GlobalConfig.EOptimizationMode.MinMemoryUsage) {
|
||||
app.UseOutputCache();
|
||||
}
|
||||
|
||||
// Add additional endpoints provided by plugins
|
||||
foreach (IWebServiceProvider plugin in PluginsCore.ActivePlugins.OfType<IWebServiceProvider>()) {
|
||||
try {
|
||||
@@ -261,7 +269,11 @@ internal static class ArchiKestrel {
|
||||
app.MapControllers();
|
||||
|
||||
// Add support for OpenAPI, responsible for automatic API documentation generation, this should be on the end, once we're done with API
|
||||
app.MapOpenApi("/swagger/{documentName}/swagger.json");
|
||||
IEndpointConventionBuilder openApi = app.MapOpenApi("/swagger/{documentName}/swagger.json");
|
||||
|
||||
if (ASF.GlobalConfig?.OptimizationMode != GlobalConfig.EOptimizationMode.MinMemoryUsage) {
|
||||
openApi.CacheOutput();
|
||||
}
|
||||
|
||||
// Add support for swagger UI, this should be after swagger, obviously
|
||||
app.MapScalarApiReference(
|
||||
@@ -311,7 +323,7 @@ internal static class ArchiKestrel {
|
||||
|
||||
if (knownNetworks != null) {
|
||||
foreach (IPNetwork knownNetwork in knownNetworks) {
|
||||
options.KnownNetworks.Add(knownNetwork);
|
||||
options.KnownIPNetworks.Add(knownNetwork);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,6 +346,11 @@ internal static class ArchiKestrel {
|
||||
services.AddCors(static options => options.AddDefaultPolicy(static policyBuilder => policyBuilder.AllowAnyOrigin()));
|
||||
}
|
||||
|
||||
// Add support for output caching
|
||||
if (ASF.GlobalConfig?.OptimizationMode != GlobalConfig.EOptimizationMode.MinMemoryUsage) {
|
||||
services.AddOutputCache();
|
||||
}
|
||||
|
||||
// Add support for OpenAPI, responsible for automatic API documentation generation
|
||||
services.AddOpenApi(
|
||||
SharedInfo.ASF, static options => {
|
||||
@@ -505,4 +522,43 @@ internal static class ArchiKestrel {
|
||||
|
||||
headers.CacheControl = cacheControl;
|
||||
}
|
||||
|
||||
private static async Task StartInternally() {
|
||||
if (WebApplication != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.IPCStarting);
|
||||
|
||||
// Init history logger for /Api/Log usage
|
||||
Logging.InitHistoryLogger();
|
||||
|
||||
WebApplication webApplication = await CreateWebApplication().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
// Start the server
|
||||
await webApplication.StartAsync().ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
await webApplication.DisposeAsync().ConfigureAwait(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
WebApplication = webApplication;
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.IPCReady);
|
||||
}
|
||||
|
||||
private static async Task StopInternally() {
|
||||
if (WebApplication == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
await WebApplication.StopAsync().ConfigureAwait(false);
|
||||
await WebApplication.DisposeAsync().ConfigureAwait(false);
|
||||
|
||||
WebApplication = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
@@ -227,7 +226,7 @@ public sealed class BotController : ArchiController {
|
||||
|
||||
[EndpointSummary("Adds keys to redeem using BGR to given bot")]
|
||||
[HttpPost("{botNames:required}/GamesToRedeemInBackground")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, IOrderedDictionary>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, OrderedDictionary<string, string>>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
public async Task<ActionResult<GenericResponse>> GamesToRedeemInBackgroundPost(string botNames, [FromBody] BotGamesToRedeemInBackgroundRequest request) {
|
||||
ArgumentException.ThrowIfNullOrEmpty(botNames);
|
||||
@@ -243,21 +242,21 @@ public sealed class BotController : ArchiController {
|
||||
return BadRequest(new GenericResponse(false, Strings.FormatBotNotFound(botNames)));
|
||||
}
|
||||
|
||||
IOrderedDictionary validGamesToRedeemInBackground = Bot.ValidateGamesToRedeemInBackground(request.GamesToRedeemInBackground);
|
||||
Bot.FilterGamesToRedeemInBackground(request.GamesToRedeemInBackground);
|
||||
|
||||
if (validGamesToRedeemInBackground.Count == 0) {
|
||||
return BadRequest(new GenericResponse(false, Strings.FormatErrorIsEmpty(nameof(validGamesToRedeemInBackground))));
|
||||
if (request.GamesToRedeemInBackground.Count == 0) {
|
||||
return BadRequest(new GenericResponse(false, Strings.FormatErrorIsEmpty(nameof(request.GamesToRedeemInBackground))));
|
||||
}
|
||||
|
||||
await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.AddGamesToRedeemInBackground(validGamesToRedeemInBackground)))).ConfigureAwait(false);
|
||||
await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.AddGamesToRedeemInBackground(request.GamesToRedeemInBackground)))).ConfigureAwait(false);
|
||||
|
||||
Dictionary<string, IOrderedDictionary> result = new(bots.Count, Bot.BotsComparer);
|
||||
Dictionary<string, OrderedDictionary<string, string>> result = new(bots.Count, Bot.BotsComparer);
|
||||
|
||||
foreach (Bot bot in bots) {
|
||||
result[bot.BotName] = validGamesToRedeemInBackground;
|
||||
result[bot.BotName] = request.GamesToRedeemInBackground;
|
||||
}
|
||||
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, IOrderedDictionary>>(result));
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, OrderedDictionary<string, string>>>(result));
|
||||
}
|
||||
|
||||
[EndpointSummary("Provides input value to given bot for next usage")]
|
||||
|
||||
@@ -124,19 +124,19 @@ internal sealed class ApiAuthenticationMiddleware {
|
||||
return (HttpStatusCode.OK, true);
|
||||
}
|
||||
|
||||
if (ForwardedHeadersOptions.KnownNetworks.Count == 0) {
|
||||
if (ForwardedHeadersOptions.KnownIPNetworks.Count == 0) {
|
||||
return (HttpStatusCode.Forbidden, true);
|
||||
}
|
||||
|
||||
if (clientIP.IsIPv4MappedToIPv6) {
|
||||
IPAddress mappedClientIP = clientIP.MapToIPv4();
|
||||
|
||||
if (ForwardedHeadersOptions.KnownNetworks.Any(network => network.Contains(mappedClientIP))) {
|
||||
if (ForwardedHeadersOptions.KnownIPNetworks.Any(network => network.Contains(mappedClientIP))) {
|
||||
return (HttpStatusCode.OK, true);
|
||||
}
|
||||
}
|
||||
|
||||
return (ForwardedHeadersOptions.KnownNetworks.Any(network => network.Contains(clientIP)) ? HttpStatusCode.OK : HttpStatusCode.Forbidden, true);
|
||||
return (ForwardedHeadersOptions.KnownIPNetworks.Any(network => network.Contains(clientIP)) ? HttpStatusCode.OK : HttpStatusCode.Forbidden, true);
|
||||
}
|
||||
|
||||
if (!context.Request.Headers.TryGetValue(HeadersField, out StringValues passwords) && !context.Request.Query.TryGetValue("password", out passwords)) {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration;
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration;
|
||||
|
||||
@@ -45,16 +46,16 @@ public sealed class SwaggerItemsMinMaxAttribute : CustomSwaggerAttribute {
|
||||
public override void Apply(OpenApiSchema schema) {
|
||||
ArgumentNullException.ThrowIfNull(schema);
|
||||
|
||||
if (schema.Items == null) {
|
||||
if (schema.Items is not OpenApiSchema items) {
|
||||
throw new InvalidOperationException(nameof(schema.Items));
|
||||
}
|
||||
|
||||
if (BackingMinimum.HasValue) {
|
||||
schema.Items.Minimum = BackingMinimum.Value;
|
||||
items.Minimum = BackingMinimum.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
if (BackingMaximum.HasValue) {
|
||||
schema.Items.Maximum = BackingMaximum.Value;
|
||||
items.Maximum = BackingMaximum.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Nodes;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration;
|
||||
|
||||
@@ -36,10 +35,20 @@ public sealed class SwaggerSecurityCriticalAttribute : CustomSwaggerAttribute {
|
||||
public override void Apply(OpenApiSchema schema) {
|
||||
ArgumentNullException.ThrowIfNull(schema);
|
||||
|
||||
if (schema.Items is { Reference: null }) {
|
||||
schema.Items.AddExtension(ExtensionName, new OpenApiBoolean(true));
|
||||
} else {
|
||||
schema.AddExtension(ExtensionName, new OpenApiBoolean(true));
|
||||
JsonValue value = JsonValue.Create(true);
|
||||
|
||||
if (schema.Items != null) {
|
||||
if (schema.Items is OpenApiSchema items) {
|
||||
items.AddExtension(ExtensionName, new JsonNodeExtension(value));
|
||||
} else if (schema.Items.Extensions != null) {
|
||||
schema.Items.Extensions[ExtensionName] = new JsonNodeExtension(value);
|
||||
} else {
|
||||
throw new InvalidOperationException(nameof(schema.Items));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
schema.AddExtension(ExtensionName, new JsonNodeExtension(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration;
|
||||
@@ -38,7 +39,7 @@ public sealed class SwaggerSteamIdentifierAttribute : CustomSwaggerAttribute {
|
||||
public override void Apply(OpenApiSchema schema) {
|
||||
ArgumentNullException.ThrowIfNull(schema);
|
||||
|
||||
schema.Minimum = new SteamID(MinimumAccountID, Universe, AccountType);
|
||||
schema.Maximum = new SteamID(MaximumAccountID, Universe, AccountType);
|
||||
schema.Minimum = new SteamID(MinimumAccountID, Universe, AccountType).ConvertToUInt64().ToString(CultureInfo.InvariantCulture);
|
||||
schema.Maximum = new SteamID(MaximumAccountID, Universe, AccountType).ConvertToUInt64().ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,36 +22,50 @@
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json.Nodes;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration;
|
||||
|
||||
[PublicAPI]
|
||||
public sealed class SwaggerValidValuesAttribute : CustomSwaggerAttribute {
|
||||
private const string ExtensionName = "x-valid-values";
|
||||
|
||||
public int[]? ValidIntValues { get; init; }
|
||||
public string[]? ValidStringValues { get; init; }
|
||||
|
||||
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "We're not creating json values with non-primitive types")]
|
||||
public override void Apply(OpenApiSchema schema) {
|
||||
ArgumentNullException.ThrowIfNull(schema);
|
||||
|
||||
OpenApiArray validValues = [];
|
||||
JsonArray validValues = [];
|
||||
|
||||
if (ValidIntValues != null) {
|
||||
validValues.AddRange(ValidIntValues.Select(static type => new OpenApiInteger(type)));
|
||||
foreach (int value in ValidIntValues) {
|
||||
validValues.Add(JsonValue.Create(value));
|
||||
}
|
||||
}
|
||||
|
||||
if (ValidStringValues != null) {
|
||||
validValues.AddRange(ValidStringValues.Select(static type => new OpenApiString(type)));
|
||||
foreach (string value in ValidStringValues) {
|
||||
validValues.Add(JsonValue.Create(value));
|
||||
}
|
||||
}
|
||||
|
||||
if (schema.Items is { Reference: null }) {
|
||||
schema.Items.AddExtension("x-valid-values", validValues);
|
||||
} else {
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
if (schema.Items != null) {
|
||||
if (schema.Items is OpenApiSchema items) {
|
||||
items.AddExtension(ExtensionName, new JsonNodeExtension(validValues));
|
||||
} else if (schema.Items.Extensions != null) {
|
||||
schema.Items.Extensions[ExtensionName] = new JsonNodeExtension(validValues);
|
||||
} else {
|
||||
throw new InvalidOperationException(nameof(schema.Items));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
schema.AddExtension(ExtensionName, new JsonNodeExtension(validValues));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ using ArchiSteamFarm.IPC.Integration;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.OpenApi;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.OpenApi;
|
||||
|
||||
@@ -40,7 +40,6 @@ internal sealed class DocumentTransformer : IOpenApiDocumentTransformer {
|
||||
ArgumentNullException.ThrowIfNull(document);
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
|
||||
document.Info ??= new OpenApiInfo();
|
||||
document.Info.Title = $"{SharedInfo.AssemblyName} API";
|
||||
document.Info.Version = SharedInfo.Version.ToString();
|
||||
|
||||
@@ -53,7 +52,7 @@ internal sealed class DocumentTransformer : IOpenApiDocumentTransformer {
|
||||
document.Info.License.Url = new Uri(SharedInfo.LicenseURL);
|
||||
|
||||
document.Components ??= new OpenApiComponents();
|
||||
document.Components.SecuritySchemes ??= new Dictionary<string, OpenApiSecurityScheme>(1);
|
||||
document.Components.SecuritySchemes ??= new Dictionary<string, IOpenApiSecurityScheme>(1);
|
||||
|
||||
document.Components.SecuritySchemes.Add(
|
||||
nameof(GlobalConfig.IPCPassword), new OpenApiSecurityScheme {
|
||||
|
||||
@@ -28,7 +28,7 @@ using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.OpenApi;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.OpenApi;
|
||||
|
||||
@@ -45,13 +45,7 @@ internal sealed class OperationTransformer : IOpenApiOperationTransformer {
|
||||
operation.Security.Add(
|
||||
new OpenApiSecurityRequirement {
|
||||
{
|
||||
new OpenApiSecurityScheme {
|
||||
Reference = new OpenApiReference {
|
||||
Id = nameof(GlobalConfig.IPCPassword),
|
||||
Type = ReferenceType.SecurityScheme
|
||||
}
|
||||
},
|
||||
|
||||
new OpenApiSecuritySchemeReference(nameof(GlobalConfig.IPCPassword), context.Document),
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,13 @@
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.IPC.Integration;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.OpenApi;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.OpenApi;
|
||||
|
||||
@@ -72,9 +71,9 @@ internal sealed class SchemaTransformer : IOpenApiSchemaTransformer {
|
||||
schema.Format = "flags";
|
||||
}
|
||||
|
||||
OpenApiObject definition = new();
|
||||
JsonObject definition = new();
|
||||
|
||||
foreach (object? enumValue in context.JsonTypeInfo.Type.GetEnumValues()) {
|
||||
foreach (object? enumValue in context.JsonTypeInfo.Type.GetEnumValuesAsUnderlyingType()) {
|
||||
if (enumValue == null) {
|
||||
throw new InvalidOperationException(nameof(enumValue));
|
||||
}
|
||||
@@ -95,41 +94,26 @@ internal sealed class SchemaTransformer : IOpenApiSchemaTransformer {
|
||||
continue;
|
||||
}
|
||||
|
||||
IOpenApiAny enumObject;
|
||||
|
||||
if (TryCast(enumValue, out int intValue)) {
|
||||
enumObject = new OpenApiInteger(intValue);
|
||||
} else if (TryCast(enumValue, out long longValue)) {
|
||||
enumObject = new OpenApiLong(longValue);
|
||||
} else if (TryCast(enumValue, out ulong ulongValue)) {
|
||||
// OpenApi spec doesn't support ulongs as of now
|
||||
enumObject = new OpenApiString(ulongValue.ToString(CultureInfo.InvariantCulture));
|
||||
} else {
|
||||
throw new InvalidOperationException(nameof(enumValue));
|
||||
}
|
||||
|
||||
definition.Add(enumName, enumObject);
|
||||
// OpenApi seems to support only int and long from underlying enum types: https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/integral-numeric-types
|
||||
definition[enumName] = enumValue switch {
|
||||
sbyte value => JsonValue.Create((int) value),
|
||||
byte value => JsonValue.Create((int) value),
|
||||
short value => JsonValue.Create((int) value),
|
||||
ushort value => JsonValue.Create((int) value),
|
||||
int value => JsonValue.Create(value),
|
||||
uint value => JsonValue.Create((long) value),
|
||||
long value => JsonValue.Create(value),
|
||||
ulong value => JsonValue.Create(value.ToString(CultureInfo.InvariantCulture)),
|
||||
nint value when nint.Size <= 4 => JsonValue.Create((int) value),
|
||||
nint value when nint.Size <= 8 => JsonValue.Create((long) value),
|
||||
nint value => JsonValue.Create(value.ToString(CultureInfo.InvariantCulture)),
|
||||
nuint value when nuint.Size <= 4 => JsonValue.Create((long) value),
|
||||
nuint value => JsonValue.Create(value.ToString(CultureInfo.InvariantCulture)),
|
||||
_ => throw new InvalidOperationException(nameof(enumValue))
|
||||
};
|
||||
}
|
||||
|
||||
schema.AddExtension("x-definition", definition);
|
||||
}
|
||||
|
||||
private static bool TryCast<T>(object value, out T typedValue) where T : struct {
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
|
||||
try {
|
||||
typedValue = (T) Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
|
||||
|
||||
return true;
|
||||
} catch (InvalidCastException) {
|
||||
typedValue = default(T);
|
||||
|
||||
return false;
|
||||
} catch (OverflowException) {
|
||||
typedValue = default(T);
|
||||
|
||||
return false;
|
||||
}
|
||||
schema.AddExtension("x-definition", new JsonNodeExtension(definition));
|
||||
}
|
||||
}
|
||||
#pragma warning restore CA1812 // False positive, the class is used internally
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Collections.Specialized;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
@@ -33,9 +34,10 @@ namespace ArchiSteamFarm.IPC.Requests;
|
||||
public sealed class BotGamesToRedeemInBackgroundRequest {
|
||||
[Description("A string-string map that maps cd-key to redeem (key) to its name (value). Key in the map must be a valid and unique Steam cd-key. Value in the map must be a non-null and non-empty name of the key (e.g. game's name, but can be anything)")]
|
||||
[JsonInclude]
|
||||
[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
|
||||
[JsonRequired]
|
||||
[Required]
|
||||
public OrderedDictionary GamesToRedeemInBackground { get; private init; } = new();
|
||||
public OrderedDictionary<string, string> GamesToRedeemInBackground { get; private init; } = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
[JsonConstructor]
|
||||
private BotGamesToRedeemInBackgroundRequest() { }
|
||||
|
||||
@@ -75,7 +75,6 @@ public sealed class ASFResponse {
|
||||
internal ASFResponse(string buildVariant, bool canUpdate, GlobalConfig globalConfig, uint memoryUsage, DateTime processStartTime, Version version) {
|
||||
ArgumentException.ThrowIfNullOrEmpty(buildVariant);
|
||||
ArgumentNullException.ThrowIfNull(globalConfig);
|
||||
ArgumentOutOfRangeException.ThrowIfZero(memoryUsage);
|
||||
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(processStartTime, DateTime.UnixEpoch);
|
||||
ArgumentNullException.ThrowIfNull(version);
|
||||
|
||||
|
||||
@@ -87,7 +87,6 @@ StackTrace:
|
||||
{2}</value>
|
||||
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>Памылка запыту да: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
@@ -186,7 +185,6 @@ StackTrace:
|
||||
<value>Ваша версія: {0} | Апошняя версія: {1}</value>
|
||||
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputSteam2FA" xml:space="preserve">
|
||||
<value>Калі ласка, увядзіце код 2FA з з мабільнага дадатку Steam: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
@@ -438,15 +436,6 @@ StackTrace:
|
||||
<data name="BotStatusLimited" xml:space="preserve">
|
||||
<value>Бот абмежаваны і не можа атрымліваць карткі праз фарменне.</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotAccountFree" xml:space="preserve">
|
||||
<value>Акаўнт больш не заняты: працэс фармавання адноўлены!</value>
|
||||
</data>
|
||||
@@ -456,7 +445,6 @@ StackTrace:
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
<value>Падключэнне...</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStopping" xml:space="preserve">
|
||||
<value>Спыненне...</value>
|
||||
</data>
|
||||
@@ -464,46 +452,16 @@ StackTrace:
|
||||
<value>Канфігурацыя вашага бота няправільная. Калі ласка, праверце змест {0} і паспрабуйце яшчэ раз!</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="IdlingGameNotPossible" xml:space="preserve">
|
||||
<value>Фармаванне {0} ({1}) часова адключана, бо ASF зараз не можа зараз гуляць у гэтую гульню.</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotAccountLocked" xml:space="preserve">
|
||||
<value>Гэты акаўнт заблакіраваны, працэс фармавання больш недаступны!</value>
|
||||
</data>
|
||||
<data name="BotStatusLocked" xml:space="preserve">
|
||||
<value>Бот абмежаваны і не можа атрымліваць карты падчас фармавання.</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PluginsWarning" xml:space="preserve">
|
||||
<value>Вы загрузілі адзін або некалькі карыстальніцкіх убудоў у ASF. Паколькі мы не можам прапанаваць падтрымку мадыфікаваных канфігурацый, калі ласка, звярніцеся да адпаведных распрацоўнікаў, убудовы якіх вы вырашылі выкарыстоўваць у выпадку ўзнікнення якіх-небудзь праблем.</value>
|
||||
</data>
|
||||
@@ -519,59 +477,15 @@ StackTrace:
|
||||
<data name="InteractiveConsoleEnabled" xml:space="preserve">
|
||||
<value>Інтэрактыўная кансоль цяпер актыўная, націсніце 'c', каб увайсці ў рэжым каманд.</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="BotExtraIdlingCooldown" xml:space="preserve">
|
||||
<value>Чакаем да {0}, каб быць упэўненымі, што мы можам пачаць фармаванне...</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "1 minute")</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="Result" xml:space="preserve">
|
||||
<value>Рэзультат: {0}</value>
|
||||
<comment>{0} will be replaced by generic result of various functions that use this string</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PatchingFiles" xml:space="preserve">
|
||||
<value>Выпраўленне файлаў ASF...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
<value>Изключение: {0}() {1} StackTrace:{2}</value>
|
||||
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>Провалена заявка: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
@@ -578,7 +577,6 @@
|
||||
<value>Ботът има ниво {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>Сравняват се Steam предмети, #{0} път...</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -678,7 +676,6 @@
|
||||
<value>Вашият криптиращ ключ е много къс. Препоръчваме да ползвате някой, който е поне {0} байта (символа) голям.</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
</data>
|
||||
|
||||
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
|
||||
<value>Ползвате {0} настройка от {1} стойност, но не сте осигурили персонализиран крипто-ключ. Това напълно нарушава защитата, тъй като ASF е принуден да ползва собствен (познат) ключ. Трябва да осигурите персонализиран крипто-ключ, за да ползвате предлаганата защита от тези настройки.</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
@@ -698,7 +695,6 @@
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>Отдалечения сървър не знае нищо за версията до която се опитвате да ъпгрейднете. Подобна ситуация е възможна ако версията е публикувана скоро - отказване да се продължи с ъпдейта като допълнителна мярка за сигурност.</value>
|
||||
</data>
|
||||
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>Отдалечения сървър отговори с различен checksum, това може да показва корумпирано сваляне или MITM атака - отказване да се продължи с ъпдейта!</value>
|
||||
</data>
|
||||
@@ -717,22 +713,4 @@
|
||||
<value>Опитахте да използвате платена функция {0}, но нямате зададен валиден LicenseID в глобалната конфигурация на ASF. Моля, прегледайте конфигурацията си, тъй като функционалността няма да работи без допълнителни подробности.</value>
|
||||
<comment>{0} will be replaced by feature name (e.g. MatchActively)</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -77,16 +77,10 @@
|
||||
<value>Podešavanje {0} je netačno: {1}</value>
|
||||
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="ErrorIsInvalid" xml:space="preserve">
|
||||
<value>{0} je netačan!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorObjectIsNull" xml:space="preserve">
|
||||
<value>{0} je null!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
@@ -95,13 +89,9 @@
|
||||
<value>Parsiranje {0} nije uspelo!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>Neuspešno traženje nove verzije!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Izlaženje...</value>
|
||||
</data>
|
||||
@@ -147,15 +137,9 @@
|
||||
<data name="UpdateCheckingNewVersion" xml:space="preserve">
|
||||
<value>Traženje nove verzije...</value>
|
||||
</data>
|
||||
|
||||
<data name="UpdateFinished" xml:space="preserve">
|
||||
<value>Proces ažuriranja je završen!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="UserInputSteamLogin" xml:space="preserve">
|
||||
<value>Molimo Vas unestie vaše Steam korističko ime: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
@@ -168,7 +152,6 @@
|
||||
<value>Molimo Vas uneste vašu Steam lozinku: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>IPC server je spreman!</value>
|
||||
</data>
|
||||
@@ -182,48 +165,28 @@
|
||||
<value>Nije moguće pronaći bilo kakvog bot-a nazvanog {0}!</value>
|
||||
<comment>{0} will be replaced by bot's name query (string)</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="CheckingFirstBadgePage" xml:space="preserve">
|
||||
<value>Proveravanje prve strane bedževa...</value>
|
||||
</data>
|
||||
<data name="CheckingOtherBadgePages" xml:space="preserve">
|
||||
<value>Proveravanje ostalih strana bedževa...</value>
|
||||
</data>
|
||||
|
||||
<data name="Done" xml:space="preserve">
|
||||
<value>Gotovo!</value>
|
||||
</data>
|
||||
|
||||
<data name="IdlingFinished" xml:space="preserve">
|
||||
<value>Farmanje završeno!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="IdlingStopped" xml:space="preserve">
|
||||
<value>Farmanje zaustavljeno!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="UnknownCommand" xml:space="preserve">
|
||||
<value>Nepoznata komanda!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotAcceptingGift" xml:space="preserve">
|
||||
<value>Prihvatanje poklona: {0}...</value>
|
||||
<comment>{0} will be replaced by giftID (number)</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotAddLicense" xml:space="preserve">
|
||||
<value>ID: {0} | Status: {1}</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by status string</comment>
|
||||
@@ -235,8 +198,6 @@
|
||||
<data name="BotAlreadyRunning" xml:space="preserve">
|
||||
<value>Ovaj bot je već pokrenut!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotAuthenticatorToken" xml:space="preserve">
|
||||
<value>2FA Token: {0}</value>
|
||||
<comment>{0} will be replaced by generated 2FA token (string)</comment>
|
||||
@@ -262,8 +223,6 @@
|
||||
<data name="BotDisconnecting" xml:space="preserve">
|
||||
<value>Prekidanje veze...</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotLoggedOff" xml:space="preserve">
|
||||
<value>Odjavljen sa Steam-a: {0}</value>
|
||||
<comment>{0} will be replaced by logging off reason (string)</comment>
|
||||
@@ -275,28 +234,22 @@
|
||||
<data name="BotLoggingIn" xml:space="preserve">
|
||||
<value>Prijavljivanje...</value>
|
||||
</data>
|
||||
|
||||
<data name="BotLootingFailed" xml:space="preserve">
|
||||
<value>Ponuda za razmjenu nije uspjela!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotLootingSuccess" xml:space="preserve">
|
||||
<value>Ponuda za razmenu je uspešno poslata!</value>
|
||||
</data>
|
||||
<data name="BotSendingTradeToYourself" xml:space="preserve">
|
||||
<value>Ne možete poslati zahtjev za razmjenu sebi!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotNotConnected" xml:space="preserve">
|
||||
<value>Ova instanca bot-a nije povezana!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotPointsBalance" xml:space="preserve">
|
||||
<value>Stanje bodova: {0}</value>
|
||||
<comment>{0} will be replaced by the points balance value (integer)</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotReconnecting" xml:space="preserve">
|
||||
<value>Ponovno povezivanje...</value>
|
||||
</data>
|
||||
@@ -308,16 +261,12 @@
|
||||
<value>Ključ: {0} | Status: {1} | Stavke: {2}</value>
|
||||
<comment>{0} will be replaced by cd-key (string), {1} will be replaced by status string, {2} will be replaced by list of key-value pairs, separated by a comma</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="BotStatusConnecting" xml:space="preserve">
|
||||
<value>Bot je povezan sa Steam-om.</value>
|
||||
</data>
|
||||
<data name="BotStatusNotRunning" xml:space="preserve">
|
||||
<value>Bot ne radi.</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStatusPlayingNotAvailable" xml:space="preserve">
|
||||
<value>Bot se trenutno koristi.</value>
|
||||
</data>
|
||||
@@ -329,63 +278,30 @@
|
||||
<value>{0} je prazan!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
<value>Povezivanje...</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStopping" xml:space="preserve">
|
||||
<value>Zaustavljanje...</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="Initializing" xml:space="preserve">
|
||||
<value>Učitavanje {0}...</value>
|
||||
<comment>{0} will be replaced by service name that is being initialized</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotVersion" xml:space="preserve">
|
||||
<value>{0} V{1}</value>
|
||||
<comment>{0} will be replaced by program's name (e.g. "ASF"), {1} will be replaced by program's version (e.g. "1.0.0.0"). This string typically has nothing to translate and you should leave it as it is, unless you need to change the format, e.g. in RTL languages.</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="ErrorAccessDenied" xml:space="preserve">
|
||||
<value>Pristup odbijеn!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotLevel" xml:space="preserve">
|
||||
<value>Bot je nivo {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="ErrorAborted" xml:space="preserve">
|
||||
<value>Obustavljeno!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="PluginLoading" xml:space="preserve">
|
||||
<value>Učitavanje {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>
|
||||
@@ -393,7 +309,6 @@
|
||||
<data name="NothingFound" xml:space="preserve">
|
||||
<value>Ništa nije pronađeno!</value>
|
||||
</data>
|
||||
|
||||
<data name="PleaseWait" xml:space="preserve">
|
||||
<value>Molimo vas sačekajte...</value>
|
||||
</data>
|
||||
@@ -403,55 +318,8 @@
|
||||
<data name="Executing" xml:space="preserve">
|
||||
<value>Izvršavanje...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="Result" xml:space="preserve">
|
||||
<value>Rezultat: {0}</value>
|
||||
<comment>{0} will be replaced by generic result of various functions that use this string</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -73,19 +73,13 @@
|
||||
{0}</value>
|
||||
<comment>{0} will be replaced by content string. Please note that this string should include newline for formatting.</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="ErrorIsInvalid" xml:space="preserve">
|
||||
<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">
|
||||
<value>La petició ha fallat després de {0} intents!</value>
|
||||
<comment>{0} will be replaced by maximum number of tries</comment>
|
||||
@@ -93,9 +87,6 @@
|
||||
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
|
||||
<value>No s'ha pogut comprovar l'última versió!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>Sortint...</value>
|
||||
</data>
|
||||
@@ -148,11 +139,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>
|
||||
<data name="UserInputSteamLogin" xml:space="preserve">
|
||||
<value>Si us plau, introduïu el vostre nom d'usuari de Steam: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
@@ -165,7 +158,6 @@
|
||||
<value>Si us plau, introduïu la vostra contrasenya de Steam: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>Servidor IPC preparat!</value>
|
||||
</data>
|
||||
@@ -179,39 +171,67 @@
|
||||
<value>No s'ha trobat cap bot anomenat {0}!</value>
|
||||
<comment>{0} will be replaced by bot's name query (string)</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="CheckingFirstBadgePage" xml:space="preserve">
|
||||
<value>Comprovant la primera pàgina d'insígnies...</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="BotAddLicense" xml:space="preserve">
|
||||
<value>ID: {0} | Estat: {1}</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by status string</comment>
|
||||
@@ -226,12 +246,18 @@
|
||||
<data name="BotAuthenticatorConverting" xml:space="preserve">
|
||||
<value>Convertint arxiu .maFile a format ASF...</value>
|
||||
</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>
|
||||
@@ -241,158 +267,77 @@
|
||||
<data name="BotDisconnecting" xml:space="preserve">
|
||||
<value>Desconnectant...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotLoggingIn" xml:space="preserve">
|
||||
<value>Iniciant sessió...</value>
|
||||
</data>
|
||||
|
||||
<data name="BotLootingFailed" xml:space="preserve">
|
||||
<value>L'oferta d'intercanvi ha fallat!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotLootingSuccess" xml:space="preserve">
|
||||
<value>Oferta d'intercanvi enviada amb èxit!</value>
|
||||
</data>
|
||||
<data name="BotSendingTradeToYourself" xml:space="preserve">
|
||||
<value>No podeu enviar una oferta d'intercanvi a vosaltres mateixos!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotReconnecting" xml:space="preserve">
|
||||
<value>Tornant a connectar...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotStatusNotRunning" xml:space="preserve">
|
||||
<value>El bot no està en funcionament.</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="ErrorIsEmpty" xml:space="preserve">
|
||||
<value>{0} no conté res!</value>
|
||||
<comment>{0} will be replaced by object's name</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
<value>S'està connectant...</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStopping" xml:space="preserve">
|
||||
<value>Aturant...</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="Initializing" xml:space="preserve">
|
||||
<value>Inicialitzant {0}...</value>
|
||||
<comment>{0} will be replaced by service name that is being initialized</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<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">
|
||||
<value>{0} V{1}</value>
|
||||
<comment>{0} will be replaced by program's name (e.g. "ASF"), {1} will be replaced by program's version (e.g. "1.0.0.0"). This string typically has nothing to translate and you should leave it as it is, unless you need to change the format, e.g. in RTL languages.</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="ErrorAccessDenied" xml:space="preserve">
|
||||
<value>Accés denegat!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
<data name="Result" xml:space="preserve">
|
||||
<value>Resultat: {0}</value>
|
||||
<comment>{0} will be replaced by generic result of various functions that use this string</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PatchingFiles" xml:space="preserve">
|
||||
<value>Apedaçant els arxius de l'ASF...</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ StackTrace:
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Prohlásili jste --system-required i když na vašem OS chybí požadované závislosti, aby tato funkce fungovala. Zvažte instalaci dbus, i když můžete bezpečně ignorovat toto upozornění, pokud nepotřebujete inhibici pro správné fungování.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ Processens oppetid: {1}</value>
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Du har erklæret --system-krævet, selvom dit operativsystem mangler krævede afhængigheder for at denne funktion kan fungere. Overvej at installere dbus, selvom du også trygt kan ignorere denne advarsel, hvis du ikke behøver hæmning for at fungere korrekt.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -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.
|
||||
@@ -801,4 +801,7 @@ Prozesslaufzeit: {1}</value>
|
||||
<value>Eingabe: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Sie haben --system-required deklariert, obwohl Ihrem Betriebssystem die erforderlichen Abhängigkeiten fehlen, damit diese Funktion funktioniert. Erwägen Sie die Installation von dbus, obwohl Sie diese Warnung auch sicher ignorieren können, wenn Sie keine Hemmung benötigen, um ordnungsgemäß zu funktionieren.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -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>
|
||||
@@ -794,4 +792,7 @@ StackTrace:
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Έχετε δηλώσει το -- system-required αν και λείπουν οι απαιτούμενες εξαρτήσεις του λειτουργικού σας συστήματος για να λειτουργήσει αυτή η λειτουργία. Σκεφτείτε την εγκατάσταση dbus, αν και μπορείτε επίσης να αγνοήσετε με ασφάλεια αυτή την προειδοποίηση αν δεν χρειάζεστε αναστολή για να λειτουργήσει σωστά.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -799,4 +799,7 @@ Tiempo de actividad del proceso: {1}</value>
|
||||
<value>Entrada: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Ha declarado --system-required, aunque su sistema operativo carece de dependencias requeridas para que esa característica funcione. Considere instalar dbus, aunque también puede ignorar de forma segura esta advertencia si no requiere inhibición para funcionar correctamente.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -510,24 +510,6 @@ StackTrace:
|
||||
<data name="Welcome" xml:space="preserve">
|
||||
<value>بنظر می رسد اولین استفاده ی شما از این برنامه باشد، خوش آمدید! 3:</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotWalletBalance" xml:space="preserve">
|
||||
<value>موجودی والت: {0} {1}</value>
|
||||
<comment>{0} will be replaced by wallet balance value, {1} will be replaced by currency name</comment>
|
||||
@@ -539,19 +521,12 @@ StackTrace:
|
||||
<value>بات لول {0} است.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="ErrorAborted" xml:space="preserve">
|
||||
<value>کنسل شد!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="NothingFound" xml:space="preserve">
|
||||
<value>چیزی پیدا نشد!</value>
|
||||
</data>
|
||||
|
||||
<data name="PleaseWait" xml:space="preserve">
|
||||
<value>لطفا صبر کنید...</value>
|
||||
</data>
|
||||
@@ -561,65 +536,22 @@ StackTrace:
|
||||
<data name="Executing" xml:space="preserve">
|
||||
<value>در حال اجرا...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="UpdateCleanup" xml:space="preserve">
|
||||
<value>درحال پاک سازی فایل های قدیمی بعد از به روزرسانی...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="Result" xml:space="preserve">
|
||||
<value>نتایج: {0}</value>
|
||||
<comment>{0} will be replaced by generic result of various functions that use this string</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PatchingFiles" xml:space="preserve">
|
||||
<value>در حال پچ کردن فایل های ASF...</value>
|
||||
</data>
|
||||
|
||||
<data name="ErrorIPNotBanned" xml:space="preserve">
|
||||
<value>آدرس آیپی {0} بن نشده است!</value>
|
||||
<comment>{0} will be replaced by an IP address which was requested to be unbanned from using IPC</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="WarningSkipping" xml:space="preserve">
|
||||
<value>در حال رد کردن: {0}...</value>
|
||||
<comment>{0} will be replaced by text value (string) of entry being skipped.</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ Prosessin käyttöaika: {1}</value>
|
||||
<value>Syöte: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Olet julistanut --system-pakolliseksi, vaikka käyttöjärjestelmästäsi puuttuu vaaditut riippuvuudet, jotta toiminto toimisi. Harkitse dbusin asentamista, vaikka voit myös turvallisesti ohittaa tämän varoituksen, jos et vaadi estoa toimimaan kunnolla.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ Durée de fonctionnement : {1}</value>
|
||||
<value>Saisie : {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Vous avez déclaré que --system-needed était nécessaire pour que cette fonctionnalité fonctionne, mais il manque à votre système d'exploitation des dépendances nécessaires. Pensez à installer dbus, bien que vous puissiez également ignorer cet avertissement en toute sécurité si vous n'avez pas besoin d'une inhibition pour fonctionner correctement.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -87,7 +87,6 @@ StackTrace:
|
||||
{2}</value>
|
||||
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>בקשה נכשלה: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
@@ -581,7 +580,6 @@ StackTrace:
|
||||
<value>לבוט יש רמה {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>מתאים פריטי Steam, שלב #{0}...</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -681,7 +679,6 @@ StackTrace:
|
||||
<value>מפתח ההצפנה שלך קצר מדי. אנו ממליצים להשתמש באחד שאורכו לפחות {0} בייטים (תווים).</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
</data>
|
||||
|
||||
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
|
||||
<value>אתה משתמש בהגדרה {0} של המאפיין {1}, אך לא סיפקת --cryptkey מותאם אישית. זה מביס לחלוטין את ההגנה, מכיוון ש-ASF נאלץ להשתמש במפתח (ידוע) משלו. עליך לספק --cryptkey מותאם אישית כדי לעשות שימוש בהטבת האבטחה שמציעה הגדרה זו.</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
@@ -701,7 +698,6 @@ StackTrace:
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>השרת המרוחק לא יודע כלום על המהדורה שאליה אנחנו מעדכנים. מצב זה אפשרי אם המהדורה פורסמה לאחרונה - מסרב להמשיך בהליך העדכון באופן מיידי כאמצעי אבטחה נוסף.</value>
|
||||
</data>
|
||||
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>שרת מרוחק השיב עם סכום ביקורת אחר, זה עשוי להצביע על הורדה פגומה או התקפת MITM, מסרב להמשיך בהליך העדכון!</value>
|
||||
</data>
|
||||
@@ -720,22 +716,4 @@ StackTrace:
|
||||
<value>ניסית להשתמש בתכונה בתשלום {0} אך אין לך מזהה רישיון חוקי שהוגדר בתצורה הגלובלית של ASF. אנא בדוק את התצורה שלך, מכיוון שהפונקציונליות לא תעבוד ללא פרטים נוספים.</value>
|
||||
<comment>{0} will be replaced by feature name (e.g. MatchActively)</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -181,180 +181,4 @@ Automatsko ažuriranje na tu verziju nije moguće.</value>
|
||||
<value/>
|
||||
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -582,7 +582,6 @@ Ennyi ideje fut: {1}</value>
|
||||
<value>A bot szintje: {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>Steam tárgyak egyeztetése #{0}...</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -705,7 +704,6 @@ Ennyi ideje fut: {1}</value>
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>A távoli szerver semmit sem tud a verzióról, amelyre frissítünk. Ez a helyzet akkor lehetséges, ha a verzió a közelmúltban jelent meg – további biztonsági intézkedésként nem hajlandó azonnal folytatni a frissítési eljárást.</value>
|
||||
</data>
|
||||
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>A távoli szerver más ellenőrzőösszeggel válaszolt, ez hibás letöltésre vagy MITM-támadásra utalhat, és nem hajlandó folytatni a frissítési eljárást!</value>
|
||||
</data>
|
||||
@@ -735,19 +733,4 @@ Ennyi ideje fut: {1}</value>
|
||||
<data name="ErrorTooManyCrashes" xml:space="preserve">
|
||||
<value>Az ASF-ed túl sokszor crashelt a közelmúltban, és emiatt a folyamat inicializálás ki lett kapcsolva. Vagy nyomozd ki, vagy javítsd meg a felszerelésedet, aztán töröld az ASF.crash fájlod a beállítás könyvtáradból, vagy lásd el --ignorál a nem támogatott felszerelést ha tudod mit csinálsz.</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -580,7 +580,6 @@
|
||||
<value>Bot mempunyai level {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>Mencocokkan item dari Steam, fase #{0}...</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -789,5 +788,4 @@
|
||||
<data name="CustomPluginUpdatesEnabled" xml:space="preserve">
|
||||
<value>Plugin kustom telah didaftarkan untuk pembaruan otomatis. Tim ASF ingin mengingatkan Anda bahwa, demi keamanan Anda, Anda hanya boleh mengaktifkan pembaruan otomatis dari pihak yang tepercaya. Jika Anda tidak bermaksud melakukan ini, Anda dapat menonaktifkan pembaruan plugin di konfigurasi global ASF.</value>
|
||||
</data>
|
||||
|
||||
</root>
|
||||
|
||||
@@ -798,4 +798,7 @@ Tempo di attività: {1}</value>
|
||||
<value>Inserisci: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Hai dichiarato --system-requireed, anche se il tuo sistema operativo manca di dipendenze richieste per far funzionare quella funzione. Considerare l'installazione di dbus, anche se si può tranquillamente ignorare questo avviso se non si richiede inibizione per funzionare correttamente.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -797,4 +797,7 @@ Process uptime: {1}</value>
|
||||
<value>入力: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>--system-requiredと宣言しましたが、その機能を動作させるために必要な依存関係が不足しています。 正常に動作するように阻害を必要としない場合は、この警告を無視することもできますが、dbusをインストールすることを検討してください。</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -68,229 +68,30 @@
|
||||
<value>ASF ავტომატურად შემოწმედბა ახალ ვერსიისთვის ყველა {0}-ში.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "24 hours")</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>გამოსვლა...</value>
|
||||
</data>
|
||||
<data name="WarningFailed" xml:space="preserve">
|
||||
<value>ვერ მოხერხდა!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="Restarting" xml:space="preserve">
|
||||
<value>რესტარტდება...</value>
|
||||
</data>
|
||||
|
||||
<data name="Success" xml:space="preserve">
|
||||
<value>წარმატება!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PleaseWait" xml:space="preserve">
|
||||
<value>გთხოვთ დაელოდოთ...</value>
|
||||
</data>
|
||||
<data name="EnterCommand" xml:space="preserve">
|
||||
<value>შეიყვანეთ ბრძანება: </value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="Result" xml:space="preserve">
|
||||
<value>შედეგი: {0}</value>
|
||||
<comment>{0} will be replaced by generic result of various functions that use this string</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="WarningSkipping" xml:space="preserve">
|
||||
<value>გამოტოვება: {0}...</value>
|
||||
<comment>{0} will be replaced by text value (string) of entry being skipped.</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -584,7 +584,6 @@ StackTrace:
|
||||
<value>봇은 레벨 {0} 입니다.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>#{0} 번째 Steam 아이템 매칭 중입니다.</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -684,7 +683,6 @@ StackTrace:
|
||||
<value>암호키가 너무 짧습니다. 최소한 {0} 바이트(글자수) 길이 이상의 암호키를 사용하는 것을 추천합니다.</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
</data>
|
||||
|
||||
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
|
||||
<value>{1} 속성의 {0} 설정을 사용하고 있습니다만, 별도의 -cryptkey를 사용하고 있지 않습니다. ASF는 자체 (이미 알려진) 키를 사용해야하므로 보호 기능이 제대로 동작하지 않습니다. 설정이 제공하는 보안의 효과를 누리기 위하여 별도의 -cryptkey를 사용해야 합니다.</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
@@ -704,7 +702,6 @@ StackTrace:
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>원격 서버는 최신 배포본의 업데이트에 대하여 알지 못합니다. 이 상황은 최근에 새로운 배포본이 배포되었을 때 발생할 수 있으며 추가 보안 조치로 업데이트를 즉시 진행하지 않습니다.</value>
|
||||
</data>
|
||||
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>원격서버와 체크섬이 다릅니다. 다운로드 받은 실행화일이 깨졌거나, 중간자 공격(MITM) 을 받았을 수도 있습니다. 업데이트를 진행하지 않습니다.</value>
|
||||
</data>
|
||||
@@ -738,20 +735,7 @@ StackTrace:
|
||||
<value>{0} ({1}) 게임이 비공개로 설정되어 있기 때문에 농사를 지을 수 없습니다. ASF로 이 게임 농사를 지으려면 공개로 변경해주세요.</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="CustomPluginUpdatesEnabled" xml:space="preserve">
|
||||
<value>커스텀 플러그인들이 자동 업데이트에 등록되었습니다. ASF 팀은 안전을 위해 신뢰할 수 있는 출처들에서만 자동 업데이트를 활성화할 것을 명시 드립니다. 만약 원치 않으신다면, ASF 글로벌 설정에서 플러그인 업데이트를 비활성화할 수 있습니다.</value>
|
||||
</data>
|
||||
|
||||
</root>
|
||||
|
||||
@@ -87,7 +87,6 @@ StackTrace:
|
||||
{2}</value>
|
||||
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>Užklausa nutrūksta: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
@@ -581,7 +580,6 @@ Proceso veikimo laikas: {1}</value>
|
||||
<value>Botas neturi {0} lygio.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>Derinami Steam item'ai, #{0} raundas...</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -681,7 +679,6 @@ Proceso veikimo laikas: {1}</value>
|
||||
<value>Jūsų šifravimo raktas yra per trumpas. Rekomenduojame naudoti raktą, kuris yra bent {0} baitų (simbolių) ilgio.</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
</data>
|
||||
|
||||
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
|
||||
<value>Jūs naudojate {0} nustatymą is {1} ypatybės, tačiau nenurodėte tinkintos --cryptkey savybės. Tai prieštarauja apsaugai, kadangi ASF bus priversta naudoti savo (žinomą) raktą. Reiktų nurodyti tinkintą --cryptkey savybę, kad šio gautumėte šio nustatymo naudą.</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
@@ -701,7 +698,6 @@ Proceso veikimo laikas: {1}</value>
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>Nuotolinis serveris nežino apie išleidimą, į kurį bandote atsinaujinti. Ši situacija galima, jeigu išleidimas buvo neseniai paskelbtas - neleidžiama atnaujinti iš karto dėl papildomos apsaugos.</value>
|
||||
</data>
|
||||
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>Nuotolinis serveris atsakė su nesutampančia kontroline suma. Tai gali būti dėl sugadinto atsisiuntimo arba MITM atakos. Atsisakoma tęsti atnaujinimo procesą!</value>
|
||||
</data>
|
||||
@@ -720,22 +716,4 @@ Proceso veikimo laikas: {1}</value>
|
||||
<value>Jūs bandote naudoti mokamą funkciją {0}, tačiau jūs neturite tinkamo LicenseID nustatyto globalioje konfigūracijoje. Prašome patikrinti savo konfigūraciją, kadangi funkcija neveiks be papildomų detalių.</value>
|
||||
<comment>{0} will be replaced by feature name (e.g. MatchActively)</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -799,4 +799,7 @@ Proces uptime: {1}</value>
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Je hebt verklaard --system-verplicht te zijn, hoewel je OS vereiste afhankelijkheden mist om die functie te laten werken. Overweeg het installeren van dbus, maar je kunt deze waarschuwing ook negeren als je geen remmen nodig hebt om goed te werken.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -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>
|
||||
@@ -779,4 +772,7 @@ prosess oppgang: {1}</value>
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Du har erklært --system-nødvendig, selv om OS mangler nødvendige avhengigheter for at den funksjonen skal fungere. Vurder å installere dbus, selv om du også trygt kan overse denne advarselen hvis du ikke trenger hemming av denne funksjonen.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ Czas procesu: {1}</value>
|
||||
<value>Wejście: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Zgłosiłeś --system-wymagane, chociaż w systemie operacyjnym brakuje wymaganych zależności, aby ta funkcja działała. Rozważ zainstalowanie dbus, chociaż możesz również bezpiecznie zignorować to ostrzeżenie, jeśli nie wymagasz zahamowania prawidłowego działania.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ Tempo de execução: {1}</value>
|
||||
<value>Entrada: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Você declarou --system-required embora esteja faltando as dependências necessárias para que esse recurso funcione. Considere instalar o dbus, embora você também possa ignorar com segurança este aviso se não exigir inibição para funcionar corretamente.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ Tempo de execução: {1}</value>
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Você declarou --system-required embora esteja faltando as dependências necessárias para que esse recurso funcione. Considere instalar o dbus, embora você também possa ignorar com segurança este aviso se não exigir inibição para funcionar corretamente.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ Process uptime: {1}</value>
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>You've declared --system-required, although your OS is missing required dependencies for that feature to work. Consider installing dbus, although you can also safely ignore this warning if you do not require inhibition to work properly.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@ Proces: {1}</value>
|
||||
<value>Intrare: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Ați declarat --necesar sistemului, deși sistemul dvs. de operare lipsește dependențele necesare pentru ca această caracteristică să funcționeze. Luați în considerare instalarea autobuzului, deși puteți ignora în siguranță această avertizare dacă nu aveți nevoie de inhibiție pentru a funcționa corect.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -804,4 +804,7 @@
|
||||
Файл: Strings.resx</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Вы объявили --system-required, хотя ваша ОС не имеет необходимых зависимостей для работы этой функции. Рассмотрим установку dbus, хотя вы также можете безопасно проигнорировать это предупреждение, если вам не требуется запрещение для нормальной работы.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -584,7 +584,6 @@ Doba prevádzky procesu: {1}</value>
|
||||
<value>Bot má level {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>Porovnávanie položiek na Steame, kolo #{0}...</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -685,7 +684,6 @@ Interaktívna konzola je teraz aktívna, napíšte "c" pre vstup do príkazovéh
|
||||
<value>Váš šifrovací kľuč je príliš krátky. Doporučujeme použiť ten, ktorý je aspoň {0} bajtu (znakov) dlhý.</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
</data>
|
||||
|
||||
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
|
||||
<value>Používate {0} nastavenie vlastnosti {1}, ale neposkytujete vlastný --cryptkey. To celkovo ruší ochranu, pretože ASF je nútený použiť svoj vlastný (známy) kľuč. Pre využitie bezpečnostného prínosu ponúkaného týmto nastavením, by ste mali poskytnúť vlastní --cryptkey.</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
@@ -705,7 +703,6 @@ Interaktívna konzola je teraz aktívna, napíšte "c" pre vstup do príkazovéh
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>Vzdialený server nepozná verziu na ktorú se snažíte aktualizovať. Táto situácia nastáva, pokiaľ verzia bola vydaná nedávno - aktualizácia nebude z bezpečnostných dôvodov pokračovať.</value>
|
||||
</data>
|
||||
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>Vzdialený server odpovedal s iným kontrolným súčtom, čo môže naznačovať chybu pri sťahovaní alebo útok MITM, proces aktualizácie preto nebude pokračovať!</value>
|
||||
</data>
|
||||
@@ -728,10 +725,6 @@ Interaktívna konzola je teraz aktívna, napíšte "c" pre vstup do príkazovéh
|
||||
<value>ASF nemôže spustiť aplikáciu {0}, pretože má regionálne obmedzenie pre krajinu {1}, ktoré trvá do {2}.</value>
|
||||
<comment>{0} will be replaced by app ID (number), {1} will be replaced by short country code (string, such as "PL"), {2} will be replaced by human-readable date (string).</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PluginUpdatesChecking" xml:space="preserve">
|
||||
<value>Kontrolujem aktualizácie pluginov...</value>
|
||||
</data>
|
||||
@@ -743,13 +736,10 @@ Interaktívna konzola je teraz aktívna, napíšte "c" pre vstup do príkazovéh
|
||||
<value>Žiadne dostupné aktualizácie pre {0} plugin: {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="PluginUpdateFound" xml:space="preserve">
|
||||
<value>Našla sa aktualizácia pre {0} plugin z verzie {1} na {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>Aktualizujem {0} plugin...</value>
|
||||
<comment>{0} will be replaced by plugin name (string).</comment>
|
||||
@@ -762,7 +752,4 @@ Interaktívna konzola je teraz aktívna, napíšte "c" pre vstup do príkazovéh
|
||||
<value>{0}/{1} plugin bol zaregistrovaný a automatické aktualizácie boli aktivované.</value>
|
||||
<comment>{0} will be replaced by plugin name (string), {1} will be replaced by plugin assembly name (string).</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -87,7 +87,6 @@ StackTrace:
|
||||
{2}</value>
|
||||
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>Zahtev se ne izvršava: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
@@ -231,8 +230,6 @@ StackTrace:
|
||||
<value>Trenutno radi {0}/{1} botova, a preostalo je ukupno {2} igrica ({3} karata) koje treba farmati.</value>
|
||||
<comment>{0} will be replaced by number of active bots, {1} will be replaced by total number of bots, {2} will be replaced by total number of games left to farm, {3} will be replaced by total number of cards left to farm</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="CheckingFirstBadgePage" xml:space="preserve">
|
||||
<value>Proveravanje prve stranje bedževa...</value>
|
||||
</data>
|
||||
@@ -246,11 +243,9 @@ StackTrace:
|
||||
<data name="Done" xml:space="preserve">
|
||||
<value>Gotovo!</value>
|
||||
</data>
|
||||
|
||||
<data name="IdlingFinished" xml:space="preserve">
|
||||
<value>Idlovanje je završeno!</value>
|
||||
</data>
|
||||
|
||||
<data name="IdlingFinishedForGames" xml:space="preserve">
|
||||
<value>Završeno idlovanje igrica: {0}</value>
|
||||
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
|
||||
@@ -401,7 +396,6 @@ StackTrace:
|
||||
<value>U vlasništvu: {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="BotRateLimitExceeded" xml:space="preserve">
|
||||
<value>Stopa ograničenja je prevazićena, pokušaćemo ponovo nakon {0} čekanja...</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "25 minutes")</comment>
|
||||
@@ -566,7 +560,6 @@ Vrijeme rada procesa: {1}</value>
|
||||
<value>Bot ima nivo {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>Podudaranje Steam itema, runda #{0}...</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -619,7 +612,6 @@ Vrijeme rada procesa: {1}</value>
|
||||
<value>Uspješno obavljeno/a {0} potvrda/e!</value>
|
||||
<comment>{0} will be replaced by number of confirmations</comment>
|
||||
</data>
|
||||
|
||||
<data name="UpdateCleanup" xml:space="preserve">
|
||||
<value>Čišćenje starih fajlova nakon ažuriranja...</value>
|
||||
</data>
|
||||
@@ -651,38 +643,4 @@ Vrijeme rada procesa: {1}</value>
|
||||
<data name="ErrorConfigDirectoryNotFound" xml:space="preserve">
|
||||
<value>Nije pronađen config direktorijum, odustajanje!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -801,4 +801,7 @@ Processens drifttid: {1}</value>
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Du har deklarerat --system-krävs, även om ditt operativsystem saknar nödvändiga beroenden för att den funktionen ska fungera. Överväg att installera dbus, men du kan också säkert ignorera denna varning om du inte behöver hämning för att fungera korrekt.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -87,7 +87,6 @@ StackTrace:
|
||||
{2}</value>
|
||||
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>คำขอล้มเหลว: {0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
@@ -125,7 +124,6 @@ StackTrace:
|
||||
<data name="ErrorUpdateNoAssets" xml:space="preserve">
|
||||
<value>ไม่สามารถดำเนินการอัพเดตได้เนื่อจากเวอร์ชั่นดังกล่าวไม่มีแอทเซทซใดๆอยู่!</value>
|
||||
</data>
|
||||
|
||||
<data name="Exiting" xml:space="preserve">
|
||||
<value>กำลังออก…</value>
|
||||
</data>
|
||||
@@ -185,7 +183,6 @@ StackTrace:
|
||||
<value>เวอร์ชันบนเครื่อง: {0} | เวอร์ชันบนเซิร์ฟเวอร์: {1}</value>
|
||||
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputSteam2FA" xml:space="preserve">
|
||||
<value>โปรดป้อนรหัส 2FA ของคุณจากแอปยืนยันตัวตน Steam ของคุณ: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
@@ -206,7 +203,6 @@ StackTrace:
|
||||
<value>โปรดป้อนรหัสผ่าน Steam ขอบคุณ: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
<value>เซิร์ฟเวอร์ IPC พร้อมแล้ว!</value>
|
||||
</data>
|
||||
@@ -220,8 +216,6 @@ StackTrace:
|
||||
<value>ไม่พบบอตชื่อ {0}!</value>
|
||||
<comment>{0} will be replaced by bot's name query (string)</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotStatusIdlingList" xml:space="preserve">
|
||||
<value>บอตกำลังฟาร์มเกม: เหลือให้ฟาร์ม {0} จากทั้งหมด {1} เกม (การ์ด {2} ใบ) (อีก ~{3})</value>
|
||||
<comment>{0} will be replaced by list of the games (IDs, numbers), {1} will be replaced by total number of games to farm, {2} will be replaced by total number of cards to farm, {3} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
|
||||
@@ -261,7 +255,6 @@ StackTrace:
|
||||
<data name="IdlingStopped" xml:space="preserve">
|
||||
<value>การฟาร์มหยุดแล้ว!</value>
|
||||
</data>
|
||||
|
||||
<data name="NothingToIdle" xml:space="preserve">
|
||||
<value>บัญชีนี้ไม่มีอะไรให้เราฟาร์มเลย!</value>
|
||||
</data>
|
||||
@@ -273,7 +266,6 @@ StackTrace:
|
||||
<value>กำลังฟาร์ม: {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>ยังคงฟาร์ม: {0} ({1})</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
@@ -293,8 +285,6 @@ StackTrace:
|
||||
<data name="UnknownCommand" xml:space="preserve">
|
||||
<value>ไม่รู้จักคำสั่งนี้!</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotAcceptingGift" xml:space="preserve">
|
||||
<value>กำลังยอมรับของขวัญ: {0}...</value>
|
||||
<comment>{0} will be replaced by giftID (number)</comment>
|
||||
@@ -316,7 +306,6 @@ StackTrace:
|
||||
<data name="BotAuthenticatorConverting" xml:space="preserve">
|
||||
<value>กำลังแปลง .maFile ให้เป็นฟอร์แมตสำหรับ ASF...</value>
|
||||
</data>
|
||||
|
||||
<data name="BotAuthenticatorToken" xml:space="preserve">
|
||||
<value>โทเคน 2FA: {0}</value>
|
||||
<comment>{0} will be replaced by generated 2FA token (string)</comment>
|
||||
@@ -342,8 +331,6 @@ StackTrace:
|
||||
<data name="BotDisconnecting" xml:space="preserve">
|
||||
<value>กำลังตัดการเชื่อมต่อ...</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotLoggedOff" xml:space="preserve">
|
||||
<value>ออกจากระบบ Steam แล้ว: {0}</value>
|
||||
<comment>{0} will be replaced by logging off reason (string)</comment>
|
||||
@@ -355,18 +342,15 @@ StackTrace:
|
||||
<data name="BotLoggingIn" xml:space="preserve">
|
||||
<value>กำลังเข้าสู่ระบบ...</value>
|
||||
</data>
|
||||
|
||||
<data name="BotLootingFailed" xml:space="preserve">
|
||||
<value>ข้อเสนอแลกเปลี่ยนล้มเหลว!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotLootingSuccess" xml:space="preserve">
|
||||
<value>ส่งข้อเสนอแลกเปลี่ยนสำเร็จ!</value>
|
||||
</data>
|
||||
<data name="BotSendingTradeToYourself" xml:space="preserve">
|
||||
<value>ไม่สามารถส่งข้อเสนอแลกเปลี่ยนให้ตัวเองได้!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotNotConnected" xml:space="preserve">
|
||||
<value>อินสแตนซ์ของบอตตัวนี้ไม่ได้รับการเชื่อมต่อ!</value>
|
||||
</data>
|
||||
@@ -382,7 +366,6 @@ StackTrace:
|
||||
<value>แต้มคงเหลือ: {0}</value>
|
||||
<comment>{0} will be replaced by the points balance value (integer)</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotReconnecting" xml:space="preserve">
|
||||
<value>กำลังเชื่อมต่อใหม่...</value>
|
||||
</data>
|
||||
@@ -434,34 +417,20 @@ StackTrace:
|
||||
<data name="BotConnectionLost" xml:space="preserve">
|
||||
<value>สูญเสียการเชื่อมต่อกับ Steam Network กำลังเชื่อมต่อใหม่...</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotConnecting" xml:space="preserve">
|
||||
<value>กำลังเชื่อมต่อ...</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStopping" xml:space="preserve">
|
||||
<value>กำลังหยุด...</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="Initializing" xml:space="preserve">
|
||||
<value>กำลังเริ่ม {0}...</value>
|
||||
<comment>{0} will be replaced by service name that is being initialized</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="BotVersion" xml:space="preserve">
|
||||
<value>{0} V{1}</value>
|
||||
<comment>{0} will be replaced by program's name (e.g. "ASF"), {1} will be replaced by program's version (e.g. "1.0.0.0"). This string typically has nothing to translate and you should leave it as it is, unless you need to change the format, e.g. in RTL languages.</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="BotOwnedAlready" xml:space="preserve">
|
||||
<value>เป็นเจ้าของแล้ว: {0}</value>
|
||||
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
|
||||
@@ -469,19 +438,14 @@ StackTrace:
|
||||
<data name="ErrorAccessDenied" xml:space="preserve">
|
||||
<value>ปฏิเสธการเข้าถึง!</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>การใช้หน่วยความจําปัจจุบัน: {0} MB.
|
||||
เวลาทํางานของกระบวนการ: {1}</value>
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used, {1} will be replaced by translated TimeSpan string (such as "25 minutes"). Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotRefreshingPackagesData" xml:space="preserve">
|
||||
<value>กำลังรีเฟรชข้อมูลแพ็กเกจ…</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="TargetBotNotConnected" xml:space="preserve">
|
||||
<value>อินสแตนซ์ของบอตเป้าหมายไม่ได้รับการเชื่อมต่อ!</value>
|
||||
</data>
|
||||
@@ -496,13 +460,9 @@ StackTrace:
|
||||
<value>บอตมีเลเวล {0}</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="ErrorAborted" xml:space="preserve">
|
||||
<value>ยกเลิกแล้ว!</value>
|
||||
</data>
|
||||
|
||||
<data name="PluginLoaded" xml:space="preserve">
|
||||
<value>{0} ถูกโหลดสำเร็จแล้ว!</value>
|
||||
<comment>{0} will be replaced by the name of the custom ASF plugin</comment>
|
||||
@@ -514,7 +474,6 @@ StackTrace:
|
||||
<data name="NothingFound" xml:space="preserve">
|
||||
<value>ไม่พบอะไรเลย!</value>
|
||||
</data>
|
||||
|
||||
<data name="PleaseWait" xml:space="preserve">
|
||||
<value>กรุณารอ...</value>
|
||||
</data>
|
||||
@@ -524,45 +483,24 @@ StackTrace:
|
||||
<data name="Executing" xml:space="preserve">
|
||||
<value>กำลังดำเนินการ...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="BotHandledConfirmations" xml:space="preserve">
|
||||
<value>จัดการการยืนยันเป็นผลสำเร็จ {0} รายการ!</value>
|
||||
<comment>{0} will be replaced by number of confirmations</comment>
|
||||
</data>
|
||||
|
||||
<data name="UpdateCleanup" xml:space="preserve">
|
||||
<value>กำลังลบไฟล์เก่าหลังการอัปเดต...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="Result" xml:space="preserve">
|
||||
<value>ผลลัพธ์: {0}</value>
|
||||
<comment>{0} will be replaced by generic result of various functions that use this string</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="BotIdlingSelectedGames" xml:space="preserve">
|
||||
<value>กำลังเล่นเกมที่เลือกไว้ {0}: {1}</value>
|
||||
<comment>{0} will be replaced by internal name of the config property (e.g. "GamesPlayedWhileIdle"), {1} will be replaced by comma-separated list of appIDs that user has chosen</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="FetchingChecksumFromRemoteServer" xml:space="preserve">
|
||||
<value>กำลังดึงข้อมูล checksum จากเซิร์ฟเวอร์ระยะไกล...</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PatchingFiles" xml:space="preserve">
|
||||
<value>กำลังแพตช์ไฟล์ ASF…</value>
|
||||
</data>
|
||||
@@ -570,24 +508,4 @@ StackTrace:
|
||||
<value>โปรดกรอกคีย์รหัสลับของคุณ: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -584,7 +584,10 @@
|
||||
<value>Рівень бота {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotInventory" xml:space="preserve">
|
||||
<value>{0}/{1} ({2}/{3}): {4} активів</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="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>Підбір предметів Steam, раунд #{0}...</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -797,4 +800,7 @@
|
||||
<value>Input: {0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>Ви оголосили --system-required, хоча у вашої ОС немає необхідних залежностей, щоб ця функція працювала. Розгляньте встановлення dbus, хоча також можна безпечно ігнорувати це попередження, якщо вам не потрібно гальмувати для належної роботи.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -800,4 +800,7 @@
|
||||
<value>输入:{0}</value>
|
||||
<comment>{0} will be replaced by text input from the user.</comment>
|
||||
</data>
|
||||
<data name="WarningNoSystemRequiredLinuxDependencies" xml:space="preserve">
|
||||
<value>您已声明--system-require, 尽管您的操作系统缺少该功能所需的依赖关系。 考虑安装 dbus ,不过如果你不需要抑制才能正常工作,你也可以安全地忽略这个警告。</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -87,7 +87,6 @@
|
||||
{2}</value>
|
||||
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
|
||||
<data name="ErrorFailingRequest" xml:space="preserve">
|
||||
<value>請求失敗:{0}</value>
|
||||
<comment>{0} will be replaced by URL of the request</comment>
|
||||
@@ -186,7 +185,6 @@
|
||||
<value>本地版本:{0} | 遠端版本:{1}</value>
|
||||
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
|
||||
</data>
|
||||
|
||||
<data name="UserInputSteam2FA" xml:space="preserve">
|
||||
<value>請輸入您的 Steam 身份驗證器應用程式上顯示的雙重驗證代碼: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
@@ -578,7 +576,6 @@
|
||||
<value>當前機械人的等級為 {0}。</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
<data name="ActivelyMatchingItems" xml:space="preserve">
|
||||
<value>正在匹配 Steam 物品,第 #{0} 輪……</value>
|
||||
<comment>{0} will be replaced by round number</comment>
|
||||
@@ -666,7 +663,6 @@
|
||||
<data name="ErrorConfigDirectoryNotFound" xml:space="preserve">
|
||||
<value>找不到配寘目錄,正在中止!</value>
|
||||
</data>
|
||||
|
||||
<data name="AutomaticFileMigration" xml:space="preserve">
|
||||
<value>{0} config file will be migrated to the latest syntax...</value>
|
||||
<comment>{0} will be replaced with the relative path to the affected config file</comment>
|
||||
@@ -675,7 +671,6 @@
|
||||
<value>您的加密金鑰太短。 我們建議使用長度至少為{0} 個位元組(字元) 的檔案。</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
</data>
|
||||
|
||||
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
|
||||
<value>您正在使用{1} 内容的{0} 設定,但您沒有提供自定義金鑰。 這完全破壞了保護,因為ASF被迫使用自己的(已知的)金鑰。 您應該提供一個自定義密碼金鑰,以利用此設定提供的安全優勢。</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
@@ -695,7 +690,6 @@
|
||||
<data name="ChecksumMissing" xml:space="preserve">
|
||||
<value>遠程服務器對我們要更新的版本一無所知。如果該版本是最近發佈的,則可能出現這種情況-作為額外的安全措施,拒絕立即繼續更新過程。</value>
|
||||
</data>
|
||||
|
||||
<data name="ChecksumWrong" xml:space="preserve">
|
||||
<value>遠程服務器已回復不同的校驗和,這可能表明下載已損壞或MITM攻擊,拒絕繼續更新過程!</value>
|
||||
</data>
|
||||
@@ -710,23 +704,4 @@
|
||||
<value>未禁止IP地址{0}!</value>
|
||||
<comment>{0} will be replaced by an IP address which was requested to be unbanned from using IPC</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -40,5 +40,5 @@ public interface IASF : IPlugin {
|
||||
/// ASF will call this method right after global config initialization.
|
||||
/// </summary>
|
||||
/// <param name="additionalConfigProperties">Extra config properties made out of <see cref="JsonExtensionDataAttribute" />. Can be null if no extra properties are found.</param>
|
||||
Task OnASFInit(IReadOnlyDictionary<string, JsonElement>? additionalConfigProperties = null);
|
||||
public Task OnASFInit(IReadOnlyDictionary<string, JsonElement>? additionalConfigProperties = null);
|
||||
}
|
||||
|
||||
@@ -40,12 +40,12 @@ public interface IBot : IPlugin {
|
||||
/// Doing so will allow the garbage collector to dispose the bot afterwards, refraining from doing so will create a "memory leak" by keeping the reference alive.
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
Task OnBotDestroy(Bot bot);
|
||||
public Task OnBotDestroy(Bot bot);
|
||||
|
||||
/// <summary>
|
||||
/// ASF will call this method after creating the bot object, e.g. after config creation.
|
||||
/// Bot config is not yet available at this stage. This function will execute only once for every bot object.
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
Task OnBotInit(Bot bot);
|
||||
public Task OnBotInit(Bot bot);
|
||||
}
|
||||
|
||||
@@ -39,17 +39,17 @@ public interface IBotCardsFarmerInfo : IPlugin {
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="farmedSomething">Bool value indicating whether the module has finished successfully, so when there was at least one card to drop, and nothing has interrupted us in the meantime.</param>
|
||||
Task OnBotFarmingFinished(Bot bot, bool farmedSomething);
|
||||
public Task OnBotFarmingFinished(Bot bot, bool farmedSomething);
|
||||
|
||||
/// <summary>
|
||||
/// ASF will call this method when cards farming module is started on given bot instance. The module is started only when there are valid cards to drop, so this method won't be called when there is nothing to idle.
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
Task OnBotFarmingStarted(Bot bot);
|
||||
public Task OnBotFarmingStarted(Bot bot);
|
||||
|
||||
/// <summary>
|
||||
/// ASF will call this method when cards farming module is stopped on given bot instance. The stop could be a result of a natural finish, or other situations (e.g. Steam networking issues, user commands).
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
Task OnBotFarmingStopped(Bot bot);
|
||||
public Task OnBotFarmingStopped(Bot bot);
|
||||
}
|
||||
|
||||
@@ -44,5 +44,5 @@ public interface IBotCommand2 : IPlugin {
|
||||
/// <param name="args">Pre-parsed message using standard ASF delimiters.</param>
|
||||
/// <param name="steamID">Optionally, steamID of the user who executed the command - may not be available with value of 0 (e.g. ASF API).</param>
|
||||
/// <returns>Response to the command, or null/empty (as the task value) if the command isn't handled by this plugin.</returns>
|
||||
Task<string?> OnBotCommand(Bot bot, EAccess access, string message, string[] args, ulong steamID = 0);
|
||||
public Task<string?> OnBotCommand(Bot bot, EAccess access, string message, string[] args, ulong steamID = 0);
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ public interface IBotConnection : IPlugin {
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="reason">Reason for disconnection, or <see cref="EResult.OK" /> if the disconnection was initiated by ASF (e.g. as a result of a command).</param>
|
||||
Task OnBotDisconnected(Bot bot, EResult reason);
|
||||
public Task OnBotDisconnected(Bot bot, EResult reason);
|
||||
|
||||
/// <summary>
|
||||
/// ASF will call this method when bot successfully connects to Steam network.
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
Task OnBotLoggedOn(Bot bot);
|
||||
public Task OnBotLoggedOn(Bot bot);
|
||||
}
|
||||
|
||||
@@ -41,5 +41,5 @@ public interface IBotCustomMachineInfoProvider : IPlugin {
|
||||
/// <remarks>This method will be called with very limited amount of bot-related data, as it's used during bot initialization. We recommend to stick with <see cref="Bot.BotName" />, <see cref="Bot.BotConfig" /> and <see cref="Bot.BotDatabase" /> exclusively.</remarks>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <returns><see cref="IMachineInfoProvider" /> that will be used for the particular bot. You can return null if you want to use default implementation.</returns>
|
||||
Task<IMachineInfoProvider?> GetMachineInfoProvider(Bot bot);
|
||||
public Task<IMachineInfoProvider?> GetMachineInfoProvider(Bot bot);
|
||||
}
|
||||
|
||||
@@ -39,5 +39,5 @@ public interface IBotFriendRequest : IPlugin {
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="steamID">64-bit Steam identificator of the user that sent a friend request, or a group that the bot has been invited to.</param>
|
||||
/// <returns>True if the request should be accepted as part of this plugin, false otherwise.</returns>
|
||||
Task<bool> OnBotFriendRequest(Bot bot, ulong steamID);
|
||||
public Task<bool> OnBotFriendRequest(Bot bot, ulong steamID);
|
||||
}
|
||||
|
||||
@@ -41,5 +41,5 @@ public interface IBotIdentity : IPlugin {
|
||||
/// <param name="data">Full data received by ASF in the callback that relates to this bot (Steam) account.</param>
|
||||
/// <param name="nickname">Parsed nickname set for this bot (Steam) account.</param>
|
||||
/// <param name="avatarHash">Parsed hash of the avatar of this bot (Steam) account, as hex.</param>
|
||||
Task OnSelfPersonaState(Bot bot, SteamFriends.PersonaStateCallback data, string? nickname, string? avatarHash);
|
||||
public Task OnSelfPersonaState(Bot bot, SteamFriends.PersonaStateCallback data, string? nickname, string? avatarHash);
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@ public interface IBotMessage : IPlugin {
|
||||
/// <param name="steamID">64-bit long unsigned integer of steamID executing the command.</param>
|
||||
/// <param name="message">Message in its raw format.</param>
|
||||
/// <returns>Response to the message, or null/empty (as the task value) for silence.</returns>
|
||||
Task<string?> OnBotMessage(Bot bot, ulong steamID, string message);
|
||||
public Task<string?> OnBotMessage(Bot bot, ulong steamID, string message);
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@ public interface IBotModules : IPlugin {
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="additionalConfigProperties">Extra config properties made out of <see cref="JsonExtensionDataAttribute" />. Can be null if no extra properties are found.</param>
|
||||
Task OnBotInitModules(Bot bot, IReadOnlyDictionary<string, JsonElement>? additionalConfigProperties = null);
|
||||
public Task OnBotInitModules(Bot bot, IReadOnlyDictionary<string, JsonElement>? additionalConfigProperties = null);
|
||||
}
|
||||
|
||||
@@ -40,12 +40,12 @@ public interface IBotSteamClient : IPlugin {
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="callbackManager">Callback manager object which can be used for establishing subscriptions to standard and custom callbacks.</param>
|
||||
Task OnBotSteamCallbacksInit(Bot bot, CallbackManager callbackManager);
|
||||
public Task OnBotSteamCallbacksInit(Bot bot, CallbackManager callbackManager);
|
||||
|
||||
/// <summary>
|
||||
/// ASF will call this method right after bot initialization in order to allow you hooking custom SK2 client handlers into the SteamClient.
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <returns>Collection of custom client handlers that are supposed to be hooked into the SteamClient by ASF. If you do not require any, just return null or empty collection.</returns>
|
||||
Task<IReadOnlyCollection<ClientMsgHandler>?> OnBotSteamHandlersInit(Bot bot);
|
||||
public Task<IReadOnlyCollection<ClientMsgHandler>?> OnBotSteamHandlersInit(Bot bot);
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@ public interface IBotTradeOffer2 : IPlugin {
|
||||
/// <param name="tradeOffer">Trade offer related to this callback.</param>
|
||||
/// <param name="asfResult">ASF result in regards to parsing this trade offer, can be useful for determining why it wasn't accepted as part of the core logic.</param>
|
||||
/// <returns>True if the trade offer should be accepted as part of this plugin, false otherwise.</returns>
|
||||
Task<bool> OnBotTradeOffer(Bot bot, TradeOffer tradeOffer, ParseTradeResult.EResult asfResult);
|
||||
public Task<bool> OnBotTradeOffer(Bot bot, TradeOffer tradeOffer, ParseTradeResult.EResult asfResult);
|
||||
}
|
||||
|
||||
@@ -40,5 +40,5 @@ public interface IBotTradeOfferResults : IPlugin {
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="tradeResults">Trade results related to this callback.</param>
|
||||
Task OnBotTradeOfferResults(Bot bot, IReadOnlyCollection<ParseTradeResult> tradeResults);
|
||||
public Task OnBotTradeOfferResults(Bot bot, IReadOnlyCollection<ParseTradeResult> tradeResults);
|
||||
}
|
||||
|
||||
@@ -40,5 +40,5 @@ public interface IBotUserNotifications : IPlugin {
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="newNotifications">Collection containing those notification types that are new (that is, when new count > previous count of that notification type).</param>
|
||||
Task OnBotUserNotifications(Bot bot, IReadOnlyCollection<UserNotificationsCallback.EUserNotification> newNotifications);
|
||||
public Task OnBotUserNotifications(Bot bot, IReadOnlyCollection<UserNotificationsCallback.EUserNotification> newNotifications);
|
||||
}
|
||||
|
||||
@@ -37,5 +37,5 @@ public interface IBotsComparer : IPlugin {
|
||||
/// Unless you know what you're doing, you should not implement this property yourself and let ASF decide.
|
||||
/// </summary>
|
||||
/// <returns>Comparer that will be used for the bots, as well as bot regexes.</returns>
|
||||
StringComparer BotsComparer => StringComparer.Ordinal;
|
||||
public StringComparer BotsComparer => StringComparer.Ordinal;
|
||||
}
|
||||
|
||||
@@ -39,5 +39,5 @@ public interface ICrossProcessSemaphoreProvider : IPlugin {
|
||||
/// </summary>
|
||||
/// <param name="resourceName">Unique resource name provided by ASF for identification purposes.</param>
|
||||
/// <returns>Concrete implementation of <see cref="ICrossProcessSemaphore" /> providing required functionality. It's allowed to return null if you want to use ASF's default implementation for specified resource instead.</returns>
|
||||
Task<ICrossProcessSemaphore?> GetCrossProcessSemaphore(string resourceName);
|
||||
public Task<ICrossProcessSemaphore?> GetCrossProcessSemaphore(string resourceName);
|
||||
}
|
||||
|
||||
@@ -48,14 +48,14 @@ public interface IGitHubPluginUpdates : IPluginUpdates {
|
||||
/// Boolean value that determines whether your plugin is able to update at the time of calling. You may provide false if, for example, you're inside a critical section and you don't want to update at this time, despite supporting updates otherwise.
|
||||
/// This effectively skips unnecessary request to GitHub if you're certain that you're not interested in any updates right now.
|
||||
/// </summary>
|
||||
bool CanUpdate => true;
|
||||
public bool CanUpdate => true;
|
||||
|
||||
/// <summary>
|
||||
/// ASF will use this property as a target for GitHub updates. GitHub repository specified here must have valid releases that will be used for updates.
|
||||
/// </summary>
|
||||
/// <returns>Repository name in format of {Author}/{Repository}.</returns>
|
||||
/// <example>JustArchiNET/ArchiSteamFarm</example>
|
||||
string RepositoryName { get; }
|
||||
public string RepositoryName { get; }
|
||||
|
||||
Task<Uri?> IPluginUpdates.GetTargetReleaseURL(Version asfVersion, string asfVariant, bool asfUpdate, GlobalConfig.EUpdateChannel updateChannel, bool forced) {
|
||||
ArgumentNullException.ThrowIfNull(asfVersion);
|
||||
@@ -104,7 +104,7 @@ public interface IGitHubPluginUpdates : IPluginUpdates {
|
||||
/// - *.zip, if exactly one match is found
|
||||
/// </remarks>
|
||||
/// <returns>Target release asset from those provided that should be used for auto-update. You may return null if the update is unavailable, for example, because ASF version/variant is determined unsupported, or due to any other reason.</returns>
|
||||
Task<ReleaseAsset?> GetTargetReleaseAsset(Version asfVersion, string asfVariant, Version newPluginVersion, IReadOnlyCollection<ReleaseAsset> releaseAssets) {
|
||||
public Task<ReleaseAsset?> GetTargetReleaseAsset(Version asfVersion, string asfVariant, Version newPluginVersion, IReadOnlyCollection<ReleaseAsset> releaseAssets) {
|
||||
ArgumentNullException.ThrowIfNull(asfVersion);
|
||||
ArgumentException.ThrowIfNullOrEmpty(asfVariant);
|
||||
ArgumentNullException.ThrowIfNull(newPluginVersion);
|
||||
|
||||
@@ -38,7 +38,7 @@ public interface IPlugin {
|
||||
/// </summary>
|
||||
/// <returns>String that will be used as the name of this plugin.</returns>
|
||||
[JsonInclude]
|
||||
string Name { get; }
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ASF will use this property as version indicator of your plugin to the user.
|
||||
@@ -46,10 +46,10 @@ public interface IPlugin {
|
||||
/// </summary>
|
||||
/// <returns>Version that will be shown to the user when plugin is loaded.</returns>
|
||||
[JsonInclude]
|
||||
Version Version { get; }
|
||||
public Version Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ASF will call this method right after plugin initialization.
|
||||
/// </summary>
|
||||
Task OnLoaded();
|
||||
public Task OnLoaded();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user