mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-24 10:16:49 +00:00
Compare commits
255 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f807bdb660 | ||
|
|
5b66b70566 | ||
|
|
41c06851a5 | ||
|
|
4dbb964ba9 | ||
|
|
11471c759d | ||
|
|
2aa4ab7fe8 | ||
|
|
dfc055c066 | ||
|
|
1a0ac11f46 | ||
|
|
7266864b3b | ||
|
|
b52f746138 | ||
|
|
a2585ec8c9 | ||
|
|
37781698e0 | ||
|
|
2a8fe7611b | ||
|
|
8fdf14bb10 | ||
|
|
31db72b2d6 | ||
|
|
f28ae15cc9 | ||
|
|
6fcc64dad1 | ||
|
|
e18046084e | ||
|
|
c3c5f33289 | ||
|
|
e03734ef8f | ||
|
|
a7c2ca6bc5 | ||
|
|
171fca42f2 | ||
|
|
e90ac74b16 | ||
|
|
a5ce8bf3d7 | ||
|
|
aad77569a7 | ||
|
|
e74b3e4f78 | ||
|
|
7db44c5835 | ||
|
|
25a88f941d | ||
|
|
2eab00facc | ||
|
|
98e51a4543 | ||
|
|
2ee49db81d | ||
|
|
aab397dd2d | ||
|
|
7426fafcb0 | ||
|
|
270bd7ae26 | ||
|
|
4c3713c19f | ||
|
|
5791b1e552 | ||
|
|
5c59236a09 | ||
|
|
a7119bba89 | ||
|
|
3b64e14489 | ||
|
|
5f36ca91d7 | ||
|
|
5a2cd25fa1 | ||
|
|
20a5d509a7 | ||
|
|
0c457e7f3e | ||
|
|
4e6014d652 | ||
|
|
1436fb6d6a | ||
|
|
e2578c7960 | ||
|
|
8fb1a2e1ea | ||
|
|
3e2951d1d0 | ||
|
|
1dcb103bf7 | ||
|
|
7ca8efb81f | ||
|
|
c08f259806 | ||
|
|
e0a8f96ec4 | ||
|
|
dae6f9d328 | ||
|
|
4258fed873 | ||
|
|
ab6e0a1e1b | ||
|
|
959056523a | ||
|
|
245e3aa250 | ||
|
|
170bd9fe42 | ||
|
|
2cf84d3691 | ||
|
|
ae0ec5feee | ||
|
|
c495ad4f4a | ||
|
|
01e4085a52 | ||
|
|
e89dad5792 | ||
|
|
8c6c7a5f3c | ||
|
|
32f52e9de3 | ||
|
|
aaabd81778 | ||
|
|
24200e3490 | ||
|
|
a896075e88 | ||
|
|
1bf35d1215 | ||
|
|
641aa435be | ||
|
|
d3e48e69d4 | ||
|
|
8548044038 | ||
|
|
cdffde2d76 | ||
|
|
afd7360676 | ||
|
|
7603efb289 | ||
|
|
3ad6f68bb9 | ||
|
|
065facb5db | ||
|
|
8140784903 | ||
|
|
c468f3e4e1 | ||
|
|
174317c674 | ||
|
|
25690056da | ||
|
|
1950c1326e | ||
|
|
876074a0ed | ||
|
|
8c06051f52 | ||
|
|
b7d9c7b6da | ||
|
|
ca048912cd | ||
|
|
290aa3ba34 | ||
|
|
8620a90787 | ||
|
|
189f998faf | ||
|
|
a5640f5a84 | ||
|
|
b343d81f56 | ||
|
|
edf2a19946 | ||
|
|
7e43a05517 | ||
|
|
db8ead92a1 | ||
|
|
e33c340183 | ||
|
|
a04781747e | ||
|
|
73bae63af6 | ||
|
|
bf4bb7225c | ||
|
|
1809028c77 | ||
|
|
c4b3899ae3 | ||
|
|
7c00e725d1 | ||
|
|
73dcb34c0c | ||
|
|
65049bc2e5 | ||
|
|
b3ed87c9ef | ||
|
|
2ea5f5a83b | ||
|
|
ba1f832f54 | ||
|
|
39e7a73cd2 | ||
|
|
d803887ef9 | ||
|
|
560d2400c0 | ||
|
|
6a0cc973f3 | ||
|
|
b21742d06e | ||
|
|
b76454ecfa | ||
|
|
376899ebe2 | ||
|
|
547bb13894 | ||
|
|
c7792c8a1c | ||
|
|
b67f92cc21 | ||
|
|
7ad05e1703 | ||
|
|
1ba2880071 | ||
|
|
fd05a2cab6 | ||
|
|
cd22d365ea | ||
|
|
6196fc175e | ||
|
|
cd5835bdcb | ||
|
|
07a7358493 | ||
|
|
475b8aa649 | ||
|
|
141c8835d0 | ||
|
|
6b498af3c9 | ||
|
|
640a794a3e | ||
|
|
82cea76901 | ||
|
|
ffccb98d79 | ||
|
|
31bf21973b | ||
|
|
7dbb8e23b0 | ||
|
|
43d1ccfb0e | ||
|
|
e2ff80cc46 | ||
|
|
457bacfef8 | ||
|
|
44f9f12263 | ||
|
|
80c2091e34 | ||
|
|
9e522e7196 | ||
|
|
335760c0bb | ||
|
|
e856ce8177 | ||
|
|
16f02740d8 | ||
|
|
7f5ada6dce | ||
|
|
65018efa7f | ||
|
|
3b87713fff | ||
|
|
d141dce93d | ||
|
|
81a92d6781 | ||
|
|
f3d491611a | ||
|
|
332d5d048c | ||
|
|
11f8b6aae5 | ||
|
|
6e5a02c380 | ||
|
|
22bbfe4e24 | ||
|
|
a2c278947d | ||
|
|
5db90e0eb8 | ||
|
|
1914f41ffe | ||
|
|
4754b3cbd9 | ||
|
|
31acd4e7dc | ||
|
|
f98d33bfa5 | ||
|
|
799b48d1b6 | ||
|
|
6444167ae4 | ||
|
|
543d03724d | ||
|
|
cdd4ff9128 | ||
|
|
004c72127c | ||
|
|
c08b2609fc | ||
|
|
eedb39e8df | ||
|
|
379b9454ec | ||
|
|
02d0610a04 | ||
|
|
f63723a157 | ||
|
|
d59bccf1db | ||
|
|
2a734344bc | ||
|
|
eb8946e480 | ||
|
|
55745c8093 | ||
|
|
5a5a573e46 | ||
|
|
dc6968b371 | ||
|
|
692a0e0c9d | ||
|
|
c5839d3cbe | ||
|
|
bc3275fa9d | ||
|
|
4c70a71072 | ||
|
|
fd2b9ff8d2 | ||
|
|
407b77428a | ||
|
|
494dd69819 | ||
|
|
71f4e16603 | ||
|
|
1c0995426c | ||
|
|
82702647b4 | ||
|
|
b826a64f88 | ||
|
|
d20c3257ed | ||
|
|
06622263c0 | ||
|
|
73b3fe4c8a | ||
|
|
429b030021 | ||
|
|
d60b932dfa | ||
|
|
5229f52f47 | ||
|
|
92a946c1cb | ||
|
|
03fc35dad0 | ||
|
|
225003c5d1 | ||
|
|
4f598d5c8f | ||
|
|
944df1cfc8 | ||
|
|
e259f9e32f | ||
|
|
c2cabfba49 | ||
|
|
dee8add183 | ||
|
|
06829beda4 | ||
|
|
2a35c82e0c | ||
|
|
dbd8fa9877 | ||
|
|
d8a0d2f22d | ||
|
|
88996d1e35 | ||
|
|
78a88979dc | ||
|
|
2513bd4163 | ||
|
|
d9a5c30659 | ||
|
|
c60ea2ba3d | ||
|
|
7a07b6a22b | ||
|
|
d89b6112dd | ||
|
|
5d33bca611 | ||
|
|
0f489f55e4 | ||
|
|
bf70f27449 | ||
|
|
0eab358af9 | ||
|
|
3eae143c55 | ||
|
|
a33d46c85b | ||
|
|
4aa524f03e | ||
|
|
861e7ded16 | ||
|
|
581d5167b9 | ||
|
|
b9108742d4 | ||
|
|
86c19a2dce | ||
|
|
f64abc02ab | ||
|
|
d6e569c970 | ||
|
|
a75d63cd7f | ||
|
|
8bfc48d8dc | ||
|
|
3de4069e3f | ||
|
|
874eb2d1c6 | ||
|
|
803d4554aa | ||
|
|
549ddb4271 | ||
|
|
9017c3970d | ||
|
|
1eecd8ace0 | ||
|
|
31da584f75 | ||
|
|
1b1cdb8c3e | ||
|
|
37e7f9f51c | ||
|
|
fc9dda13a0 | ||
|
|
94c214af96 | ||
|
|
a184fc555b | ||
|
|
ad2dae4faf | ||
|
|
aaf9cc67b3 | ||
|
|
fe866554d6 | ||
|
|
97200da414 | ||
|
|
876c332452 | ||
|
|
75bc0ed598 | ||
|
|
bcbc44cb1f | ||
|
|
db8b23031a | ||
|
|
586ad7c370 | ||
|
|
86867c8d99 | ||
|
|
6a824c2c6f | ||
|
|
ac02495e80 | ||
|
|
67c5e1f7c4 | ||
|
|
85437774de | ||
|
|
8cb813a354 | ||
|
|
d64669d563 | ||
|
|
a049bf39d6 | ||
|
|
c191a85966 | ||
|
|
a5cd6314e4 | ||
|
|
90bf83cf48 |
@@ -6,6 +6,7 @@ root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
#file_header_template = · _ _ _ ____ _ _____\n / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___\n / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \\n / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |\n/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|\n\nCopyright 2015-2021 Łukasz "JustArchi" Domeradzki\nContact: JustArchi@JustArchi.net\n\nLicensed under the Apache License, Version 2.0 (the "License")\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
71
.github/ISSUE_TEMPLATE/Bug-report.yml
vendored
71
.github/ISSUE_TEMPLATE/Bug-report.yml
vendored
@@ -8,7 +8,7 @@ body:
|
||||
label: Checklist
|
||||
description: Ensure that our bug report form is appropriate for you.
|
||||
options:
|
||||
- label: I read and understood ASF's **[Contributing Guidelines](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md)**
|
||||
- label: I read and understood ASF's **[Contributing guidelines](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md)**
|
||||
required: true
|
||||
- label: I also read **[Setting-up](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Setting-up)** and **[FAQ](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/FAQ)**, I don't need **[help](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/SUPPORT.md)**, this is a bug report
|
||||
required: true
|
||||
@@ -46,6 +46,7 @@ body:
|
||||
- linux-arm
|
||||
- linux-arm64
|
||||
- linux-x64
|
||||
- osx-arm64
|
||||
- osx-x64
|
||||
- win-x64
|
||||
validations:
|
||||
@@ -56,7 +57,7 @@ body:
|
||||
label: Bug description
|
||||
description: Short explanation of what you were going to do, what did you want to accomplish?
|
||||
placeholder: |
|
||||
I tried to brew a coffee with ASF using `PUT /Api/Coffee` ASF API, but upon trying the program returned HTTP error: 418 I'm a teapot
|
||||
I tried to brew a coffee with ASF using `PUT /Api/Coffee` ASF API endpoint, but upon trying the program returned HTTP error: 418 I'm a teapot.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -74,27 +75,36 @@ body:
|
||||
label: Actual behavior
|
||||
description: What happened instead?
|
||||
placeholder: |
|
||||
No coffee was brewed, and so I was forced to use a water dispenser instead :/
|
||||
No coffee was brewed, and so I was forced to use a water dispenser instead :/.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Every command or action that happened after launching ASF, which leads to the bug.
|
||||
placeholder: |
|
||||
description: |
|
||||
Every command or action that happened after launching ASF, which leads to the bug.
|
||||
If launching ASF with provided configs (below) is everything that is needed, then this section is not mandatory.
|
||||
placeholder: |
|
||||
1. Put cup below the machine hosting ASF.
|
||||
2. Send `PUT /Api/Coffee` request selecting latte macchiato.
|
||||
3. No coffee was brewed.
|
||||
- type: textarea
|
||||
id: possible-solution
|
||||
attributes:
|
||||
label: Possible reason/solution
|
||||
description: Not mandatory, but you can suggest a fix/reason for the bug, if known to you.
|
||||
placeholder: If you observed something peculiar about your issue that could help us locate and fix the culprit, this is the right place.
|
||||
description: |
|
||||
Not mandatory, but you can suggest a fix/reason for the bug, if known to you.
|
||||
If you observed something peculiar about your issue that could help us locate and fix the culprit, this is the right place.
|
||||
placeholder: |
|
||||
Perhaps no coffee was brewed because I was out of milk?
|
||||
- type: dropdown
|
||||
id: help
|
||||
attributes:
|
||||
label: Can you help us with this bug report?
|
||||
description: ASF is offered for free and our resources are limited. Helping us increases the chance of fixing the problem.
|
||||
description: |
|
||||
ASF is offered for free and our resources are limited.
|
||||
Helping us increases the chance of fixing the problem.
|
||||
options:
|
||||
- Yes, I can code the solution myself and send a pull request
|
||||
- Somehow, I can test and offer feedback, but can't code
|
||||
@@ -105,9 +115,24 @@ body:
|
||||
id: asf-log
|
||||
attributes:
|
||||
label: Full log.txt recorded during reproducing the problem
|
||||
description: You can find `log.txt` file directly in ASF directory. If the bug report doesn't come from the last run of the program, you can find logs from previous runs of the program in the `logs` directory instead.
|
||||
description: |
|
||||
You can find `log.txt` file directly in ASF directory.
|
||||
If the bug report doesn't come from the last run of the program, you can find logs from previous runs of the program in the `logs` directory instead.
|
||||
If no `log.txt` was recorded due to crash at the very early stage, console output should be pasted instead.
|
||||
placeholder: |
|
||||
If no log.txt was recorded due to crash at the very early stage, console output should be pasted instead.
|
||||
2021-12-16 00:20:43|dotnet-282887|INFO|ASF|InitCore() ArchiSteamFarm V5.2.1.2 (generic/6b492ffa-9927-431d-bae7-7360ab9968a9 | .NET 6.0.0-rtm.21522.10; debian-arm64; Linux 5.15.0-1-arm64 #1 SMP Debian 5.15.3-1 (2021-11-18))
|
||||
2021-12-16 00:20:43|dotnet-282887|INFO|ASF|InitCore() Copyright © 2015-2021 JustArchiNET
|
||||
2021-12-16 00:20:47|dotnet-282887|INFO|ASF|InitPlugins() Initializing Plugins...
|
||||
2021-12-16 00:20:47|dotnet-282887|INFO|ASF|InitPlugins() Loading SteamTokenDumperPlugin V5.2.1.2...
|
||||
2021-12-16 00:20:47|dotnet-282887|INFO|ASF|InitPlugins() SteamTokenDumperPlugin has been loaded successfully!
|
||||
2021-12-16 00:20:47|dotnet-282887|INFO|ASF|UpdateAndRestart() ASF will automatically check for new versions every 1 day.
|
||||
2021-12-16 00:20:52|dotnet-282887|INFO|ASF|Update() Checking for new version...
|
||||
2021-12-16 00:20:54|dotnet-282887|INFO|ASF|Update() Local version: 5.2.1.2 | Remote version: 5.2.1.2
|
||||
2021-12-16 00:20:54|dotnet-282887|INFO|ASF|Load() Loading STD global cache...
|
||||
2021-12-16 00:20:56|dotnet-282887|INFO|ASF|Load() Validating STD global cache integrity...
|
||||
2021-12-16 00:20:56|dotnet-282887|INFO|ASF|OnASFInit() SteamTokenDumperPlugin has been initialized successfully, thank you in advance for your help. The first submission will happen in approximately 47 minutes from now.
|
||||
2021-12-16 00:20:57|dotnet-282887|INFO|ASF|Start() Starting IPC server...
|
||||
2021-12-16 00:20:59|dotnet-282887|INFO|ASF|Start() IPC server ready!
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
@@ -115,9 +140,9 @@ body:
|
||||
id: global-config
|
||||
attributes:
|
||||
label: Global ASF.json config file
|
||||
description: The config can be found in `config` directory under `ASF.json` name. You can leave this field empty if not using one.
|
||||
placeholder: |
|
||||
Paste the file content here, no need for triple backtick tags
|
||||
description: |
|
||||
The config can be found in `config` directory under `ASF.json` name.
|
||||
You can leave this field empty if not using one.
|
||||
|
||||
Ensure that your config has redacted (but NOT removed) potentially-sensitive properties, such as:
|
||||
- IPCPassword (recommended)
|
||||
@@ -127,14 +152,22 @@ body:
|
||||
- WebProxyUsername (optionally, if exposing private details)
|
||||
|
||||
Redacting involves replacing sensitive details, for example with stars (***). You should refrain from removing config lines entirely, as their pure existence may be relevant and should be preserved.
|
||||
placeholder: |
|
||||
{
|
||||
"AutoRestart": false,
|
||||
"Headless": true,
|
||||
"IPCPassword": "********",
|
||||
"UpdateChannel": 2,
|
||||
"SteamTokenDumperPluginEnabled": true
|
||||
}
|
||||
render: json
|
||||
- type: textarea
|
||||
id: bot-config
|
||||
attributes:
|
||||
label: BotName.json config of all affected bot instances
|
||||
description: Bot config files can be found in `config` directory, ending with `json` extension. You can leave this field empty if you don't have any defined.
|
||||
placeholder: |
|
||||
Paste the file content here, no need for triple backtick tags
|
||||
description: |
|
||||
Bot config files can be found in `config` directory, ending with `json` extension.
|
||||
You can leave this field empty if you don't have any defined.
|
||||
|
||||
Ensure that your config has redacted (but NOT removed) potentially-sensitive properties, such as:
|
||||
- SteamLogin (mandatory)
|
||||
@@ -145,6 +178,12 @@ body:
|
||||
- SteamUserPermissions (optionally, only SteamIDs)
|
||||
|
||||
Redacting involves replacing sensitive details, for example with stars (***). You should refrain from removing config lines entirely, as their pure existence may be relevant and should be preserved.
|
||||
placeholder: |
|
||||
{
|
||||
"Enabled": true,
|
||||
"SteamLogin": "********",
|
||||
"SteamPassword": "********"
|
||||
}
|
||||
render: json
|
||||
- type: textarea
|
||||
id: additional-info
|
||||
|
||||
25
.github/ISSUE_TEMPLATE/Enhancement-idea.yml
vendored
25
.github/ISSUE_TEMPLATE/Enhancement-idea.yml
vendored
@@ -8,7 +8,7 @@ body:
|
||||
label: Checklist
|
||||
description: Ensure that our enhancement idea form is appropriate for you.
|
||||
options:
|
||||
- label: I read and understood ASF's **[Contributing Guidelines](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md)**
|
||||
- label: I read and understood ASF's **[Contributing guidelines](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md)**
|
||||
required: true
|
||||
- label: I also read **[Setting-up](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Setting-up)** and **[FAQ](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/FAQ)**, I don't need **[help](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/SUPPORT.md)**, this is an enhancement idea
|
||||
required: true
|
||||
@@ -26,8 +26,12 @@ body:
|
||||
id: enhancement-purpose
|
||||
attributes:
|
||||
label: Enhancement purpose
|
||||
description: Purpose of the enhancement - if it solves some problem, precise in particular which. If it benefits the program in some other way, precise in particular why.
|
||||
placeholder: Present the underlying reason why this enhancement makes sense, and what is the context of it.
|
||||
description: |
|
||||
Purpose of the enhancement - if it solves some problem, precise in particular which. If it benefits the program in some other way, precise in particular why.
|
||||
Present the underlying reason why this enhancement makes sense, and what is the context of it.
|
||||
placeholder: |
|
||||
As of today ASF offers variety of beverages, such as latte macchiato or cappuccino. I'd appreciate if ASF offered some no-milk options as well, for example espresso or ristretto.
|
||||
I believe it'd further improve the program offering the users wider selection, which is very convenient.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -35,25 +39,30 @@ body:
|
||||
attributes:
|
||||
label: Solution
|
||||
description: What would you like to see as a solution to the purpose specified by you above?
|
||||
placeholder: What would work for you?
|
||||
placeholder: |
|
||||
Simply add an option to brew some no-milk types of coffee. The existing logic is fine, we just need wider choice!
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: why-existing-not-sufficient
|
||||
attributes:
|
||||
label: Why currently available solutions are not sufficient?
|
||||
description: Evaluate the existing solutions in regards to your requirements.
|
||||
placeholder: |
|
||||
description: |
|
||||
Evaluate the existing solutions in regards to your requirements.
|
||||
If something you're suggesting is already possible, then explain to us why the currently available solutions are not sufficient.
|
||||
|
||||
If it's not possible yet, then explain to us why it should be.
|
||||
placeholder: |
|
||||
I'm allergic to milk, there is currently no option to pick a beverage that doesn't include it.
|
||||
Temporarily I'm switching cup mid-brewing as a workaround, but that is suboptimal considering the milk wasted.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: help
|
||||
attributes:
|
||||
label: Can you help us with this enhancement idea?
|
||||
description: ASF is offered for free and our resources are limited. Helping us increases the chance of making it happen.
|
||||
description: |
|
||||
ASF is offered for free and our resources are limited.
|
||||
Helping us increases the chance of making it happen.
|
||||
options:
|
||||
- Yes, I can code the solution myself and send a pull request
|
||||
- Somehow, I can test and offer feedback, but can't code
|
||||
|
||||
24
.github/ISSUE_TEMPLATE/Wiki-suggestion.yml
vendored
24
.github/ISSUE_TEMPLATE/Wiki-suggestion.yml
vendored
@@ -8,7 +8,7 @@ body:
|
||||
label: Checklist
|
||||
description: Ensure that our wiki suggestion form is appropriate for you.
|
||||
options:
|
||||
- label: I read and understood ASF's **[Contributing Guidelines](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md)**
|
||||
- label: I read and understood ASF's **[Contributing guidelines](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md)**
|
||||
required: true
|
||||
- label: I also read **[Setting-up](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Setting-up)** and **[FAQ](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/FAQ)**, I don't need **[help](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/SUPPORT.md)**, this is a wiki suggestion
|
||||
required: true
|
||||
@@ -20,7 +20,9 @@ body:
|
||||
id: wiki-page
|
||||
attributes:
|
||||
label: Wiki page
|
||||
description: If this is a suggestion regarding an existing wiki page, please link it for reference. If the wiki page doesn't exist, suggest its title.
|
||||
description: |
|
||||
If this is a suggestion regarding an existing wiki page, please link it for reference.
|
||||
If the wiki page doesn't exist, suggest its title.
|
||||
placeholder: https://github.com/JustArchiNET/ArchiSteamFarm/wiki/???
|
||||
validations:
|
||||
required: true
|
||||
@@ -28,26 +30,32 @@ body:
|
||||
id: issue
|
||||
attributes:
|
||||
label: The issue
|
||||
description: Please specify your issue in regards to our wiki documentation.
|
||||
placeholder: |
|
||||
description: |
|
||||
Please specify your issue in regards to our wiki documentation.
|
||||
If you're reporting a mistake/correction, state what is wrong.
|
||||
|
||||
If you're suggesting an idea, explain the details.
|
||||
placeholder: |
|
||||
As of today the wiki doesn't explain how to sing famous song composed by Rick Astley - Never Gonna Give You Up.
|
||||
I'm sick of googling the lyrics every time I'm opening a complaint on your GitHub, so please consider just adding it along the other stuff.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: wrong-text
|
||||
attributes:
|
||||
label: Wrong text
|
||||
description: The existing text on the wiki which you classify as wrong.
|
||||
placeholder: |
|
||||
description: |
|
||||
The existing text on the wiki which you classify as wrong.
|
||||
If you're suggesting a new page, paragraph or other addition to the wiki, then this section is not mandatory.
|
||||
placeholder: |
|
||||
Lack of song lyrics is what's wrong!
|
||||
render: markdown
|
||||
- type: textarea
|
||||
id: suggested-improvement
|
||||
attributes:
|
||||
label: Suggested improvement
|
||||
description: The new or corrected text that would satisfy your issue stated above. You may use **[markdown](https://guides.github.com/features/mastering-markdown)** for formatting.
|
||||
description: |
|
||||
The new or corrected text that would satisfy your issue stated above.
|
||||
You may use **[markdown](https://guides.github.com/features/mastering-markdown)** for formatting.
|
||||
placeholder: |
|
||||
# Never Gonna Give You Up by Rick Astley
|
||||
|
||||
|
||||
2
.github/RELEASE_TEMPLATE.md
vendored
2
.github/RELEASE_TEMPLATE.md
vendored
@@ -12,6 +12,6 @@ This is automated GitHub deployment, human-readable changelog should be availabl
|
||||
|
||||
### Support
|
||||
|
||||
ASF is available for free, this release was made possible thanks to the people that decided to support the project. If you're grateful for what we're doing, please consider donating. Developing ASF requires massive amount of time and knowledge, especially when it comes to Steam (and its problems). Even $1 is highly appreciated and shows that you care. Thank you!
|
||||
ASF is available for free, this release was made possible thanks to the people that decided to support the project. If you're grateful for what we're doing, please consider a donation. Developing ASF requires massive amount of time and knowledge, especially when it comes to Steam (and its problems). Even $1 is highly appreciated and shows that you care. Thank you!
|
||||
|
||||
[](https://github.com/sponsors/JustArchi) [](https://www.patreon.com/JustArchi) [](https://commerce.coinbase.com/checkout/0c23b844-c51b-45f4-9135-8db7c6fcf98e) [](https://paypal.me/JustArchi) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HD2P2P3WGS5Y4) [](https://pay.revolut.com/profile/ukaszyxm) [](https://steamcommunity.com/tradeoffer/new/?partner=46697991&token=0ix2Ruv_)
|
||||
|
||||
7
.github/renovate.json5
vendored
7
.github/renovate.json5
vendored
@@ -17,13 +17,8 @@
|
||||
{
|
||||
// TODO: <= 3.1 for Mono support, last failed version 6.12, https://steamcommunity.com/groups/archiasf/discussions/1/2997673517556002529
|
||||
"allowedVersions": "<= 3.1",
|
||||
"matchManagers": [ "nuget" ],
|
||||
"matchPackageNames": [ "Microsoft.Extensions.Configuration.Json", "Microsoft.Extensions.Logging.Configuration" ]
|
||||
},
|
||||
{
|
||||
// TODO: <= 2.2.4 due to https://github.com/microsoft/testfx/issues/906, should be resolved with v2.2.8+ (?)
|
||||
"allowedVersions": "<= 2.2.4",
|
||||
"groupName": "MSTest packages",
|
||||
"matchPackagePatterns": ["^MSTest\\..+"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
- name: Upload latest strings for translation on Crowdin
|
||||
continue-on-error: true
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.configuration == 'Release' && startsWith(matrix.os, 'ubuntu-') }}
|
||||
uses: crowdin/github-action@1.4.1
|
||||
uses: crowdin/github-action@1.4.6
|
||||
with:
|
||||
crowdin_branch_name: main
|
||||
config: '.github/crowdin.yml'
|
||||
|
||||
2
.github/workflows/docker-ci.yml
vendored
2
.github/workflows/docker-ci.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Build ${{ matrix.configuration }} Docker image from ${{ matrix.file }}
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.file }}
|
||||
|
||||
8
.github/workflows/docker-publish-latest.yml
vendored
8
.github/workflows/docker-publish-latest.yml
vendored
@@ -23,14 +23,14 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@v1.10.0
|
||||
uses: docker/login-action@v1.12.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1.10.0
|
||||
uses: docker/login-action@v1.12.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and publish Docker image from Dockerfile.Service
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.Service
|
||||
|
||||
8
.github/workflows/docker-publish-main.yml
vendored
8
.github/workflows/docker-publish-main.yml
vendored
@@ -24,14 +24,14 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@v1.10.0
|
||||
uses: docker/login-action@v1.12.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1.10.0
|
||||
uses: docker/login-action@v1.12.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and publish Docker image from Dockerfile
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ env.PLATFORMS }}
|
||||
|
||||
@@ -24,14 +24,14 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@v1.10.0
|
||||
uses: docker/login-action@v1.12.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1.10.0
|
||||
uses: docker/login-action@v1.12.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and publish Docker image from Dockerfile
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ env.PLATFORMS }}
|
||||
|
||||
4
.github/workflows/lock-threads.yml
vendored
4
.github/workflows/lock-threads.yml
vendored
@@ -11,5 +11,5 @@ jobs:
|
||||
- name: Lock inactive threads
|
||||
uses: dessant/lock-threads@v3.0.0
|
||||
with:
|
||||
issue-inactive-days: 30
|
||||
pr-inactive-days: 30
|
||||
issue-inactive-days: 60
|
||||
pr-inactive-days: 60
|
||||
|
||||
47
.github/workflows/publish.yml
vendored
47
.github/workflows/publish.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
run: dotnet --info
|
||||
|
||||
- name: Setup Node.js with npm
|
||||
uses: actions/setup-node@v2.4.1
|
||||
uses: actions/setup-node@v2.5.1
|
||||
with:
|
||||
check-latest: true
|
||||
node-version: ${{ env.NODE_JS_VERSION }}
|
||||
@@ -325,13 +325,22 @@ jobs:
|
||||
|
||||
foreach ($variant in $env:VARIANTS.Split([char[]] $null, [System.StringSplitOptions]::RemoveEmptyEntries)) {
|
||||
Start-Job -Name "$variant" $PublishBlock -ArgumentList "$variant"
|
||||
|
||||
# Limit active jobs in parallel to help with memory usage
|
||||
$jobs = $(Get-Job -State Running)
|
||||
|
||||
while (@($jobs).Count -ge 5) {
|
||||
Wait-Job -Job $jobs -Any | Out-Null
|
||||
|
||||
$jobs = $(Get-Job -State Running)
|
||||
}
|
||||
}
|
||||
|
||||
Get-Job | Receive-Job -Wait
|
||||
|
||||
- name: Upload ASF-generic
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-generic
|
||||
path: out/ASF-generic.zip
|
||||
@@ -339,49 +348,49 @@ jobs:
|
||||
- name: Upload ASF-generic-netf
|
||||
continue-on-error: true
|
||||
if: startsWith(matrix.os, 'windows-')
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-generic-netf
|
||||
path: out/ASF-generic-netf.zip
|
||||
|
||||
- name: Upload ASF-linux-arm
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-linux-arm
|
||||
path: out/ASF-linux-arm.zip
|
||||
|
||||
- name: Upload ASF-linux-arm64
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-linux-arm64
|
||||
path: out/ASF-linux-arm64.zip
|
||||
|
||||
- name: Upload ASF-linux-x64
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-linux-x64
|
||||
path: out/ASF-linux-x64.zip
|
||||
|
||||
- name: Upload ASF-osx-arm64
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-osx-arm64
|
||||
path: out/ASF-osx-arm64.zip
|
||||
|
||||
- name: Upload ASF-osx-x64
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-osx-x64
|
||||
path: out/ASF-osx-x64.zip
|
||||
|
||||
- name: Upload ASF-win-x64
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-win-x64
|
||||
path: out/ASF-win-x64.zip
|
||||
@@ -399,49 +408,49 @@ jobs:
|
||||
# However, that is currently impossible due to https://github.com/dotnet/msbuild/issues/3897
|
||||
# Therefore, we'll (sadly) pull artifacts from Windows machine only for now
|
||||
- name: Download ASF-generic artifact from windows-latest
|
||||
uses: actions/download-artifact@v2.0.10
|
||||
uses: actions/download-artifact@v2.1.0
|
||||
with:
|
||||
name: windows-latest_ASF-generic
|
||||
path: out
|
||||
|
||||
- name: Download ASF-generic-netf artifact from windows-latest
|
||||
uses: actions/download-artifact@v2.0.10
|
||||
uses: actions/download-artifact@v2.1.0
|
||||
with:
|
||||
name: windows-latest_ASF-generic-netf
|
||||
path: out
|
||||
|
||||
- name: Download ASF-linux-arm artifact from windows-latest
|
||||
uses: actions/download-artifact@v2.0.10
|
||||
uses: actions/download-artifact@v2.1.0
|
||||
with:
|
||||
name: windows-latest_ASF-linux-arm
|
||||
path: out
|
||||
|
||||
- name: Download ASF-linux-arm64 artifact from windows-latest
|
||||
uses: actions/download-artifact@v2.0.10
|
||||
uses: actions/download-artifact@v2.1.0
|
||||
with:
|
||||
name: windows-latest_ASF-linux-arm64
|
||||
path: out
|
||||
|
||||
- name: Download ASF-linux-x64 artifact from windows-latest
|
||||
uses: actions/download-artifact@v2.0.10
|
||||
uses: actions/download-artifact@v2.1.0
|
||||
with:
|
||||
name: windows-latest_ASF-linux-x64
|
||||
path: out
|
||||
|
||||
- name: Download ASF-osx-arm64 artifact from windows-latest
|
||||
uses: actions/download-artifact@v2.0.10
|
||||
uses: actions/download-artifact@v2.1.0
|
||||
with:
|
||||
name: windows-latest_ASF-osx-arm64
|
||||
path: out
|
||||
|
||||
- name: Download ASF-osx-x64 artifact from windows-latest
|
||||
uses: actions/download-artifact@v2.0.10
|
||||
uses: actions/download-artifact@v2.1.0
|
||||
with:
|
||||
name: windows-latest_ASF-osx-x64
|
||||
path: out
|
||||
|
||||
- name: Download ASF-win-x64 artifact from windows-latest
|
||||
uses: actions/download-artifact@v2.0.10
|
||||
uses: actions/download-artifact@v2.1.0
|
||||
with:
|
||||
name: windows-latest_ASF-win-x64
|
||||
path: out
|
||||
@@ -465,14 +474,14 @@ jobs:
|
||||
|
||||
- name: Upload SHA512SUMS
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: SHA512SUMS
|
||||
path: out/SHA512SUMS
|
||||
|
||||
- name: Upload SHA512SUMS.sign
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
with:
|
||||
name: SHA512SUMS.sign
|
||||
path: out/SHA512SUMS.sign
|
||||
|
||||
2
.github/workflows/translations.yml
vendored
2
.github/workflows/translations.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
git reset --hard origin/master
|
||||
|
||||
- name: Download latest translations from Crowdin
|
||||
uses: crowdin/github-action@1.4.1
|
||||
uses: crowdin/github-action@1.4.6
|
||||
with:
|
||||
upload_sources: false
|
||||
download_translations: true
|
||||
|
||||
2
ASF-ui
2
ASF-ui
Submodule ASF-ui updated: 88f7324e09...533e6082fb
@@ -5,6 +5,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="all" />
|
||||
<PackageReference Include="JetBrains.Annotations" PrivateAssets="all" />
|
||||
<PackageReference Include="Newtonsoft.Json" IncludeAssets="compile" />
|
||||
<PackageReference Include="SteamKit2" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -35,9 +35,7 @@ internal static class CatAPI {
|
||||
private const string URL = "https://aws.random.cat";
|
||||
|
||||
internal static async Task<string?> GetRandomCatURL(WebBrowser webBrowser) {
|
||||
if (webBrowser == null) {
|
||||
throw new ArgumentNullException(nameof(webBrowser));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(webBrowser);
|
||||
|
||||
Uri request = new($"{URL}/meow");
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -28,7 +28,6 @@ using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Plugins.Interfaces;
|
||||
using ArchiSteamFarm.Steam;
|
||||
using ArchiSteamFarm.Steam.Data;
|
||||
using ArchiSteamFarm.Steam.Storage;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SteamKit2;
|
||||
@@ -41,7 +40,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin;
|
||||
// Your plugin class should inherit the plugin interfaces it wants to handle
|
||||
// If you do not want to handle a particular action (e.g. OnBotMessage that is offered in IBotMessage), it's the best idea to not inherit it at all
|
||||
// This will keep your code compact, efficient and less dependent. You can always add additional interfaces when you'll need them, this example project will inherit quite a bit of them to show you potential usage
|
||||
internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, IBotFriendRequest, IBotMessage, IBotModules, IBotTradeOffer {
|
||||
internal sealed class ExamplePlugin : IASF, IBot, IBotCommand2, IBotConnection, IBotFriendRequest, IBotMessage, IBotModules, IBotTradeOffer {
|
||||
// This is used for identification purposes, typically you want to use a friendly name of your plugin here, such as the name of your main class
|
||||
// Please note that this property can have direct dependencies only on structures that were initialized by the constructor, as it's possible to be called before OnLoaded() takes place
|
||||
public string Name => nameof(ExamplePlugin);
|
||||
@@ -58,9 +57,9 @@ internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, I
|
||||
// Thanks to that, you can extend default ASF config with your own stuff, then parse it here in order to customize your plugin during runtime
|
||||
// Keep in mind that, as noted in the interface, additionalConfigProperties can be null if no custom, unrecognized properties are found by ASF, you should handle that case appropriately
|
||||
// In addition to that, this method also guarantees that all plugins were already OnLoaded(), which allows cross-plugins-communication to be possible
|
||||
public void OnASFInit(IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
public Task OnASFInit(IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
if (additionalConfigProperties == null) {
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
foreach ((string configProperty, JToken configValue) in additionalConfigProperties) {
|
||||
@@ -73,6 +72,10 @@ internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, I
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ASF interface methods usually expect a Task as a return value, this allows you to optionally implement async operations in your functions (with async Task function signature)
|
||||
// If your method does not implement any async operations (is fully synchronous), you could in theory still mark it as async, but a better idea is to just return Task.CompletedTask from it, like here
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
// This method is called when unknown command is received (starting with CommandPrefix)
|
||||
@@ -82,11 +85,11 @@ internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, I
|
||||
// Since ASF already had to do initial parsing in order to determine that the command is unknown, args[] are splitted using standard ASF delimiters
|
||||
// If by any chance you want to handle message in its raw format, you also have it available, although for usual ASF pattern you can most likely stick with args[] exclusively. The message has CommandPrefix already stripped for your convenience
|
||||
// If you do not recognize the command, just return null/empty and allow ASF to gracefully return "unknown command" to user on usual basis
|
||||
public async Task<string?> OnBotCommand(Bot bot, ulong steamID, string message, string[] args) {
|
||||
public async Task<string?> OnBotCommand(Bot bot, EAccess access, string message, string[] args, ulong steamID = 0) {
|
||||
// In comparison with OnBotMessage(), we're using asynchronous CatAPI call here, so we declare our method as async and return the message as usual
|
||||
// Notice how we handle access here as well, it'll work only for FamilySharing+
|
||||
switch (args[0].ToUpperInvariant()) {
|
||||
case "CAT" when bot.HasAccess(steamID, BotConfig.EAccess.FamilySharing):
|
||||
case "CAT" when access >= EAccess.FamilySharing:
|
||||
// Notice how we can decide whether to use bot's AWH WebBrowser or ASF's one. For Steam-related requests, AWH's one should always be used, for third-party requests like those it doesn't really matter
|
||||
// Still, it makes sense to pass AWH's one, so in case you get some errors or alike, you know from which bot instance they come from. It's similar to using Bot's ArchiLogger compared to ASF's one
|
||||
string? randomCatURL = await CatAPI.GetRandomCatURL(bot.ArchiWebHandler.WebBrowser).ConfigureAwait(false);
|
||||
@@ -101,12 +104,12 @@ internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, I
|
||||
// You should ensure that all of your references to this bot instance are cleared - most of the time this is anything you created in OnBotInit(), including deep roots in your custom modules
|
||||
// This doesn't have to be done immediately (e.g. no need to cancel existing work), but it should be done in timely manner when everything is finished
|
||||
// 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
|
||||
public void OnBotDestroy(Bot bot) { }
|
||||
public Task OnBotDestroy(Bot bot) => Task.CompletedTask;
|
||||
|
||||
// This method is called when bot is disconnected from Steam network, you may want to use this info in some kind of way, or not
|
||||
// ASF tries its best to provide logical reason why the disconnection has happened, and will use EResult.OK if the disconnection was initiated by us (e.g. as part of a command)
|
||||
// Still, you should take anything other than EResult.OK with a grain of salt, unless you want to assume that Steam knows why it disconnected us (hehe, you bet)
|
||||
public void OnBotDisconnected(Bot bot, EResult reason) { }
|
||||
public Task OnBotDisconnected(Bot bot, EResult reason) => Task.CompletedTask;
|
||||
|
||||
// This method is called when bot receives a friend request or group invite that ASF isn't willing to accept
|
||||
// It allows you to generate a response whether ASF should accept it (true) or proceed like usual (false)
|
||||
@@ -117,10 +120,12 @@ internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, I
|
||||
// This method is called at the end of Bot's constructor
|
||||
// You can initialize all your per-bot structures here
|
||||
// In general you should do that only when you have a particular need of custom modules or alike, since ASF's plugin system will always provide bot to you as a function argument
|
||||
public void OnBotInit(Bot bot) {
|
||||
public Task OnBotInit(Bot bot) {
|
||||
// Apart of those two that are already provided by ASF, you can also initialize your own logger with your plugin's name, if needed
|
||||
bot.ArchiLogger.LogGenericInfo($"Our bot named {bot.BotName} has been initialized, and we're letting you know about it from our {nameof(ExamplePlugin)}!");
|
||||
ASF.ArchiLogger.LogGenericWarning("In case we won't have a bot reference or have something process-wide to log, we can also use ASF's logger!");
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
// This method, apart from being called during bot modules initialization, allows you to read custom bot config properties that are not recognized by ASF
|
||||
@@ -128,8 +133,7 @@ internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, I
|
||||
// Keep in mind that, as noted in the interface, additionalConfigProperties can be null if no custom, unrecognized properties are found by ASF, you should handle that case appropriately
|
||||
// Also keep in mind that this function can be called multiple times, e.g. when user edits his bot configs during runtime
|
||||
// Take a look at OnASFInit() for example parsing code
|
||||
public async void OnBotInitModules(Bot bot, IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
// ASF marked this message as synchronous, in case we have async code to execute, we can just use async void return
|
||||
public async Task OnBotInitModules(Bot bot, IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
// For example, we'll ensure that every bot starts paused regardless of Paused property, in order to do this, we'll just call Pause here in InitModules()
|
||||
// Thanks to the fact that this method is called with each bot config reload, we'll ensure that our bot stays paused even if it'd get unpaused otherwise
|
||||
bot.ArchiLogger.LogGenericInfo("Pausing this bot as asked from the plugin");
|
||||
@@ -137,7 +141,7 @@ internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, I
|
||||
}
|
||||
|
||||
// This method is called when the bot is successfully connected to Steam network and it's a good place to schedule any on-connected tasks, as AWH is also expected to be available shortly
|
||||
public void OnBotLoggedOn(Bot bot) { }
|
||||
public Task OnBotLoggedOn(Bot bot) => Task.CompletedTask;
|
||||
|
||||
// This method is called when bot receives a message that is NOT a command (in other words, a message that doesn't start with CommandPrefix)
|
||||
// Normally ASF entirely ignores such messages as the program should not respond to something that isn't recognized
|
||||
@@ -174,8 +178,10 @@ internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, I
|
||||
// If you do not have any global structures to initialize, you can leave this function empty
|
||||
// At this point you can access core ASF's functionality, such as logging, but more advanced structures (like ASF's WebBrowser) will be available in OnASFInit(), which itself takes place after every plugin gets OnLoaded()
|
||||
// Typically you should use this function only for preparing core structures of your plugin, and optionally also sending a message to the user (e.g. support link, welcome message or similar), ASF-specific things should usually happen in OnASFInit()
|
||||
public void OnLoaded() {
|
||||
public Task OnLoaded() {
|
||||
ASF.ArchiLogger.LogGenericInfo($"Hey! Thanks for checking if our example plugin works fine, this is a confirmation that indeed {nameof(OnLoaded)}() method was called!");
|
||||
ASF.ArchiLogger.LogGenericInfo("Good luck in whatever you're doing!");
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="all" />
|
||||
<PackageReference Include="JetBrains.Annotations" PrivateAssets="all" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -24,6 +24,7 @@ using System.Composition;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Plugins.Interfaces;
|
||||
|
||||
@@ -41,7 +42,7 @@ internal sealed class PeriodicGCPlugin : IPlugin {
|
||||
|
||||
public Version Version => typeof(PeriodicGCPlugin).Assembly.GetName().Version ?? throw new InvalidOperationException(nameof(Version));
|
||||
|
||||
public void OnLoaded() {
|
||||
public Task OnLoaded() {
|
||||
TimeSpan timeSpan = TimeSpan.FromSeconds(GCPeriod);
|
||||
|
||||
ASF.ArchiLogger.LogGenericWarning($"Periodic GC will occur every {timeSpan.ToHumanReadable()}. Please keep in mind that this plugin should be used for debugging tests only.");
|
||||
@@ -49,6 +50,8 @@ internal sealed class PeriodicGCPlugin : IPlugin {
|
||||
lock (LockObject) {
|
||||
PeriodicGCTimer.Change(timeSpan, timeSpan);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static void PerformGC(object? state = null) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -28,7 +28,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Helpers;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.Localization;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using SteamKit2;
|
||||
@@ -96,20 +96,18 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
|
||||
internal static async Task<GlobalCache?> Load() {
|
||||
if (!File.Exists(SharedFilePath)) {
|
||||
GlobalCache result = new();
|
||||
|
||||
Utilities.InBackground(result.Save);
|
||||
|
||||
return result;
|
||||
return new GlobalCache();
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.LoadingGlobalCache);
|
||||
|
||||
GlobalCache? globalCache;
|
||||
|
||||
try {
|
||||
string json = await File.ReadAllTextAsync(SharedFilePath).ConfigureAwait(false);
|
||||
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(json)));
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, ArchiSteamFarm.Localization.Strings.ErrorIsEmpty, nameof(json)));
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -127,6 +125,14 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
return null;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.ValidatingGlobalCacheIntegrity);
|
||||
|
||||
if (globalCache.DepotKeys.Values.Any(static depotKey => !IsValidDepotKey(depotKey))) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.GlobalCacheIntegrityValidationFailed);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return globalCache;
|
||||
}
|
||||
|
||||
@@ -135,9 +141,7 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
throw new ArgumentOutOfRangeException(nameof(currentChangeNumber));
|
||||
}
|
||||
|
||||
if (appChanges == null) {
|
||||
throw new ArgumentNullException(nameof(appChanges));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(appChanges);
|
||||
|
||||
if (currentChangeNumber <= LastChangeNumber) {
|
||||
return;
|
||||
@@ -175,9 +179,7 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
internal bool ShouldRefreshDepotKey(uint depotID) => !DepotKeys.ContainsKey(depotID);
|
||||
|
||||
internal void UpdateAppChangeNumbers(IReadOnlyCollection<KeyValuePair<uint, uint>> appChangeNumbers) {
|
||||
if (appChangeNumbers == null) {
|
||||
throw new ArgumentNullException(nameof(appChangeNumbers));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(appChangeNumbers);
|
||||
|
||||
bool save = false;
|
||||
|
||||
@@ -196,13 +198,8 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
}
|
||||
|
||||
internal void UpdateAppTokens(IReadOnlyCollection<KeyValuePair<uint, ulong>> appTokens, IReadOnlyCollection<uint> publicAppIDs) {
|
||||
if (appTokens == null) {
|
||||
throw new ArgumentNullException(nameof(appTokens));
|
||||
}
|
||||
|
||||
if (publicAppIDs == null) {
|
||||
throw new ArgumentNullException(nameof(publicAppIDs));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(appTokens);
|
||||
ArgumentNullException.ThrowIfNull(publicAppIDs);
|
||||
|
||||
bool save = false;
|
||||
|
||||
@@ -230,9 +227,7 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
}
|
||||
|
||||
internal void UpdateDepotKeys(ICollection<SteamApps.DepotKeyCallback> depotKeyResults) {
|
||||
if (depotKeyResults == null) {
|
||||
throw new ArgumentNullException(nameof(depotKeyResults));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(depotKeyResults);
|
||||
|
||||
bool save = false;
|
||||
|
||||
@@ -243,6 +238,12 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
|
||||
string depotKey = Convert.ToHexString(depotKeyResult.DepotKey);
|
||||
|
||||
if (!IsValidDepotKey(depotKey)) {
|
||||
ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, ArchiSteamFarm.Localization.Strings.ErrorIsInvalid, nameof(depotKey)));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DepotKeys.TryGetValue(depotKeyResult.DepotID, out string? previousDepotKey) && (previousDepotKey == depotKey)) {
|
||||
continue;
|
||||
}
|
||||
@@ -257,9 +258,7 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
}
|
||||
|
||||
internal void UpdatePackageTokens(IReadOnlyCollection<KeyValuePair<uint, ulong>> packageTokens) {
|
||||
if (packageTokens == null) {
|
||||
throw new ArgumentNullException(nameof(packageTokens));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(packageTokens);
|
||||
|
||||
bool save = false;
|
||||
|
||||
@@ -278,17 +277,9 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
}
|
||||
|
||||
internal void UpdateSubmittedData(IReadOnlyDictionary<uint, ulong> apps, IReadOnlyDictionary<uint, ulong> packages, IReadOnlyDictionary<uint, string> depots) {
|
||||
if (apps == null) {
|
||||
throw new ArgumentNullException(nameof(apps));
|
||||
}
|
||||
|
||||
if (packages == null) {
|
||||
throw new ArgumentNullException(nameof(packages));
|
||||
}
|
||||
|
||||
if (depots == null) {
|
||||
throw new ArgumentNullException(nameof(depots));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(apps);
|
||||
ArgumentNullException.ThrowIfNull(packages);
|
||||
ArgumentNullException.ThrowIfNull(depots);
|
||||
|
||||
foreach ((uint appID, ulong token) in apps) {
|
||||
SubmittedApps[appID] = token;
|
||||
@@ -304,4 +295,12 @@ internal sealed class GlobalCache : SerializableFile {
|
||||
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
|
||||
private static bool IsValidDepotKey(string depotKey) {
|
||||
if (string.IsNullOrEmpty(depotKey)) {
|
||||
throw new ArgumentNullException(nameof(depotKey));
|
||||
}
|
||||
|
||||
return (depotKey.Length == 64) && Utilities.IsValidHexadecimalText(depotKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
@@ -12,46 +11,32 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.Localization {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Strings {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
private static System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
private static System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Strings() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.Localization.Strings", typeof(Strings).Assembly);
|
||||
if (object.Equals(null, resourceMan)) {
|
||||
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.Localization.Strings", typeof(Strings).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
@@ -60,246 +45,183 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.Localization {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving {0} app access tokens..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving {0} app infos..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingAppInfos {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingAppInfos", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving {0} depot keys..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingDepotKeys {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingDepotKeys", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving a total of {0} app access tokens..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingTotalAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingTotalAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving all depot keys for a total of {0} apps..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingTotalDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingTotalDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to There are no apps that require a refresh on this bot instance..
|
||||
/// </summary>
|
||||
internal static string BotNoAppsToRefresh {
|
||||
get {
|
||||
return ResourceManager.GetString("BotNoAppsToRefresh", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving {0} app access tokens....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving {0} app infos....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingAppInfos {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingAppInfos", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving {0} depot keys....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingDepotKeys {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingDepotKeys", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving a total of {0} app access tokens....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingTotalAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingTotalAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving all depots for a total of {0} apps....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingTotalDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingTotalDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} could not be loaded, a fresh instance will be initialized....
|
||||
/// </summary>
|
||||
internal static string FileCouldNotBeLoadedFreshInit {
|
||||
get {
|
||||
return ResourceManager.GetString("FileCouldNotBeLoadedFreshInit", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} is currently disabled according to your configuration. If you'd like to help SteamDB in data submission, please check out our wiki..
|
||||
/// </summary>
|
||||
internal static string PluginDisabledInConfig {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginDisabledInConfig", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} has been disabled due to a missing build token.
|
||||
/// </summary>
|
||||
internal static string PluginDisabledMissingBuildToken {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginDisabledMissingBuildToken", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} has been initialized successfully, thank you in advance for your help. The first submission will happen in approximately {1} from now..
|
||||
/// </summary>
|
||||
internal static string PluginDisabledInConfig {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginDisabledInConfig", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string PluginInitializedAndEnabled {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginInitializedAndEnabled", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} initialized, the plugin will not resolve any of those: {1}..
|
||||
/// </summary>
|
||||
internal static string PluginSecretListInitialized {
|
||||
internal static string FileCouldNotBeLoadedFreshInit {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginSecretListInitialized", resourceCulture);
|
||||
return ResourceManager.GetString("FileCouldNotBeLoadedFreshInit", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The submission has failed due to too many requests sent, we'll try again in approximately {0} from now..
|
||||
/// </summary>
|
||||
internal static string SubmissionFailedTooManyRequests {
|
||||
internal static string BotNoAppsToRefresh {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionFailedTooManyRequests", resourceCulture);
|
||||
return ResourceManager.GetString("BotNoAppsToRefresh", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Submitting a total of registered apps/packages/depots: {0}/{1}/{2}....
|
||||
/// </summary>
|
||||
internal static string SubmissionInProgress {
|
||||
internal static string BotRetrievingTotalAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionInProgress", resourceCulture);
|
||||
return ResourceManager.GetString("BotRetrievingTotalAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Could not submit the data because there is no valid SteamID set that we could classify as a contributor. Consider setting up {0} property..
|
||||
/// </summary>
|
||||
internal static string SubmissionNoContributorSet {
|
||||
internal static string BotRetrievingAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionNoContributorSet", resourceCulture);
|
||||
return ResourceManager.GetString("BotRetrievingAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string BotFinishedRetrievingAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string BotFinishedRetrievingTotalAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingTotalAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string BotRetrievingTotalDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingTotalDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string BotRetrievingAppInfos {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingAppInfos", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string BotFinishedRetrievingAppInfos {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingAppInfos", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string BotRetrievingDepotKeys {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingDepotKeys", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string BotFinishedRetrievingDepotKeys {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingDepotKeys", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string BotFinishedRetrievingTotalDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingTotalDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to There is no new data to submit, everything is up-to-date..
|
||||
/// </summary>
|
||||
internal static string SubmissionNoNewData {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionNoNewData", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The data has been successfully submitted. The server has registered a total of new apps/packages/depots: {0} ({1} verified)/{2} ({3} verified)/{4} ({5} verified)..
|
||||
/// </summary>
|
||||
internal static string SubmissionNoContributorSet {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionNoContributorSet", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string SubmissionInProgress {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionInProgress", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string SubmissionFailedTooManyRequests {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionFailedTooManyRequests", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string SubmissionSuccessful {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessful", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to New apps: {0}.
|
||||
/// </summary>
|
||||
internal static string SubmissionSuccessfulNewApps {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulNewApps", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to New depots: {0}.
|
||||
/// </summary>
|
||||
internal static string SubmissionSuccessfulNewDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulNewDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to New packages: {0}.
|
||||
/// </summary>
|
||||
internal static string SubmissionSuccessfulNewPackages {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulNewPackages", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Verified apps: {0}.
|
||||
/// </summary>
|
||||
internal static string SubmissionSuccessfulVerifiedApps {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulVerifiedApps", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Verified depots: {0}.
|
||||
/// </summary>
|
||||
internal static string SubmissionSuccessfulNewPackages {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulNewPackages", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string SubmissionSuccessfulVerifiedPackages {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulVerifiedPackages", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string SubmissionSuccessfulNewDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulNewDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string SubmissionSuccessfulVerifiedDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulVerifiedDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Verified packages: {0}.
|
||||
/// </summary>
|
||||
internal static string SubmissionSuccessfulVerifiedPackages {
|
||||
internal static string PluginSecretListInitialized {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessfulVerifiedPackages", resourceCulture);
|
||||
return ResourceManager.GetString("PluginSecretListInitialized", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string LoadingGlobalCache {
|
||||
get {
|
||||
return ResourceManager.GetString("LoadingGlobalCache", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string ValidatingGlobalCacheIntegrity {
|
||||
get {
|
||||
return ResourceManager.GetString("ValidatingGlobalCacheIntegrity", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GlobalCacheIntegrityValidationFailed {
|
||||
get {
|
||||
return ResourceManager.GetString("GlobalCacheIntegrityValidationFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -62,6 +62,50 @@
|
||||
PublicKeyToken=b77a5c561934e089
|
||||
</value>
|
||||
</resheader>
|
||||
<data name="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>{0} byl zakázán z důvodu chybějícího tokenu</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>{0} je v současné době v souladu s vaší konfigurací zakázán. Pokud byste chtěli pomoci SteamDB při odesílání dat, podívejte se na naši wiki.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>{0} byl úspěšně inicializován, předem vám děkujeme za vaši pomoc. První příspěvek se od teď stane přibližně za {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>{0} nelze načíst, nová instance bude inicializována...</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>Neexistují žádné aplikace, které by vyžadovaly aktualizaci této instance bota.</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Načítám celkem {0} přístupových tokenů...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Načítání {0} přístupových tokenů...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Načítání {0} přístupových tokenů bylo dokončeno.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Dokončeno načítání celkem {0} přístupových tokenů.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Získávání {0} informací o aplikaci...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Načítání informací o aplikaci {0} bylo dokončeno.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
@@ -70,23 +114,32 @@
|
||||
|
||||
|
||||
|
||||
<data name="SubmissionSuccessfulNewApps" xml:space="preserve">
|
||||
<value>Nové aplikace: {0}</value>
|
||||
<comment>{0} will be replaced by list of the apps (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulVerifiedApps" xml:space="preserve">
|
||||
<value>Ověřené aplikace: {0}</value>
|
||||
<comment>{0} will be replaced by list of the apps (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulNewPackages" xml:space="preserve">
|
||||
<value>Nové balíčky: {0}</value>
|
||||
<comment>{0} will be replaced by list of the packages (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulVerifiedPackages" xml:space="preserve">
|
||||
<value>Ověřené balíčky: {0}</value>
|
||||
<comment>{0} will be replaced by list of the packages (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Načítání globální mezipaměti STD...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Ověřování globální integrity STD keše...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Ověření globální integrity STD keše se nezdařilo. To naznačuje, že může dojít k poškození souboru/paměti, místo toho bude inicializována nová instance.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} wurde initialisiert, das Plugin wird keinen der folgenden Werte verarbeiten: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Globaler STD-Cache wird geladen...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Überprüfe STD globale Cache-Integrität...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Fehler beim Überprüfen der globalen STD-Cache-Integrität. Dies deutet auf eine mögliche Datei-/Speicher-Beschädigung hin; stattdessen wird eine neue Instanz initialisiert.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} αρχικοποιήθηκε, το plugin δεν θα επιλύσει κανένα από αυτά: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Φόρτωση καθολικής μνήμης cache...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Επικύρωση ακεραιότητας καθολικής λανθάνουσας μνήμης STD...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Αποτυχία επαλήθευσης ακεραιότητας καθολικής λανθάνουσας μνήμης STD. Αυτό υποδηλώνει πιθανή διαφθορά αρχείου/μνήμης, αντ' αυτού θα ξεκινήσει μια νέα διεργασία.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} iniciado, el plugin no analizará ninguno de los siguientes: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Cargando caché global de STD... </value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Validando integridad de la caché global de STD... </value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>No se pudo verificar la integridad de la caché global de STD. Esto puede significar una potencial corrupción de archivo/memoria, se iniciará una nueva instancia. </value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} initialisé, le plugin ne résoudra aucun de ceux-ci : {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Chargement du cache STD global...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Validation de l'intégrité du cache STD global...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Impossible de vérifier l'intégrité du cache STD global. Cela peut être due à une corruption potentielle de fichier/mémoire, une nouvelle instance va être créée.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +91,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -101,13 +101,22 @@
|
||||
<value>Ricezione di tutti i depositi per un totale di {0} app...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Recuperate {0} informazioni app...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Hai completato il recupero di {0} informazioni app.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Recupero {0} chiavi...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Completato il recupero di {0} chiavi.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Finito il recupero di tutte le chiavi del deposito per un totale di {0} applicazioni.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
@@ -143,8 +152,29 @@
|
||||
<value>Nuovi pacchetti: {0}</value>
|
||||
<comment>{0} will be replaced by list of the packages (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="SubmissionSuccessfulVerifiedPackages" xml:space="preserve">
|
||||
<value>Pacchetti verificati: {0}</value>
|
||||
<comment>{0} will be replaced by list of the packages (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulNewDepots" xml:space="preserve">
|
||||
<value>Nuove app: {0}</value>
|
||||
<comment>{0} will be replaced by list of the depots (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulVerifiedDepots" xml:space="preserve">
|
||||
<value>App verificate: {0}</value>
|
||||
<comment>{0} will be replaced by list of the depots (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="PluginSecretListInitialized" xml:space="preserve">
|
||||
<value>{0} inizializzato, il plugin non risolverà nessuno dei seguenti: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Caricamento cache globale STD...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Convalida integrità cache globale STD...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Impossibile verificare l'integrità globale della cache STD. Questo suggerisce un potenziale danneggiamento di file/memoria, una nuova istanza verrà inizializzata.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -124,4 +124,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -62,31 +62,87 @@
|
||||
PublicKeyToken=b77a5c561934e089
|
||||
</value>
|
||||
</resheader>
|
||||
<data name="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>{0} buvo išjungtas, dėl trūkstamos dalies</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>{0} buvo sėkmingai įrašytas, dėkojame už jūsų pagalbą. Pirma pateiktis įvyks už maždaug {1} nuo dabar.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>{0} nepavyko užkrauti, bus įrašyta nauja instancija...</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>Šiame robote nėra jokių programų, kurias reikėtų atnaujinti.</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Iš viso gaunama {0} programos prieigos raktų...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Gaunama {0} programos prieigos raktų...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Baigta gauti {0} programos prieigos raktų.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Iš viso baigta gauti {0} programos prieigos raktų.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Gaunama {0} programos informacijos...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Baigta gauti {0} programos informacijos.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>Nėra jokių naujų duomenų, kuriuos būtų galima pateikti, viskas jau atnaujinta.</value>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="SubmissionFailedTooManyRequests" xml:space="preserve">
|
||||
<value>Pateiktis nepavyko dėl per daug išsiustų prašymų, pradėsime iš naujo už maždaug {0} nuo dabar.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
|
||||
<data name="SubmissionSuccessfulNewApps" xml:space="preserve">
|
||||
<value>Naujos programos: {0}</value>
|
||||
<comment>{0} will be replaced by list of the apps (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulVerifiedApps" xml:space="preserve">
|
||||
<value>Patvirtintos programos: {0}</value>
|
||||
<comment>{0} will be replaced by list of the apps (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulNewPackages" xml:space="preserve">
|
||||
<value>Nauji paketai: {0}</value>
|
||||
<comment>{0} will be replaced by list of the packages (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulVerifiedPackages" xml:space="preserve">
|
||||
<value>Patvirtinti paketai: {0}</value>
|
||||
<comment>{0} will be replaced by list of the packages (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PluginSecretListInitialized" xml:space="preserve">
|
||||
<value>{0} inicijuota, įskiepis neišspręs nė vieno iš šių dalykų: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Kraunama STD global talpykla...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Tvirtinamas STD global talpyklos vientisumas...</value>
|
||||
</data>
|
||||
|
||||
</root>
|
||||
|
||||
@@ -82,7 +82,22 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="SubmissionSuccessfulNewApps" xml:space="preserve">
|
||||
<value>Jaunas aplikācijas: {0}</value>
|
||||
<comment>{0} will be replaced by list of the apps (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulVerifiedApps" xml:space="preserve">
|
||||
<value>Pārbaudītas aplikācijas: {0}</value>
|
||||
<comment>{0} will be replaced by list of the apps (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulNewPackages" xml:space="preserve">
|
||||
<value>Jaunas pakas: {0}</value>
|
||||
<comment>{0} will be replaced by list of the packages (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessfulVerifiedPackages" xml:space="preserve">
|
||||
<value>Pārbaudītas pakas: {0}</value>
|
||||
<comment>{0} will be replaced by list of the packages (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} zainicjowano, wtyczka nie rozwiąże żadnego z tych: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Ładowanie globalnej pamięci podręcznej STD...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Sprawdzanie integralność globalnej pamięci podręcznej STD...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Nie udało się zweryfikować integralności globalnej pamięci podręcznej STD. Sugeruje to potencjalne uszkodzenie pliku/pamięci, zamiast tego zostanie zainicjowana nowa instancja.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} inicializado, o plugin não resolverá nenhum desses: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Carregando cache STD global...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Validando integridade do cache STD global...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Falha ao verificar a integridade do cache STD global. Isso sugere uma potencial corrupção de arquivo/memória, uma instância nova será inicializada em vez disso.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} INITIALIZD, TEH PLUGIN WILL NOT RESOLVE ANY OV DOSE: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>LOADIN STD GLOBAL CACHE...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>VALIDATIN STD GLOBAL CACHE INTEGRITY...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>FAILD 2 VERIFY STD GLOBAL CACHE INTEGRITY. DIS SUGGESTS POTENTIAL FILE/MEMS CORRUPSHUN, FRESH INSTANCE WILL BE INITIALIZD INSTEAD.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} initialized, the plugin will not resolve any of those: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Loading STD global cache...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Validating STD global cache integrity...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Failed to verify STD global cache integrity. This suggests a potential file/memory corruption, a fresh instance will be initialized instead.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} инициализирован, плагин не взаимодействует ни с одним из их: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Загрузка глобального кэша STD...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Проверка целостности глобального кэша STD...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Не удалось проверить целостность глобального кэша STD. Это говорит о потенциальном повреждении файла/памяти, вместо этого будет инициализирован новый экземпляр.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -168,4 +168,7 @@
|
||||
<value>{0} inicializovaných, modul nebude pracovať so žiadnym: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} başlatıldı, eklenti şunlardan hiçbirini çözemedi: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>STD küresel önbelleği yükleniyor...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>STD küresel önbellek bütünlüğü doğrulanıyor...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>STD küresel önbellek bütünlüğü doğrulanamadı. Bu, olası bir dosya/bellek bozulması olduğunu gösterir, bunun yerine yeni bir örnek başlatılacaktır.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} đã được khởi tạo, plugin sẽ không can thiệp với những thứ sau: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>Đang tải bộ nhớ đệm STD chung...</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>Đang kiểm tra trạng thái bộ nhớ đệm STD chung...</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>Không thể xác minh trạng thái bộ nhớ đệm chung STD. Điều này có khả năng do tệp/bộ nhớ bị hỏng, một trạng thái mới sẽ được khởi tạo thay thế.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -168,4 +168,13 @@
|
||||
<value>{0} 已初始化,插件无法解析以下任何内容:{1}。</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
<data name="LoadingGlobalCache" xml:space="preserve">
|
||||
<value>正在加载 STD 全局缓存……</value>
|
||||
</data>
|
||||
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
|
||||
<value>正在验证 STD 全局缓存完整性……</value>
|
||||
</data>
|
||||
<data name="GlobalCacheIntegrityValidationFailed" xml:space="preserve">
|
||||
<value>验证 STD 全局缓存完整性失败。这意味着潜在的文件或内存损坏,即将初始化新实例作为替代。</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -62,20 +62,72 @@
|
||||
PublicKeyToken=b77a5c561934e089
|
||||
</value>
|
||||
</resheader>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>由於 {0} 缺少組建令牌而被停用</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>目前 {0} 已根據您的設定被停用。如果您想幫助 SteamDB 提交資料,請查看我們的 Wiki。</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>已成功初始化 {0},預先感謝您的幫助。第一次提交將大約在 {1} 後進行。</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>無法載入 {0},將初始化一個新實例…</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>此 Bot 實例中沒有需要再新的應用程式。</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>正在檢索共 {0} 個應用程式存取令牌…</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>正在檢索 {0} 個應用程式存取令牌…</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>已完成檢索 {0} 個應用程式存取令牌。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>已完成檢索共 {0} 個應用程式存取令牌。</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>正在檢索共 {0} 個應用程式的所有資料段儲存目錄…</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>正在檢索 {0} 個應用程式資料…</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>已完成檢索 {0} 個應用程式資料。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>正在檢索 {0} 個應用程式的所有資料段儲存目錄…</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>已完成檢索 {0} 個應用程式的所有資料段儲存目錄。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>已完成檢索共 {0} 個應用程式的所有資料段儲存目錄。</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
</data>
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>沒有要提交的新資料,一切都是最新的。</value>
|
||||
</data>
|
||||
<data name="SubmissionNoContributorSet" xml:space="preserve">
|
||||
<value>無法提交資料,因為沒有可以讓我們歸類為貢獻者的有效 SteamID 集。 考慮設定 {0} 屬性。</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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -58,17 +58,9 @@ internal sealed class RequestData {
|
||||
throw new ArgumentOutOfRangeException(nameof(steamID));
|
||||
}
|
||||
|
||||
if (apps == null) {
|
||||
throw new ArgumentNullException(nameof(apps));
|
||||
}
|
||||
|
||||
if (accessTokens == null) {
|
||||
throw new ArgumentNullException(nameof(accessTokens));
|
||||
}
|
||||
|
||||
if (depots == null) {
|
||||
throw new ArgumentNullException(nameof(depots));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(apps);
|
||||
ArgumentNullException.ThrowIfNull(accessTokens);
|
||||
ArgumentNullException.ThrowIfNull(depots);
|
||||
|
||||
SteamID = steamID;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -62,7 +62,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
|
||||
public Task<uint> GetPreferredChangeNumberToStartFrom() => Task.FromResult(Config?.Enabled == true ? GlobalCache?.LastChangeNumber ?? 0 : 0);
|
||||
|
||||
public async void OnASFInit(IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
public async Task OnASFInit(IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
if (!SharedInfo.HasValidToken) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.PluginDisabledMissingBuildToken, nameof(SteamTokenDumperPlugin)));
|
||||
|
||||
@@ -100,8 +100,6 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
config.Enabled = true;
|
||||
}
|
||||
|
||||
Config = config;
|
||||
|
||||
if (!config.Enabled) {
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.PluginDisabledInConfig, nameof(SteamTokenDumperPlugin)));
|
||||
|
||||
@@ -132,6 +130,8 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
}
|
||||
}
|
||||
|
||||
Config = config;
|
||||
|
||||
#pragma warning disable CA5394 // This call isn't used in a security-sensitive manner
|
||||
TimeSpan startIn = TimeSpan.FromMinutes(Random.Shared.Next(SharedInfo.MinimumMinutesBeforeFirstUpload, SharedInfo.MaximumMinutesBeforeFirstUpload));
|
||||
#pragma warning restore CA5394 // This call isn't used in a security-sensitive manner
|
||||
@@ -144,10 +144,8 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.PluginInitializedAndEnabled, nameof(SteamTokenDumperPlugin), startIn.ToHumanReadable()));
|
||||
}
|
||||
|
||||
public async void OnBotDestroy(Bot bot) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
public async Task OnBotDestroy(Bot bot) {
|
||||
ArgumentNullException.ThrowIfNull(bot);
|
||||
|
||||
if (BotSubscriptions.TryRemove(bot, out IDisposable? subscription)) {
|
||||
subscription.Dispose();
|
||||
@@ -160,10 +158,8 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
}
|
||||
}
|
||||
|
||||
public async void OnBotInit(Bot bot) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
public async Task OnBotInit(Bot bot) {
|
||||
ArgumentNullException.ThrowIfNull(bot);
|
||||
|
||||
if (Config is not { Enabled: true }) {
|
||||
return;
|
||||
@@ -179,21 +175,16 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBotSteamCallbacksInit(Bot bot, CallbackManager callbackManager) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
if (callbackManager == null) {
|
||||
throw new ArgumentNullException(nameof(callbackManager));
|
||||
}
|
||||
public Task OnBotSteamCallbacksInit(Bot bot, CallbackManager callbackManager) {
|
||||
ArgumentNullException.ThrowIfNull(bot);
|
||||
ArgumentNullException.ThrowIfNull(callbackManager);
|
||||
|
||||
if (BotSubscriptions.TryRemove(bot, out IDisposable? subscription)) {
|
||||
subscription.Dispose();
|
||||
}
|
||||
|
||||
if (Config is not { Enabled: true }) {
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
subscription = callbackManager.Subscribe<SteamApps.LicenseListCallback>(callback => OnLicenseList(bot, callback));
|
||||
@@ -201,27 +192,28 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
if (!BotSubscriptions.TryAdd(bot, subscription)) {
|
||||
subscription.Dispose();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<ClientMsgHandler>? OnBotSteamHandlersInit(Bot bot) => null;
|
||||
public Task<IReadOnlyCollection<ClientMsgHandler>?> OnBotSteamHandlersInit(Bot bot) => Task.FromResult((IReadOnlyCollection<ClientMsgHandler>?) null);
|
||||
|
||||
public override void OnLoaded() => Utilities.WarnAboutIncompleteTranslation(Strings.ResourceManager);
|
||||
public override Task OnLoaded() {
|
||||
Utilities.WarnAboutIncompleteTranslation(Strings.ResourceManager);
|
||||
|
||||
public void OnPICSChanges(uint currentChangeNumber, IReadOnlyDictionary<uint, SteamApps.PICSChangesCallback.PICSChangeData> appChanges, IReadOnlyDictionary<uint, SteamApps.PICSChangesCallback.PICSChangeData> packageChanges) {
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task OnPICSChanges(uint currentChangeNumber, IReadOnlyDictionary<uint, SteamApps.PICSChangesCallback.PICSChangeData> appChanges, IReadOnlyDictionary<uint, SteamApps.PICSChangesCallback.PICSChangeData> packageChanges) {
|
||||
if (currentChangeNumber == 0) {
|
||||
throw new ArgumentOutOfRangeException(nameof(currentChangeNumber));
|
||||
}
|
||||
|
||||
if (appChanges == null) {
|
||||
throw new ArgumentNullException(nameof(appChanges));
|
||||
}
|
||||
|
||||
if (packageChanges == null) {
|
||||
throw new ArgumentNullException(nameof(packageChanges));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(appChanges);
|
||||
ArgumentNullException.ThrowIfNull(packageChanges);
|
||||
|
||||
if (Config is not { Enabled: true }) {
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (GlobalCache == null) {
|
||||
@@ -229,15 +221,17 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
}
|
||||
|
||||
GlobalCache.OnPICSChanges(currentChangeNumber, appChanges);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void OnPICSChangesRestart(uint currentChangeNumber) {
|
||||
public Task OnPICSChangesRestart(uint currentChangeNumber) {
|
||||
if (currentChangeNumber == 0) {
|
||||
throw new ArgumentOutOfRangeException(nameof(currentChangeNumber));
|
||||
}
|
||||
|
||||
if (Config is not { Enabled: true }) {
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (GlobalCache == null) {
|
||||
@@ -245,6 +239,8 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
}
|
||||
|
||||
GlobalCache.OnPICSChangesRestart(currentChangeNumber);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static async void OnBotRefreshTimer(object? state) {
|
||||
@@ -256,13 +252,8 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
}
|
||||
|
||||
private static async void OnLicenseList(Bot bot, SteamApps.LicenseListCallback callback) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
if (callback == null) {
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(bot);
|
||||
ArgumentNullException.ThrowIfNull(callback);
|
||||
|
||||
if (Config is not { Enabled: true }) {
|
||||
return;
|
||||
@@ -280,9 +271,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
}
|
||||
|
||||
private static async Task Refresh(Bot bot, IReadOnlyCollection<uint>? packageIDs = null) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(bot);
|
||||
|
||||
if (Config is not { Enabled: true }) {
|
||||
return;
|
||||
@@ -467,10 +456,6 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
throw new InvalidOperationException(nameof(GlobalCache));
|
||||
}
|
||||
|
||||
if (ASF.GlobalConfig == null) {
|
||||
throw new InvalidOperationException(nameof(ASF.GlobalConfig));
|
||||
}
|
||||
|
||||
if (ASF.WebBrowser == null) {
|
||||
throw new InvalidOperationException(nameof(ASF.WebBrowser));
|
||||
}
|
||||
@@ -490,7 +475,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotS
|
||||
return;
|
||||
}
|
||||
|
||||
ulong contributorSteamID = (ASF.GlobalConfig.SteamOwnerID > 0) && new SteamID(ASF.GlobalConfig.SteamOwnerID).IsIndividualAccount ? ASF.GlobalConfig.SteamOwnerID : Bot.Bots.Values.Where(static bot => bot.SteamID > 0).OrderByDescending(static bot => bot.OwnedPackageIDs.Count).FirstOrDefault()?.SteamID ?? 0;
|
||||
ulong contributorSteamID = ASF.GlobalConfig is { SteamOwnerID: > 0 } && new SteamID(ASF.GlobalConfig.SteamOwnerID).IsIndividualAccount ? ASF.GlobalConfig.SteamOwnerID : Bot.Bots.Values.Where(static bot => bot.SteamID > 0).OrderByDescending(static bot => bot.OwnedPackageIDs.Count).FirstOrDefault()?.SteamID ?? 0;
|
||||
|
||||
if (contributorSteamID == 0) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionNoContributorSet, nameof(ASF.GlobalConfig.SteamOwnerID)));
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="all" />
|
||||
<PackageReference Include="JetBrains.Annotations" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="MSTest.TestAdapter" />
|
||||
<PackageReference Include="MSTest.TestFramework" />
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -485,13 +485,8 @@ public sealed class Bot {
|
||||
}
|
||||
|
||||
private static void AssertResultMatchesExpectation(IReadOnlyDictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult, IReadOnlyCollection<Asset> itemsToSend) {
|
||||
if (expectedResult == null) {
|
||||
throw new ArgumentNullException(nameof(expectedResult));
|
||||
}
|
||||
|
||||
if (itemsToSend == null) {
|
||||
throw new ArgumentNullException(nameof(itemsToSend));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(expectedResult);
|
||||
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);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -24,10 +24,10 @@ using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: CLSCompliant(false)]
|
||||
|
||||
#if DEBUG
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.Tests")]
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.OfficialPlugins.SteamTokenDumper")]
|
||||
#else
|
||||
#if ASF_SIGNED_BUILD
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.Tests, PublicKey=002400000480000014020000060200000024000052534131001000000100010099f0e5961ec7497fd7de1cba2b8c5eff3b18c1faf3d7a8d56e063359c7f928b54b14eae24d23d9d3c1a5db7ceca82edb6956d43e8ea2a0b7223e6e6836c0b809de43fde69bf33fba73cf669e71449284d477333d4b6e54fb69f7b6c4b4811b8fe26e88975e593cffc0e321490a50500865c01e50ab87c8a943b2a788af47dc20f2b860062b7b6df25477e471a744485a286b435cea2df3953cbb66febd8db73f3ccb4588886373141d200f749ba40bb11926b668cc15f328412dd0b0b835909229985336eb4a34f47925558dc6dc3910ea09c1aad5c744833f26ad9de727559d393526a7a29b3383de87802a034ead8ecc2d37340a5fa9b406774446256337d77e3c9e8486b5e732097e238312deaf5b4efcc04df8ecb986d90ee12b4a8a9a00319cc25cb91fd3e36a3cc39e501f83d14eb1e1a6fa6a1365483d99f4cefad1ea5dec204dad958e2a9a93add19781a8aa7bac71747b11d156711eafd1e873e19836eb573fa5cde284739df09b658ed40c56c7b5a7596840774a7065864e6c2af7b5a8bf7a2d238de83d77891d98ef5a4a58248c655a1c7c97c99e01d9928dc60c629eeb523356dc3686e3f9a1a30ffcd0268cd03718292f21d839fce741f4c1163001ab5b654c37d862998962a05e8028e061c611384772777ef6a49b00ebb4f228308e61b2afe408b33db2d82c4f385e26d7438ec0a183c64eeca4138cbc3dc2")]
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.OfficialPlugins.SteamTokenDumper, PublicKey=002400000480000014020000060200000024000052534131001000000100010099f0e5961ec7497fd7de1cba2b8c5eff3b18c1faf3d7a8d56e063359c7f928b54b14eae24d23d9d3c1a5db7ceca82edb6956d43e8ea2a0b7223e6e6836c0b809de43fde69bf33fba73cf669e71449284d477333d4b6e54fb69f7b6c4b4811b8fe26e88975e593cffc0e321490a50500865c01e50ab87c8a943b2a788af47dc20f2b860062b7b6df25477e471a744485a286b435cea2df3953cbb66febd8db73f3ccb4588886373141d200f749ba40bb11926b668cc15f328412dd0b0b835909229985336eb4a34f47925558dc6dc3910ea09c1aad5c744833f26ad9de727559d393526a7a29b3383de87802a034ead8ecc2d37340a5fa9b406774446256337d77e3c9e8486b5e732097e238312deaf5b4efcc04df8ecb986d90ee12b4a8a9a00319cc25cb91fd3e36a3cc39e501f83d14eb1e1a6fa6a1365483d99f4cefad1ea5dec204dad958e2a9a93add19781a8aa7bac71747b11d156711eafd1e873e19836eb573fa5cde284739df09b658ed40c56c7b5a7596840774a7065864e6c2af7b5a8bf7a2d238de83d77891d98ef5a4a58248c655a1c7c97c99e01d9928dc60c629eeb523356dc3686e3f9a1a30ffcd0268cd03718292f21d839fce741f4c1163001ab5b654c37d862998962a05e8028e061c611384772777ef6a49b00ebb4f228308e61b2afe408b33db2d82c4f385e26d7438ec0a183c64eeca4138cbc3dc2")]
|
||||
#else
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.Tests")]
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.OfficialPlugins.SteamTokenDumper")]
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -34,9 +34,7 @@ internal sealed class ConcurrentEnumerator<T> : IEnumerator<T> {
|
||||
object? IEnumerator.Current => Current;
|
||||
|
||||
internal ConcurrentEnumerator(IReadOnlyCollection<T> collection, IDisposable lockObject) {
|
||||
if (collection == null) {
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(collection);
|
||||
|
||||
LockObject = lockObject ?? throw new ArgumentNullException(nameof(lockObject));
|
||||
Enumerator = collection.GetEnumerator();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -39,9 +39,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ISet<T> where
|
||||
public ConcurrentHashSet() => BackingCollection = new ConcurrentDictionary<T, bool>();
|
||||
|
||||
public ConcurrentHashSet(IEqualityComparer<T> comparer) {
|
||||
if (comparer == null) {
|
||||
throw new ArgumentNullException(nameof(comparer));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(comparer);
|
||||
|
||||
BackingCollection = new ConcurrentDictionary<T, bool>(comparer);
|
||||
}
|
||||
@@ -71,9 +69,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ISet<T> where
|
||||
public void CopyTo(T[] array, int arrayIndex) => BackingCollection.Keys.CopyTo(array, arrayIndex);
|
||||
|
||||
public void ExceptWith(IEnumerable<T> other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentNullException(nameof(other));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(other);
|
||||
|
||||
foreach (T item in other) {
|
||||
Remove(item);
|
||||
@@ -151,9 +147,7 @@ public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ISet<T> where
|
||||
}
|
||||
|
||||
public void UnionWith(IEnumerable<T> other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentNullException(nameof(other));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(other);
|
||||
|
||||
foreach (T otherElement in other) {
|
||||
Add(otherElement);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -69,6 +69,8 @@ public static class ASF {
|
||||
[PublicAPI]
|
||||
public static WebBrowser? WebBrowser { get; private set; }
|
||||
|
||||
internal static readonly SemaphoreSlim OpenConnectionsSemaphore = new(WebBrowser.MaxConnections, WebBrowser.MaxConnections);
|
||||
|
||||
internal static ICrossProcessSemaphore? ConfirmationsSemaphore { get; private set; }
|
||||
internal static ICrossProcessSemaphore? GiftsSemaphore { get; private set; }
|
||||
internal static ICrossProcessSemaphore? InventorySemaphore { get; private set; }
|
||||
@@ -94,7 +96,7 @@ public static class ASF {
|
||||
}
|
||||
|
||||
internal static string GetFilePath(EFileType fileType) {
|
||||
if (!Enum.IsDefined(typeof(EFileType), fileType)) {
|
||||
if (!Enum.IsDefined(fileType)) {
|
||||
throw new InvalidEnumArgumentException(nameof(fileType), (int) fileType, typeof(EFileType));
|
||||
}
|
||||
|
||||
@@ -315,12 +317,18 @@ public static class ASF {
|
||||
return SharedInfo.Version;
|
||||
}
|
||||
|
||||
try {
|
||||
await PluginsCore.OnUpdateProceeding(newVersion).ConfigureAwait(false);
|
||||
|
||||
bool kestrelWasRunning = ArchiKestrel.IsRunning;
|
||||
|
||||
if (kestrelWasRunning) {
|
||||
// We disable ArchiKestrel here as the update process moves the core files and might result in IPC crash
|
||||
// TODO: It might fail if the update was triggered from the API, this should be something to improve in the future, by changing the structure into request -> return response -> finish update
|
||||
await ArchiKestrel.Stop().ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericWarningException(e);
|
||||
try {
|
||||
await ArchiKestrel.Stop().ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericWarningException(e);
|
||||
}
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.PatchingFiles);
|
||||
@@ -338,11 +346,23 @@ public static class ASF {
|
||||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericException(e);
|
||||
|
||||
if (kestrelWasRunning) {
|
||||
// We've temporarily disabled ArchiKestrel but the update has failed, let's bring it back up
|
||||
// We can't even be sure if it's possible to bring it back up in this state, but it's worth trying anyway
|
||||
try {
|
||||
await ArchiKestrel.Start().ConfigureAwait(false);
|
||||
} catch (Exception ex) {
|
||||
ArchiLogger.LogGenericWarningException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.UpdateFinished);
|
||||
|
||||
await PluginsCore.OnUpdateFinished(newVersion).ConfigureAwait(false);
|
||||
|
||||
return newVersion;
|
||||
} finally {
|
||||
UpdateSemaphore.Release();
|
||||
@@ -481,13 +501,8 @@ public static class ASF {
|
||||
private static async void OnAutoUpdatesTimer(object? state = null) => await UpdateAndRestart().ConfigureAwait(false);
|
||||
|
||||
private static async void OnChanged(object sender, FileSystemEventArgs e) {
|
||||
if (sender == null) {
|
||||
throw new ArgumentNullException(nameof(sender));
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
throw new ArgumentNullException(nameof(e));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(sender);
|
||||
ArgumentNullException.ThrowIfNull(e);
|
||||
|
||||
if (string.IsNullOrEmpty(e.Name)) {
|
||||
throw new InvalidOperationException(nameof(e.Name));
|
||||
@@ -567,13 +582,8 @@ public static class ASF {
|
||||
}
|
||||
|
||||
private static async void OnCreated(object sender, FileSystemEventArgs e) {
|
||||
if (sender == null) {
|
||||
throw new ArgumentNullException(nameof(sender));
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
throw new ArgumentNullException(nameof(e));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(sender);
|
||||
ArgumentNullException.ThrowIfNull(e);
|
||||
|
||||
if (string.IsNullOrEmpty(e.Name)) {
|
||||
throw new InvalidOperationException(nameof(e.Name));
|
||||
@@ -709,13 +719,8 @@ public static class ASF {
|
||||
}
|
||||
|
||||
private static async void OnDeleted(object sender, FileSystemEventArgs e) {
|
||||
if (sender == null) {
|
||||
throw new ArgumentNullException(nameof(sender));
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
throw new ArgumentNullException(nameof(e));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(sender);
|
||||
ArgumentNullException.ThrowIfNull(e);
|
||||
|
||||
if (string.IsNullOrEmpty(e.Name)) {
|
||||
throw new InvalidOperationException(nameof(e.Name));
|
||||
@@ -833,13 +838,8 @@ public static class ASF {
|
||||
}
|
||||
|
||||
private static async void OnRenamed(object sender, RenamedEventArgs e) {
|
||||
if (sender == null) {
|
||||
throw new ArgumentNullException(nameof(sender));
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
throw new ArgumentNullException(nameof(e));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(sender);
|
||||
ArgumentNullException.ThrowIfNull(e);
|
||||
|
||||
if (string.IsNullOrEmpty(e.OldName)) {
|
||||
throw new InvalidOperationException(nameof(e.OldName));
|
||||
@@ -949,9 +949,7 @@ public static class ASF {
|
||||
}
|
||||
|
||||
private static bool UpdateFromArchive(ZipArchive archive, string targetDirectory) {
|
||||
if (archive == null) {
|
||||
throw new ArgumentNullException(nameof(archive));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(archive);
|
||||
|
||||
if (string.IsNullOrEmpty(targetDirectory)) {
|
||||
throw new ArgumentNullException(nameof(targetDirectory));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -41,9 +41,7 @@ internal static class ArchiNet {
|
||||
private static Uri URL => new("https://asf.JustArchi.net");
|
||||
|
||||
internal static async Task<HttpStatusCode?> AnnounceForListing(Bot bot, IReadOnlyCollection<Asset> inventory, IReadOnlyCollection<Asset.EType> acceptedMatchableTypes, string tradeToken, string? nickname = null, string? avatarHash = null) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(bot);
|
||||
|
||||
if ((inventory == null) || (inventory.Count == 0)) {
|
||||
throw new ArgumentNullException(nameof(inventory));
|
||||
@@ -105,9 +103,7 @@ internal static class ArchiNet {
|
||||
}
|
||||
|
||||
internal static async Task<ImmutableHashSet<ListedUser>?> GetListedUsers(Bot bot) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(bot);
|
||||
|
||||
Uri request = new(URL, "/Api/Bots");
|
||||
|
||||
@@ -117,9 +113,7 @@ internal static class ArchiNet {
|
||||
}
|
||||
|
||||
internal static async Task<HttpStatusCode?> HeartBeatForListing(Bot bot) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(bot);
|
||||
|
||||
Uri request = new(URL, "/Api/HeartBeat");
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -20,6 +20,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm.Core;
|
||||
@@ -31,7 +32,7 @@ internal static class Debugging {
|
||||
internal static bool IsDebugBuild => false;
|
||||
#endif
|
||||
|
||||
internal static bool IsDebugConfigured => ASF.GlobalConfig?.Debug ?? throw new InvalidOperationException(nameof(ASF.GlobalConfig));
|
||||
internal static bool IsDebugConfigured => ASF.GlobalConfig?.Debug ?? GlobalConfig.DefaultDebug;
|
||||
|
||||
internal static bool IsUserDebugging => IsDebugBuild || IsDebugConfigured;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -121,7 +121,7 @@ internal static class OS {
|
||||
}
|
||||
|
||||
internal static void Init(GlobalConfig.EOptimizationMode optimizationMode) {
|
||||
if (!Enum.IsDefined(typeof(GlobalConfig.EOptimizationMode), optimizationMode)) {
|
||||
if (!Enum.IsDefined(optimizationMode)) {
|
||||
throw new ArgumentNullException(nameof(optimizationMode));
|
||||
}
|
||||
|
||||
@@ -226,34 +226,67 @@ internal static class OS {
|
||||
}
|
||||
|
||||
internal static bool VerifyEnvironment() {
|
||||
#if NETFRAMEWORK
|
||||
// This is .NET Framework build, we support that one only on mono for platforms not supported by .NET Core
|
||||
|
||||
// We're not going to analyze source builds, as we don't know what changes the author has made, assume they have a point
|
||||
if (SharedInfo.BuildInfo.IsCustomBuild) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// All windows variants have valid .NET Core build, and generic-netf is supported only on mono
|
||||
if (OperatingSystem.IsWindows() || !RuntimeMadness.IsRunningOnMono) {
|
||||
return false;
|
||||
}
|
||||
if (SharedInfo.BuildInfo.Variant.EndsWith("-netf", StringComparison.Ordinal)) {
|
||||
#if NETFRAMEWORK
|
||||
// All Windows variants (7+) have valid .NET Core build
|
||||
if (OperatingSystem.IsWindows()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return RuntimeInformation.OSArchitecture switch {
|
||||
// Sadly we can't tell a difference between ARMv6 and ARMv7 reliably, we'll believe that this linux-arm user knows what he's doing and he's indeed in need of generic-netf on ARMv6
|
||||
Architecture.Arm => true,
|
||||
// Non-Windows variants of generic-netf are supported only in Mono
|
||||
if (!RuntimeMadness.IsRunningOnMono) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apart from real x86, this also covers all unknown architectures, such as sparc, ppc64, and anything else Mono might support, we're fine with that
|
||||
Architecture.X86 => true,
|
||||
// Platforms not supported by .NET Core
|
||||
return RuntimeInformation.OSArchitecture switch {
|
||||
// Sadly we can't tell a difference between ARMv6 and ARMv7 reliably, we'll believe that this linux-arm user knows what he's doing and he's indeed in need of generic-netf on ARMv6
|
||||
Architecture.Arm => true,
|
||||
|
||||
// Everything else is covered by .NET Core
|
||||
_ => false
|
||||
};
|
||||
// Apart from real x86, this also covers all unknown architectures, such as sparc, ppc64, and anything else Mono might support, we're fine with that
|
||||
Architecture.X86 => true,
|
||||
|
||||
// Everything else is covered by .NET Core
|
||||
_ => false
|
||||
};
|
||||
#else
|
||||
|
||||
// This is .NET Core build, we support all scenarios
|
||||
return true;
|
||||
// .NET Framework build running on .NET Core? Very funny - only if somebody lied during build process
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningUnknownValuePleaseReport, nameof(SharedInfo.BuildInfo.Variant), SharedInfo.BuildInfo.Variant));
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (SharedInfo.BuildInfo.Variant == "generic") {
|
||||
// Generic is supported everywhere
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((SharedInfo.BuildInfo.Variant == "docker") || SharedInfo.BuildInfo.Variant.StartsWith("linux-", StringComparison.Ordinal)) {
|
||||
// OS-specific Linux and Docker builds are supported only on Linux
|
||||
return OperatingSystem.IsLinux();
|
||||
}
|
||||
|
||||
if (SharedInfo.BuildInfo.Variant.StartsWith("osx-", StringComparison.Ordinal)) {
|
||||
// OS-specific OS X build is supported only on OS X
|
||||
return OperatingSystem.IsMacOS();
|
||||
}
|
||||
|
||||
if (SharedInfo.BuildInfo.Variant.StartsWith("win-", StringComparison.Ordinal)) {
|
||||
// OS-specific Windows build is supported only on Windows
|
||||
return OperatingSystem.IsWindows();
|
||||
}
|
||||
|
||||
// Unknown combination, we intend to cover all of the available ones above, so this results in an error
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningUnknownValuePleaseReport, nameof(SharedInfo.BuildInfo.Variant), SharedInfo.BuildInfo.Variant));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("Windows")]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -41,7 +41,7 @@ using ArchiSteamFarm.Web;
|
||||
|
||||
namespace ArchiSteamFarm.Core;
|
||||
|
||||
internal sealed class Statistics : IAsyncDisposable {
|
||||
internal sealed class RemoteCommunication : IAsyncDisposable {
|
||||
private const ushort MaxItemsForFairBots = ArchiWebHandler.MaxItemsInSingleInventoryRequest * WebBrowser.MaxTries; // Determines which fair bots we'll deprioritize when matching due to excessive number of inventory requests they need to make, which are likely to fail in the process or cause excessive delays
|
||||
private const byte MaxMatchedBotsHard = 40; // Determines how many bots we can attempt to match in total, where match attempt is equal to analyzing bot's inventory
|
||||
private const byte MaxMatchingRounds = 10; // Determines maximum amount of matching rounds we're going to consider before leaving the rest of work for the next batch
|
||||
@@ -61,7 +61,7 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
private readonly SemaphoreSlim MatchActivelySemaphore = new(1, 1);
|
||||
|
||||
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
|
||||
private readonly Timer MatchActivelyTimer;
|
||||
private readonly Timer? MatchActivelyTimer;
|
||||
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
|
||||
|
||||
private readonly SemaphoreSlim RequestsSemaphore = new(1, 1);
|
||||
@@ -71,25 +71,33 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
private DateTime LastPersonaStateRequest;
|
||||
private bool ShouldSendHeartBeats;
|
||||
|
||||
internal Statistics(Bot bot) {
|
||||
internal RemoteCommunication(Bot bot) {
|
||||
Bot = bot ?? throw new ArgumentNullException(nameof(bot));
|
||||
|
||||
MatchActivelyTimer = new Timer(
|
||||
MatchActively,
|
||||
null,
|
||||
TimeSpan.FromHours(1) + TimeSpan.FromSeconds(ASF.LoadBalancingDelay * Bot.Bots?.Count ?? 0), // Delay
|
||||
TimeSpan.FromHours(8) // Period
|
||||
);
|
||||
if (Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.MatchActively)) {
|
||||
MatchActivelyTimer = new Timer(
|
||||
MatchActively,
|
||||
null,
|
||||
TimeSpan.FromHours(1) + TimeSpan.FromSeconds(ASF.LoadBalancingDelay * Bot.Bots?.Count ?? 0), // Delay
|
||||
TimeSpan.FromHours(8) // Period
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync() {
|
||||
MatchActivelySemaphore.Dispose();
|
||||
RequestsSemaphore.Dispose();
|
||||
|
||||
await MatchActivelyTimer.DisposeAsync().ConfigureAwait(false);
|
||||
if (MatchActivelyTimer != null) {
|
||||
await MatchActivelyTimer.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task OnHeartBeat() {
|
||||
if (!Bot.BotConfig.RemoteCommunication.HasFlag(BotConfig.ERemoteCommunication.PublicListing)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Request persona update if needed
|
||||
if ((DateTime.UtcNow > LastPersonaStateRequest.AddHours(MinPersonaStateTTL)) && (DateTime.UtcNow > LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL))) {
|
||||
LastPersonaStateRequest = DateTime.UtcNow;
|
||||
@@ -125,12 +133,20 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
}
|
||||
|
||||
internal async Task OnLoggedOn() {
|
||||
if (!Bot.BotConfig.RemoteCommunication.HasFlag(BotConfig.ERemoteCommunication.SteamGroup)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await Bot.ArchiWebHandler.JoinGroup(SharedInfo.ASFGroupSteamID).ConfigureAwait(false)) {
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(ArchiWebHandler.JoinGroup)));
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task OnPersonaState(string? nickname = null, string? avatarHash = null) {
|
||||
if (!Bot.BotConfig.RemoteCommunication.HasFlag(BotConfig.ERemoteCommunication.PublicListing)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((DateTime.UtcNow < LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL)) && (ShouldSendHeartBeats || (LastHeartBeat == DateTime.MinValue))) {
|
||||
return;
|
||||
}
|
||||
@@ -229,12 +245,20 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
}
|
||||
|
||||
private async Task<bool?> IsEligibleForListing() {
|
||||
// Bot must be eligible for matching first
|
||||
bool? isEligibleForMatching = await IsEligibleForMatching().ConfigureAwait(false);
|
||||
|
||||
if (isEligibleForMatching != true) {
|
||||
return isEligibleForMatching;
|
||||
}
|
||||
|
||||
// Bot must have STM enabled in TradingPreferences
|
||||
if (!Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher)) {
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.TradingPreferences)}: {Bot.BotConfig.TradingPreferences}"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bot must have public inventory
|
||||
bool? hasPublicInventory = await Bot.HasPublicInventory().ConfigureAwait(false);
|
||||
|
||||
@@ -255,13 +279,6 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bot must have STM enable in TradingPreferences
|
||||
if (!Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher)) {
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.TradingPreferences)}: {Bot.BotConfig.TradingPreferences}"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bot must have at least one accepted matchable type set
|
||||
if ((Bot.BotConfig.MatchableTypes.Count == 0) || Bot.BotConfig.MatchableTypes.All(static type => !AcceptedMatchableTypes.Contains(type))) {
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.MatchableTypes)}: {string.Join(", ", Bot.BotConfig.MatchableTypes)}"));
|
||||
@@ -342,9 +359,7 @@ internal sealed class Statistics : IAsyncDisposable {
|
||||
throw new ArgumentNullException(nameof(acceptedMatchableTypes));
|
||||
}
|
||||
|
||||
if (triedSteamIDs == null) {
|
||||
throw new ArgumentNullException(nameof(triedSteamIDs));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(triedSteamIDs);
|
||||
|
||||
HashSet<Asset> ourInventory;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -51,9 +51,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static string GetArgsAsText(string[] args, byte argsToSkip, string delimiter) {
|
||||
if (args == null) {
|
||||
throw new ArgumentNullException(nameof(args));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(args);
|
||||
|
||||
if (args.Length <= argsToSkip) {
|
||||
throw new InvalidOperationException($"{nameof(args.Length)} && {nameof(argsToSkip)}");
|
||||
@@ -79,9 +77,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static string? GetCookieValue(this CookieContainer cookieContainer, Uri uri, string name) {
|
||||
if (cookieContainer == null) {
|
||||
throw new ArgumentNullException(nameof(cookieContainer));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(cookieContainer);
|
||||
|
||||
if (uri == null) {
|
||||
throw new ArgumentNullException(nameof(uri));
|
||||
@@ -105,9 +101,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static async void InBackground(Action action, bool longRunning = false) {
|
||||
if (action == null) {
|
||||
throw new ArgumentNullException(nameof(action));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(action);
|
||||
|
||||
TaskCreationOptions options = TaskCreationOptions.DenyChildAttach;
|
||||
|
||||
@@ -120,9 +114,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static async void InBackground<T>(Func<T> function, bool longRunning = false) {
|
||||
if (function == null) {
|
||||
throw new ArgumentNullException(nameof(function));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(function);
|
||||
|
||||
TaskCreationOptions options = TaskCreationOptions.DenyChildAttach;
|
||||
|
||||
@@ -135,9 +127,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static async Task<IList<T>> InParallel<T>(IEnumerable<Task<T>> tasks) {
|
||||
if (tasks == null) {
|
||||
throw new ArgumentNullException(nameof(tasks));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(tasks);
|
||||
|
||||
IList<T> results;
|
||||
|
||||
@@ -161,9 +151,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static async Task InParallel(IEnumerable<Task> tasks) {
|
||||
if (tasks == null) {
|
||||
throw new ArgumentNullException(nameof(tasks));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(tasks);
|
||||
|
||||
switch (ASF.GlobalConfig?.OptimizationMode) {
|
||||
case GlobalConfig.EOptimizationMode.MinMemoryUsage:
|
||||
@@ -208,9 +196,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static IEnumerable<IElement> SelectNodes(this IDocument document, string xpath) {
|
||||
if (document == null) {
|
||||
throw new ArgumentNullException(nameof(document));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(document);
|
||||
|
||||
return document.Body.SelectNodes(xpath).OfType<IElement>();
|
||||
}
|
||||
@@ -220,9 +206,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static IElement? SelectSingleNode(this IDocument document, string xpath) {
|
||||
if (document == null) {
|
||||
throw new ArgumentNullException(nameof(document));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(document);
|
||||
|
||||
return (IElement?) document.Body.SelectSingleNode(xpath);
|
||||
}
|
||||
@@ -237,9 +221,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static Task<T> ToLongRunningTask<T>(this AsyncJob<T> job) where T : CallbackMsg {
|
||||
if (job == null) {
|
||||
throw new ArgumentNullException(nameof(job));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(job);
|
||||
|
||||
job.Timeout = TimeSpan.FromSeconds(TimeoutForLongRunningTasksInSeconds);
|
||||
|
||||
@@ -248,9 +230,7 @@ public static class Utilities {
|
||||
|
||||
[PublicAPI]
|
||||
public static Task<AsyncJobMultiple<T>.ResultSet> ToLongRunningTask<T>(this AsyncJobMultiple<T> job) where T : CallbackMsg {
|
||||
if (job == null) {
|
||||
throw new ArgumentNullException(nameof(job));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(job);
|
||||
|
||||
job.Timeout = TimeSpan.FromSeconds(TimeoutForLongRunningTasksInSeconds);
|
||||
|
||||
@@ -311,9 +291,7 @@ public static class Utilities {
|
||||
}
|
||||
|
||||
internal static void WarnAboutIncompleteTranslation(ResourceManager resourceManager) {
|
||||
if (resourceManager == null) {
|
||||
throw new ArgumentNullException(nameof(resourceManager));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(resourceManager);
|
||||
|
||||
// Skip translation progress for English and invariant (such as "C") cultures
|
||||
switch (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -48,7 +48,7 @@ public sealed class ArchiCacheable<T> : IDisposable {
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<(bool Success, T? Result)> GetValue(EFallback fallback = EFallback.DefaultForType) {
|
||||
if (!Enum.IsDefined(typeof(EFallback), fallback)) {
|
||||
if (!Enum.IsDefined(fallback)) {
|
||||
throw new InvalidEnumArgumentException(nameof(fallback), (int) fallback, typeof(EFallback));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -60,7 +60,7 @@ public static class ArchiCryptoHelper {
|
||||
private static byte[] EncryptionKey = Encoding.UTF8.GetBytes(nameof(ArchiSteamFarm));
|
||||
|
||||
internal static async Task<string?> Decrypt(ECryptoMethod cryptoMethod, string encryptedString) {
|
||||
if (!Enum.IsDefined(typeof(ECryptoMethod), cryptoMethod)) {
|
||||
if (!Enum.IsDefined(cryptoMethod)) {
|
||||
throw new InvalidEnumArgumentException(nameof(cryptoMethod), (int) cryptoMethod, typeof(ECryptoMethod));
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public static class ArchiCryptoHelper {
|
||||
}
|
||||
|
||||
internal static string? Encrypt(ECryptoMethod cryptoMethod, string decryptedString) {
|
||||
if (!Enum.IsDefined(typeof(ECryptoMethod), cryptoMethod)) {
|
||||
if (!Enum.IsDefined(cryptoMethod)) {
|
||||
throw new InvalidEnumArgumentException(nameof(cryptoMethod), (int) cryptoMethod, typeof(ECryptoMethod));
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public static class ArchiCryptoHelper {
|
||||
}
|
||||
|
||||
internal static string Hash(EHashingMethod hashingMethod, string stringToHash) {
|
||||
if (!Enum.IsDefined(typeof(EHashingMethod), hashingMethod)) {
|
||||
if (!Enum.IsDefined(hashingMethod)) {
|
||||
throw new InvalidEnumArgumentException(nameof(hashingMethod), (int) hashingMethod, typeof(EHashingMethod));
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ public static class ArchiCryptoHelper {
|
||||
throw new ArgumentOutOfRangeException(nameof(hashLength));
|
||||
}
|
||||
|
||||
if (!Enum.IsDefined(typeof(EHashingMethod), hashingMethod)) {
|
||||
if (!Enum.IsDefined(hashingMethod)) {
|
||||
throw new InvalidEnumArgumentException(nameof(hashingMethod), (int) hashingMethod, typeof(EHashingMethod));
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public static class ArchiCryptoHelper {
|
||||
throw new ArgumentNullException(nameof(salt));
|
||||
}
|
||||
|
||||
if (!Enum.IsDefined(typeof(EHashingMethod), hashingMethod)) {
|
||||
if (!Enum.IsDefined(hashingMethod)) {
|
||||
throw new InvalidEnumArgumentException(nameof(hashingMethod), (int) hashingMethod, typeof(EHashingMethod));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -42,6 +42,8 @@ using NLog.Web;
|
||||
namespace ArchiSteamFarm.IPC;
|
||||
|
||||
internal static class ArchiKestrel {
|
||||
internal static bool IsRunning => KestrelWebHost != null;
|
||||
|
||||
internal static HistoryTarget? HistoryTarget { get; private set; }
|
||||
|
||||
private static IHost? KestrelWebHost;
|
||||
@@ -113,7 +115,9 @@ internal static class ArchiKestrel {
|
||||
builder.ConfigureWebHostDefaults(
|
||||
webBuilder => {
|
||||
// Set default web root
|
||||
webBuilder.UseWebRoot(websiteDirectory);
|
||||
if (Directory.Exists(websiteDirectory)) {
|
||||
webBuilder.UseWebRoot(websiteDirectory);
|
||||
}
|
||||
|
||||
// Now conditionally initialize settings that are not possible to override
|
||||
if (customConfigExists) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -46,9 +46,7 @@ public sealed class ASFController : ArchiController {
|
||||
[ProducesResponseType(typeof(GenericResponse<string>), (int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)]
|
||||
public ActionResult<GenericResponse> ASFEncryptPost([FromBody] ASFEncryptRequest request) {
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if (string.IsNullOrEmpty(request.StringToEncrypt)) {
|
||||
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(request.StringToEncrypt))));
|
||||
@@ -84,9 +82,7 @@ public sealed class ASFController : ArchiController {
|
||||
[ProducesResponseType(typeof(GenericResponse<string>), (int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)]
|
||||
public ActionResult<GenericResponse> ASFHashPost([FromBody] ASFHashRequest request) {
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if (string.IsNullOrEmpty(request.StringToHash)) {
|
||||
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(request.StringToHash))));
|
||||
@@ -105,9 +101,7 @@ public sealed class ASFController : ArchiController {
|
||||
[ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)]
|
||||
public async Task<ActionResult<GenericResponse>> ASFPost([FromBody] ASFRequest request) {
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if (ASF.GlobalConfig == null) {
|
||||
throw new InvalidOperationException(nameof(ASF.GlobalConfig));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -94,9 +94,7 @@ public sealed class BotController : ArchiController {
|
||||
throw new ArgumentNullException(nameof(botNames));
|
||||
}
|
||||
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if (Bot.Bots == null) {
|
||||
throw new InvalidOperationException(nameof(Bot.Bots));
|
||||
@@ -220,9 +218,7 @@ public sealed class BotController : ArchiController {
|
||||
throw new ArgumentNullException(nameof(botNames));
|
||||
}
|
||||
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if (request.GamesToRedeemInBackground.Count == 0) {
|
||||
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(request.GamesToRedeemInBackground))));
|
||||
@@ -263,11 +259,9 @@ public sealed class BotController : ArchiController {
|
||||
throw new ArgumentNullException(nameof(botNames));
|
||||
}
|
||||
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if ((request.Type == ASF.EUserInputType.None) || !Enum.IsDefined(typeof(ASF.EUserInputType), request.Type) || string.IsNullOrEmpty(request.Value)) {
|
||||
if ((request.Type == ASF.EUserInputType.None) || !Enum.IsDefined(request.Type) || string.IsNullOrEmpty(request.Value)) {
|
||||
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, $"{nameof(request.Type)} || {nameof(request.Value)}")));
|
||||
}
|
||||
|
||||
@@ -294,9 +288,7 @@ public sealed class BotController : ArchiController {
|
||||
throw new ArgumentNullException(nameof(botNames));
|
||||
}
|
||||
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
HashSet<Bot>? bots = Bot.GetBots(botNames);
|
||||
|
||||
@@ -325,9 +317,7 @@ public sealed class BotController : ArchiController {
|
||||
throw new ArgumentNullException(nameof(botNames));
|
||||
}
|
||||
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if (request.KeysToRedeem.Count == 0) {
|
||||
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(request.KeysToRedeem))));
|
||||
@@ -369,9 +359,7 @@ public sealed class BotController : ArchiController {
|
||||
throw new ArgumentNullException(nameof(botName));
|
||||
}
|
||||
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if (Bot.Bots == null) {
|
||||
throw new InvalidOperationException(nameof(Bot.Bots));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -48,20 +48,12 @@ public sealed class CommandController : ArchiController {
|
||||
[ProducesResponseType(typeof(GenericResponse<string>), (int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)]
|
||||
public async Task<ActionResult<GenericResponse>> CommandPost([FromBody] CommandRequest request) {
|
||||
if (request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
|
||||
if (string.IsNullOrEmpty(request.Command)) {
|
||||
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(request.Command))));
|
||||
}
|
||||
|
||||
ulong steamOwnerID = ASF.GlobalConfig?.SteamOwnerID ?? GlobalConfig.DefaultSteamOwnerID;
|
||||
|
||||
if (steamOwnerID == 0) {
|
||||
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(ASF.GlobalConfig.SteamOwnerID))));
|
||||
}
|
||||
|
||||
Bot? targetBot = Bot.Bots?.OrderBy(static bot => bot.Key, Bot.BotsComparer).Select(static bot => bot.Value).FirstOrDefault();
|
||||
|
||||
if (targetBot == null) {
|
||||
@@ -82,7 +74,7 @@ public sealed class CommandController : ArchiController {
|
||||
command = command[commandPrefix.Length..];
|
||||
}
|
||||
|
||||
string? response = await targetBot.Commands.Response(steamOwnerID, command).ConfigureAwait(false);
|
||||
string? response = await targetBot.Commands.Response(EAccess.Owner, command).ConfigureAwait(false);
|
||||
|
||||
return Ok(new GenericResponse<string>(response));
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user