Compare commits

..

90 Commits

Author SHA1 Message Date
Archi
35364e46ca Closes #2972 2023-07-28 11:46:23 +02:00
ArchiBot
f2dae15562 Automatic translations update 2023-07-28 02:11:06 +00:00
ArchiBot
e71552645e Automatic translations update 2023-07-27 02:07:57 +00:00
renovate[bot]
acce99bf2e Update github/codeql-action action to v2.21.1 2023-07-26 19:23:14 +00:00
ArchiBot
dd14257116 Automatic translations update 2023-07-26 02:17:10 +00:00
Archi
68c17b0af9 Bump 2023-07-25 11:27:50 +02:00
Archi
556e1282a3 Misc fix 2023-07-25 11:26:22 +02:00
renovate[bot]
fd1b44cadc Update ASF-ui digest to 578e8ea 2023-07-25 04:00:12 +00:00
ArchiBot
9c18564830 Automatic translations update 2023-07-25 02:20:37 +00:00
Łukasz Domeradzki
97e8aece92 Update CONTRIBUTING.md 2023-07-25 00:17:47 +02:00
renovate[bot]
030ab53062 Update crowdin/github-action action to v1.12.0 2023-07-24 10:32:40 +00:00
renovate[bot]
2c0aa2a36c Update ASF-ui digest to b89ca92 2023-07-24 04:13:45 +00:00
ArchiBot
7a91e82a57 Automatic translations update 2023-07-24 02:15:15 +00:00
Łukasz Domeradzki
88d2924bc2 Update cc.sh 2023-07-23 12:25:14 +02:00
renovate[bot]
bae91cda04 Update ASF-ui digest to a00a24a 2023-07-23 03:35:12 +00:00
ArchiBot
173a0f18b9 Automatic translations update 2023-07-23 02:17:32 +00:00
Łukasz Domeradzki
0e8e360c7e Update cc.sh 2023-07-22 21:25:23 +02:00
renovate[bot]
afce39ca9c Update ASF-ui digest to d61d8aa 2023-07-22 09:15:32 +00:00
renovate[bot]
605897b7c5 Update ASF-ui digest to b04b006 2023-07-20 04:52:31 +00:00
ArchiBot
fc31027f9c Automatic translations update 2023-07-20 02:13:50 +00:00
renovate[bot]
48f1492aed Update github/codeql-action action to v2.21.0 2023-07-19 13:59:28 +00:00
renovate[bot]
7c9c92cced Update JetBrains/qodana-action action to v2023.2.1 2023-07-19 02:16:07 +00:00
renovate[bot]
abd9256026 Update ASF-ui digest to f02bd30 2023-07-18 07:11:00 +00:00
renovate[bot]
2a439e186a Update ASF-ui digest to 8ec6253 2023-07-17 04:18:33 +00:00
ArchiBot
60fd7d79d8 Automatic translations update 2023-07-16 02:31:22 +00:00
renovate[bot]
e1595719d8 Update ASF-ui digest to 3973226 2023-07-14 21:40:19 +00:00
renovate[bot]
5549481746 Update github/codeql-action action to v2.20.4 2023-07-14 17:41:07 +00:00
renovate[bot]
2a89cd781d Update mstest monorepo to v3.1.1 2023-07-14 10:55:29 +00:00
Archi
52ae995296 Bump 2023-07-13 22:59:45 +02:00
Archi
bceef4f74e Fix Abry potato server 2023-07-13 22:47:42 +02:00
Archi
49a64b75cf Closes #2952 2023-07-13 22:33:52 +02:00
renovate[bot]
0130fa9ee6 Update ASF-ui digest to fa3d8fc 2023-07-12 23:02:31 +00:00
renovate[bot]
29145d823b Update docker/setup-buildx-action action to v2.9.1 2023-07-12 14:24:14 +00:00
renovate[bot]
a4f16a0aa3 Update ASF-ui digest to f93d011 2023-07-10 07:55:13 +00:00
ArchiBot
7c4c82e980 Automatic translations update 2023-07-10 02:24:34 +00:00
ArchiBot
4f87744fd5 Automatic translations update 2023-07-09 02:29:01 +00:00
ArchiBot
a13f6cd23d Automatic translations update 2023-07-08 02:23:19 +00:00
renovate[bot]
a4f70c8ff4 Update ASF-ui digest to 369c14f 2023-07-07 18:18:34 +00:00
renovate[bot]
e72e894863 Update docker/setup-buildx-action action to v2.9.0 2023-07-07 11:47:37 +00:00
renovate[bot]
b4f747f990 Update ASF-ui digest to 81a232b 2023-07-07 07:14:54 +00:00
ArchiBot
a3122b9bd9 Automatic translations update 2023-07-07 02:23:44 +00:00
renovate[bot]
e935ec8bc4 Update ASF-ui digest to 9000bc1 2023-07-06 20:06:43 +00:00
renovate[bot]
421005c341 Update github/codeql-action action to v2.20.3 2023-07-06 14:08:41 +00:00
renovate[bot]
38c19510b5 Update actions/setup-node action to v3.7.0 2023-07-05 15:38:34 +00:00
renovate[bot]
88eaa3a745 Update dependency JetBrains.Annotations to v2023 (#2944)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-05 09:26:55 +02:00
ArchiBot
8d71433059 Automatic translations update 2023-07-05 02:23:34 +00:00
renovate[bot]
8cce153f0b Update dependency NLog.Web.AspNetCore to v5.3.2 2023-07-04 22:08:01 +00:00
renovate[bot]
9e32d4a00c Update ASF-ui digest to 1ff5f2a 2023-07-04 13:47:33 +00:00
ArchiBot
29fea78ee9 Automatic translations update 2023-07-04 02:23:50 +00:00
renovate[bot]
4a8260beef Update github/codeql-action action to v2.20.2 2023-07-03 12:31:21 +00:00
ArchiBot
4c73a6bc8b Automatic translations update 2023-07-03 02:23:45 +00:00
renovate[bot]
4361be279f Update ASF-ui digest to 9dd90cf 2023-07-02 04:16:48 +00:00
ArchiBot
970307b0e6 Automatic translations update 2023-07-02 02:27:22 +00:00
renovate[bot]
c908ebe192 Update dependency NLog.Web.AspNetCore to v5.3.1 2023-07-01 21:52:05 +00:00
renovate[bot]
b95c5cc584 Update ASF-ui digest to f0d7c48 2023-07-01 07:18:15 +00:00
ArchiBot
1034e7e625 Automatic translations update 2023-07-01 02:26:28 +00:00
Archi
3144bf2a98 Closes #2938 2023-06-30 10:44:29 +02:00
Archi
2ef341fc73 Misc 2023-06-30 10:30:01 +02:00
ArchiBot
b7b8c4bc1c Automatic translations update 2023-06-30 02:22:17 +00:00
renovate[bot]
7dd7e06e38 Update wiki digest to a1000c7 2023-06-29 22:36:03 +00:00
Archi
088fa2e9f9 Bump 2023-06-29 22:41:06 +02:00
Archi
3f91b18a4d Refactor confirmations
Make it so the design actually follows what Steam gives us now. There is no need for standalone Confirmation object anymore, rather re-use what Steam gives us. Optimize parsing type, expose it as public API. Small breaking change in HandleConfirmations() action.
2023-06-29 22:34:26 +02:00
Archi
d7722fae84 Misc code cleanup 2023-06-29 21:56:05 +02:00
ArchiBot
267f44ded0 Automatic translations update 2023-06-29 02:23:10 +00:00
renovate[bot]
cbb0ac7f4f Update ASF-ui digest to 94befd8 2023-06-28 21:25:44 +00:00
renovate[bot]
f8abcf9726 Update docker/setup-buildx-action action to v2.8.0 2023-06-28 16:34:53 +00:00
Chr_
7882f709d9 add checkout.steampowered.com to known service (#2934) 2023-06-28 13:22:35 +02:00
Ryzhehvost
003bf0e2b3 Allow plugins to override blacklisted trades (#2933) 2023-06-28 11:29:40 +02:00
renovate[bot]
1fbf8b7daf Update ASF-ui digest to 38cf6f6 2023-06-28 03:45:40 +00:00
ArchiBot
c30f7f9f0c Automatic translations update 2023-06-28 02:23:42 +00:00
renovate[bot]
4af9364109 Update dependency Microsoft.NET.Test.Sdk to v17.6.3 2023-06-27 13:46:08 +00:00
ArchiBot
7d0d8b5b43 Automatic translations update 2023-06-26 02:26:13 +00:00
Archi
5abe69162d Revert "Revert "Remove obsolete ICustomMachineInfoProvider interface""
This reverts commit 19ffe6e761.
2023-06-25 12:54:40 +02:00
Archi
549bd2f0be Revert "Back to 5.4.7.3 for a second"
This reverts commit 40a23e3c99.
2023-06-25 12:54:36 +02:00
Archi
40a23e3c99 Back to 5.4.7.3 for a second 2023-06-25 12:54:17 +02:00
Archi
19ffe6e761 Revert "Remove obsolete ICustomMachineInfoProvider interface"
This reverts commit 9d837c15b3.
2023-06-25 12:53:42 +02:00
Vincent Jansen
9e1ba20783 Fix for addlicense (#2927)
Fixing #2925 based on suggestions on that issue
2023-06-25 12:52:33 +02:00
renovate[bot]
cf70b5ff6c Update ASF-ui digest to 34e52e3 2023-06-25 04:19:47 +00:00
ArchiBot
9bbe4e73c6 Automatic translations update 2023-06-25 02:31:26 +00:00
renovate[bot]
1001d3ce49 Update ASF-ui digest to f86fb28 2023-06-24 22:38:32 +00:00
ArchiBot
aeffa85b87 Automatic translations update 2023-06-24 02:23:20 +00:00
Archi
9d837c15b3 Remove obsolete ICustomMachineInfoProvider interface 2023-06-23 12:22:57 +02:00
Archi
ae7793193d Bump 2023-06-23 12:20:57 +02:00
ArchiBot
5c8976313f Automatic translations update 2023-06-23 02:23:50 +00:00
Jack Nolddor
5e53073e8f Blacklist Summer Sale 2023 appid (#2923) 2023-06-22 16:38:10 +02:00
renovate[bot]
b06aac0024 Update ASF-ui digest to c56f3a3 2023-06-22 02:32:07 +00:00
ArchiBot
54a0857429 Automatic translations update 2023-06-22 02:19:28 +00:00
renovate[bot]
eac12de92e Update github/codeql-action action to v2.20.1 2023-06-21 12:44:12 +00:00
renovate[bot]
ad1ce5be9c Update JetBrains/qodana-action action to v2023.1.5 2023-06-21 11:13:39 +00:00
Archi
b99d7bc78f Bump 2023-06-21 13:13:21 +02:00
46 changed files with 953 additions and 316 deletions

View File

@@ -9,7 +9,7 @@ Before making an issue or pull request, you should carefully read **[ASF wiki](h
Examples of **invalid** issues:
- Asking how to install the program or use one of its functions
- Having technical difficulties running the program in some environment, encountering expected issues caused by the user's neglect
- Reporting problems that are not caused by ASF, such as ASF-ui issues or Steam not allowing you to log in
- Reporting problems that are not caused by ASF, such as ASF-ui issues or Steam not allowing you to send trade offers
- All issues encountered while running ASF in unsupported environment/setup, such as those with modified ASF source, having more bots than our maximum recommended limit or using custom plugins
- Other activities that are not related to ASF development in any way and do not require any development action from us

View File

@@ -39,7 +39,7 @@ jobs:
- name: Upload latest strings for translation on Crowdin
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.configuration == 'Release' && startsWith(matrix.os, 'ubuntu-') }}
uses: crowdin/github-action@v1.11.0
uses: crowdin/github-action@v1.12.0
with:
crowdin_branch_name: main
config: '.github/crowdin.yml'

View File

@@ -15,13 +15,13 @@ jobs:
uses: actions/checkout@v3.5.3
- name: Run Qodana scan
uses: JetBrains/qodana-action@v2023.1.4
uses: JetBrains/qodana-action@v2023.2.1
with:
args: --property=idea.headless.enable.statistics=false
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
- name: Report Qodana results to GitHub
uses: github/codeql-action/upload-sarif@v2.20.0
uses: github/codeql-action/upload-sarif@v2.21.1
with:
sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json

View File

@@ -22,7 +22,7 @@ jobs:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.7.0
uses: docker/setup-buildx-action@v2.9.1
- name: Build ${{ matrix.configuration }} Docker image from ${{ matrix.file }}
uses: docker/build-push-action@v4.1.1

View File

@@ -20,7 +20,7 @@ jobs:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.7.0
uses: docker/setup-buildx-action@v2.9.1
- name: Login to ghcr.io
uses: docker/login-action@v2.2.0

View File

@@ -21,7 +21,7 @@ jobs:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.7.0
uses: docker/setup-buildx-action@v2.9.1
- name: Login to ghcr.io
uses: docker/login-action@v2.2.0

View File

@@ -21,7 +21,7 @@ jobs:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2.7.0
uses: docker/setup-buildx-action@v2.9.1
- name: Login to ghcr.io
uses: docker/login-action@v2.2.0

View File

@@ -21,7 +21,7 @@ jobs:
submodules: recursive
- name: Setup Node.js with npm
uses: actions/setup-node@v3.6.0
uses: actions/setup-node@v3.7.0
with:
check-latest: true
node-version: ${{ env.NODE_JS_VERSION }}

View File

@@ -26,7 +26,7 @@ jobs:
git reset --hard origin/master
- name: Download latest translations from Crowdin
uses: crowdin/github-action@v1.11.0
uses: crowdin/github-action@v1.12.0
with:
upload_sources: false
download_translations: true

2
ASF-ui

Submodule ASF-ui updated: 0dc9b31a57...578e8eacf9

View File

@@ -44,6 +44,9 @@ internal class AssetForMatching {
[JsonProperty("p", Required = Required.Always)]
internal readonly Asset.EType Type;
[JsonConstructor]
protected AssetForMatching() { }
internal AssetForMatching(Asset asset) {
ArgumentNullException.ThrowIfNull(asset);
@@ -56,7 +59,4 @@ internal class AssetForMatching {
Type = asset.Type;
Rarity = asset.Rarity;
}
[JsonConstructor]
protected AssetForMatching() { }
}

View File

@@ -63,7 +63,7 @@
</value>
</resheader>
<data name="ActivelyMatchingItemsRound" xml:space="preserve">
<value>התאימו בסך הכל {0} ערכות בסיבוב זה.</value>
<value>הותאמו בסך הכל {0} ערכות בסיבוב זה.</value>
<comment>{0} will be replaced by number of sets traded</comment>
</data>
<data name="ListingAnnouncing" xml:space="preserve">
@@ -78,4 +78,8 @@
<value>נכשל שליחת הצעת סחר לבוט {0} ({1}), ממשיך הלאה...</value>
<comment>{0} will be replaced by steam ID (number), {1} will be replaced by user's nickname'</comment>
</data>
<data name="ActivelyMatchingSomeConfirmationsFailed" xml:space="preserve">
<value>חלק מהאישורים נכשלו, בערך {0} מתוך {1} עסקאות נשלחו בהצלחה.</value>
<comment>{0} will be replaced by amount of the trade offers that succeeded (number), {1} will be replaced by amount of the trade offers that were supposed to be sent in total (number)</comment>
</data>
</root>

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns="" id="root">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<data name="ActivelyMatchingItemsRound" xml:space="preserve">
<value>Matchet totalt {0} sett denne runden.</value>
<comment>{0} will be replaced by number of sets traded</comment>
</data>
<data name="ListingAnnouncing" xml:space="preserve">
<value>Kunngjør {0} ({1}) med inventar laget av totalt {2} gjenstander på oppføringen...</value>
<comment>{0} will be replaced by steam ID (number), {1} will be replaced by user's nickname, {2} will be replaced with number of items in the inventory</comment>
</data>
<data name="MatchingFound" xml:space="preserve">
<value>Matchet totalt {0} gjenstander med bot {1} ({2}), sender byttehandel...</value>
<comment>{0} will be replaced by number of items matched, {1} will be replaced by steam ID (number), {2} will be replaced by user's nickname</comment>
</data>
<data name="TradeOfferFailed" xml:space="preserve">
<value>Kunne ikke sende en byttehandel til bot {0}({1}), fortsetter...</value>
<comment>{0} will be replaced by steam ID (number), {1} will be replaced by user's nickname'</comment>
</data>
<data name="ActivelyMatchingSomeConfirmationsFailed" xml:space="preserve">
<value>Noen bekreftelser har mislyktes, ca {0} av {1} byttehandler ble sendt.</value>
<comment>{0} will be replaced by amount of the trade offers that succeeded (number), {1} will be replaced by amount of the trade offers that were supposed to be sent in total (number)</comment>
</data>
</root>

View File

@@ -37,7 +37,6 @@ using ArchiSteamFarm.Steam.Cards;
using ArchiSteamFarm.Steam.Data;
using ArchiSteamFarm.Steam.Exchange;
using ArchiSteamFarm.Steam.Integration;
using ArchiSteamFarm.Steam.Security;
using ArchiSteamFarm.Steam.Storage;
using ArchiSteamFarm.Storage;
using ArchiSteamFarm.Web;
@@ -990,7 +989,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable {
pendingMobileTradeOfferIDs.UnionWith(mobileTradeOfferIDs);
if (pendingMobileTradeOfferIDs.Count >= MaxTradeOffersActive) {
(bool twoFactorSuccess, IReadOnlyCollection<Confirmation>? handledConfirmations, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EType.Trade, pendingMobileTradeOfferIDs, true).ConfigureAwait(false);
(bool twoFactorSuccess, IReadOnlyCollection<Confirmation>? handledConfirmations, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EConfirmationType.Trade, pendingMobileTradeOfferIDs, true).ConfigureAwait(false);
if (!twoFactorSuccess) {
Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Localization.Strings.ActivelyMatchingSomeConfirmationsFailed, handledConfirmations?.Count ?? 0, pendingMobileTradeOfferIDs.Count));
@@ -1086,7 +1085,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable {
}
if (pendingMobileTradeOfferIDs.Count > 0) {
(bool twoFactorSuccess, IReadOnlyCollection<Confirmation>? handledConfirmations, _) = Bot.IsConnectedAndLoggedOn ? await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EType.Trade, pendingMobileTradeOfferIDs, true).ConfigureAwait(false) : (false, null, null);
(bool twoFactorSuccess, IReadOnlyCollection<Confirmation>? handledConfirmations, _) = Bot.IsConnectedAndLoggedOn ? await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EConfirmationType.Trade, pendingMobileTradeOfferIDs, true).ConfigureAwait(false) : (false, null, null);
if (!twoFactorSuccess) {
Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Localization.Strings.ActivelyMatchingSomeConfirmationsFailed, handledConfirmations?.Count ?? 0, pendingMobileTradeOfferIDs.Count));

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns="" id="root">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
</root>

View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns="" id="root">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
</root>

View File

@@ -165,12 +165,12 @@
<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>
<value>STD genel önbelleği yükleniyor...</value>
</data>
<data name="ValidatingGlobalCacheIntegrity" xml:space="preserve">
<value>STD küresel önbellek bütünlüğü doğrulanıyor...</value>
<value>STD genel önbellek bütünlüğü doğrulama...</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>
<value>STD genel önbellek bütünlüğü doğrulanamadı. Bu, olası bir dosya / bellek bozulmasına işaret eder, bunun yerine yeni bir örnek başlatılır.</value>
</data>
</root>

View File

@@ -195,6 +195,9 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotC
}
if (BotSynchronizations.TryRemove(bot, out (SemaphoreSlim RefreshSemaphore, Timer RefreshTimer) synchronization)) {
// Ensure the semaphore is empty, otherwise we're risking disposed exceptions
await synchronization.RefreshSemaphore.WaitAsync().ConfigureAwait(false);
synchronization.RefreshSemaphore.Dispose();
await synchronization.RefreshTimer.DisposeAsync().ConfigureAwait(false);

View File

@@ -33,6 +33,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMethodOrOperatorBody/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMissingParentheses/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeNamespaceBody/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeNullCheckingPattern/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeObjectCreationWhenTypeNotEvident/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeStaticMemberQualifier/@EntryIndexedValue">SUGGESTION</s:String>
@@ -188,6 +189,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceLockStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceWhileStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ExtractCommonPropertyPattern/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FunctionComplexityOverflow/@EntryIndexedValue">HINT</s:String>
@@ -210,6 +212,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBePartlyConvertedToQuery/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MarkupAttributeTypo/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MarkupTextTypo/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeFileLocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeInternal/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002EGlobal/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002ELocal/@EntryIndexedValue">SUGGESTION</s:String>
@@ -241,6 +244,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PassStringInterpolation/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PatternAlwaysMatches/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PatternAlwaysOfType/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PlaceAssignmentExpressionIntoBlock/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PropertyNotResolved/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantArrayCreationExpression/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantAttributeParentheses/@EntryIndexedValue">SUGGESTION</s:String>
@@ -269,6 +273,11 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceSubstringWithRangeIndexer/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReturnTypeCanBeEnumerable_002EGlobal/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReturnTypeCanBeEnumerable_002ELocal/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RouteTemplates_002EActionRoutePrefixCanBeExtractedToControllerRoute/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RouteTemplates_002EControllerRouteParameterIsNotPassedToMethods/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RouteTemplates_002EMethodMissingRouteParameters/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RouteTemplates_002EParameterConstraintCanBeSpecified/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RouteTemplates_002ERouteParameterIsNotPassedToMethod/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SeparateControlTransferStatement/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SimilarAnonymousTypeNearby/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SpecifyStringComparison/@EntryIndexedValue">SUGGESTION</s:String>

View File

@@ -441,7 +441,8 @@ public static class ASF {
LoginSemaphore ??= await PluginsCore.GetCrossProcessSemaphore(nameof(LoginSemaphore)).ConfigureAwait(false);
RateLimitingSemaphore ??= await PluginsCore.GetCrossProcessSemaphore(nameof(RateLimitingSemaphore)).ConfigureAwait(false);
WebLimitingSemaphores ??= new Dictionary<Uri, (ICrossProcessSemaphore RateLimitingSemaphore, SemaphoreSlim OpenConnectionsSemaphore)>(4) {
WebLimitingSemaphores ??= new Dictionary<Uri, (ICrossProcessSemaphore RateLimitingSemaphore, SemaphoreSlim OpenConnectionsSemaphore)>(5) {
{ ArchiWebHandler.SteamCheckoutURL, (await PluginsCore.GetCrossProcessSemaphore($"{nameof(ArchiWebHandler)}-{nameof(ArchiWebHandler.SteamCheckoutURL)}").ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ ArchiWebHandler.SteamCommunityURL, (await PluginsCore.GetCrossProcessSemaphore($"{nameof(ArchiWebHandler)}-{nameof(ArchiWebHandler.SteamCommunityURL)}").ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ ArchiWebHandler.SteamHelpURL, (await PluginsCore.GetCrossProcessSemaphore($"{nameof(ArchiWebHandler)}-{nameof(ArchiWebHandler.SteamHelpURL)}").ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },
{ ArchiWebHandler.SteamStoreURL, (await PluginsCore.GetCrossProcessSemaphore($"{nameof(ArchiWebHandler)}-{nameof(ArchiWebHandler.SteamStoreURL)}").ConfigureAwait(false), new SemaphoreSlim(WebBrowser.MaxConnections, WebBrowser.MaxConnections)) },

View File

@@ -356,8 +356,8 @@ public static class Utilities {
HashSet<DictionaryEntry> defaultStringObjects = defaultResourceSet.Cast<DictionaryEntry>().ToHashSet();
if (defaultStringObjects.Count == 0) {
ASF.ArchiLogger.LogNullError(defaultStringObjects);
// This means we don't have entries for English, so there is nothing to check against
// Can happen e.g. for plugins with no strings declared which are calling this function
return;
}

View File

@@ -30,6 +30,7 @@ using ArchiSteamFarm.IPC.Requests;
using ArchiSteamFarm.IPC.Responses;
using ArchiSteamFarm.Localization;
using ArchiSteamFarm.Steam;
using ArchiSteamFarm.Steam.Data;
using ArchiSteamFarm.Steam.Security;
using Microsoft.AspNetCore.Mvc;
@@ -51,7 +52,7 @@ public sealed class TwoFactorAuthenticationController : ArchiController {
ArgumentNullException.ThrowIfNull(request);
if (request.AcceptedType.HasValue && ((request.AcceptedType.Value == Confirmation.EType.Unknown) || !Enum.IsDefined(request.AcceptedType.Value))) {
if (request.AcceptedType.HasValue && ((request.AcceptedType.Value == Confirmation.EConfirmationType.Unknown) || !Enum.IsDefined(request.AcceptedType.Value))) {
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(request.AcceptedType))));
}

View File

@@ -27,7 +27,7 @@ using System.Globalization;
using System.Linq;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.Localization;
using ArchiSteamFarm.Steam.Security;
using ArchiSteamFarm.Steam.Data;
using Newtonsoft.Json;
namespace ArchiSteamFarm.IPC.Requests;
@@ -50,7 +50,7 @@ public sealed class TwoFactorAuthenticationConfirmationsRequest {
/// Specifies the type of confirmations to handle. If not provided, all confirmation types are considered for an action.
/// </summary>
[JsonProperty]
public Confirmation.EType? AcceptedType { get; private set; }
public Confirmation.EConfirmationType? AcceptedType { get; private set; }
/// <summary>
/// A helper property which works the same as <see cref="AcceptedCreatorIDs" /> but with values written as strings - for javascript compatibility purposes. Use either this one, or <see cref="AcceptedCreatorIDs" />, not both.

View File

@@ -190,7 +190,10 @@ StackTrace:
<value>Místní verze: {0} | Vzdálená verze: {1}</value>
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
<data name="UserInputDeviceConfirmation" xml:space="preserve">
<value>Prosím zkontrolujte svou mobilní aplikaci Steam, měli byste dostat oznámení o schválení přihlášení. Napiště Y pokud jste dostali a potvrdili oznámení, N pokud místo toho chcete vypsat přihlašovací kód: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteam2FA" xml:space="preserve">
<value>Zadejte váš 2FA kód z aplikace Steam: </value>
<comment>Please note that this translation should end with space</comment>

View File

@@ -304,7 +304,10 @@ StackTrace:
<value>Stoppede med at idle: {0} ({1})</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StoppedIdlingList" xml:space="preserve">
<value>Stoppede med at farme: {0}</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
</data>
<data name="UnknownCommand" xml:space="preserve">
<value>Ukendt kommando!</value>
</data>

View File

@@ -97,7 +97,7 @@ StackTrace:
<comment>{0} will be replaced by URL of the request</comment>
</data>
<data name="ErrorGlobalConfigNotLoaded" xml:space="preserve">
<value>לא ניתן לטעון תצורה גלובלית. נא ודאו כי {0} קיים ותקין! ניתן לפנות למדריך ההגדרה ב-wiki להסבר נוסף.</value>
<value>לא ניתן לטעון config גלובלי. נא ודא כי {0} קיים ותקין! ניתן לפנות למדריך ההגדרה ב-wiki להסבר נוסף.</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorIsInvalid" xml:space="preserve">
@@ -138,10 +138,10 @@ StackTrace:
<value>נכשל!</value>
</data>
<data name="GlobalConfigChanged" xml:space="preserve">
<value>קובץ תצורה גלובלית השתנה!</value>
<value>קובץ config גלובלי השתנה!</value>
</data>
<data name="ErrorGlobalConfigRemoved" xml:space="preserve">
<value>קובץ תצורה גלובלית הוסר!</value>
<value>קובץ config גלובלי הוסר!</value>
</data>
<data name="IgnoringTrade" xml:space="preserve">
<value>מתעלם מעסקת חליפין: {0}</value>
@@ -190,7 +190,10 @@ StackTrace:
<value>גירסה מקומית: {0} | הגירסה המרוחקת: {1}</value>
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
<data name="UserInputDeviceConfirmation" xml:space="preserve">
<value>אנא בדוק את אפליקציית Steam שלך, אתה אמור לקבל התראה להרשאת התחברות. לחץ Y אם קיבלת ואישרת את ההתראה, N אם אתה רוצה לספק קוד במקום: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteam2FA" xml:space="preserve">
<value>אנא הכנס את קוד האימות מאפליקציית המאמת של Steam: </value>
<comment>Please note that this translation should end with space</comment>
@@ -203,7 +206,10 @@ StackTrace:
<value>נא הזינו את משתמש ה- Steam שלכם: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamParentalCode" xml:space="preserve">
<value>הזן בבקשה קוד הורים של Steam: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamPassword" xml:space="preserve">
<value>אנא הקישו את הסיסמה הנוכחית שלכם: </value>
<comment>Please note that this translation should end with space</comment>
@@ -225,38 +231,86 @@ StackTrace:
<value>לא ניתן למצוא אף בוט בשם {0}!</value>
<comment>{0} will be replaced by bot's name query (string)</comment>
</data>
<data name="BotStatusOverview" xml:space="preserve">
<value>{1}/{0} בוטים רצים כרגע, {2} משחקים ({3} קלפים) נותרו להרצה.</value>
<comment>{0} will be replaced by number of active bots, {1} will be replaced by total number of bots, {2} will be replaced by total number of games left to farm, {3} will be replaced by total number of cards left to farm</comment>
</data>
<data name="BotStatusIdling" xml:space="preserve">
<value>הבוט מריץ את המשחק: {0} ({1}, {2} קלפים נותרו להשגה) מתוך {3} משחקים ({4} קלפים) שנותרו להרצה ({5}~ נותרו).</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to farm, {3} will be replaced by total number of games to farm, {4} will be replaced by total number of cards to farm, {5} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
</data>
<data name="BotStatusIdlingList" xml:space="preserve">
<value>הבוט מריץ את המשחקים: {0} מתוך סך כולל של {1} משחקים ({2} קלפים) שנותרו להרצה ({3}~ נותרו).</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), {1} will be replaced by total number of games to farm, {2} will be replaced by total number of cards to farm, {3} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
</data>
<data name="CheckingFirstBadgePage" xml:space="preserve">
<value>בודק עמוד תגים ראשון...</value>
</data>
<data name="CheckingOtherBadgePages" xml:space="preserve">
<value>בודק עמודי תגים אחרים...</value>
</data>
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
<value>אלגוריתם הרצה שנבחר: {0}</value>
<comment>{0} will be replaced by the name of chosen farming algorithm</comment>
</data>
<data name="Done" xml:space="preserve">
<value>הושלם!</value>
</data>
<data name="GamesToIdle" xml:space="preserve">
<value>נותרו {0} משחקים ({1} קלפים) להרצה ({2}~ נותרו)...</value>
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
</data>
<data name="IdlingFinished" xml:space="preserve">
<value>ההרצה הסתיימה!</value>
</data>
<data name="IdlingFinishedForGame" xml:space="preserve">
<value>ההרצה הסתיימה עבור: {0} ({1}) לאחר {2} של זמן משחק!</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string (such as "1 day, 5 hours and 30 minutes")</comment>
</data>
<data name="IdlingFinishedForGames" xml:space="preserve">
<value>הרצת המשחקים התסיימה עבור: {0}</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
</data>
<data name="IdlingStatusForGame" xml:space="preserve">
<value>סטטוס ההרצה של {0} ({1}): {2} קלפים נותרו</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to farm</comment>
</data>
<data name="IdlingStopped" xml:space="preserve">
<value>הרצה נעצרה!</value>
</data>
<data name="IgnoredPermanentPauseEnabled" xml:space="preserve">
<value>מתעלם מבקשה זו, כיוון שהשהיה תמידית פועלת!</value>
</data>
<data name="NothingToIdle" xml:space="preserve">
<value>אין לנו מה להריץ על החשבון הזה!</value>
</data>
<data name="NowIdling" xml:space="preserve">
<value>עכשיו מריץ: {0} ({1})</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="NowIdlingList" xml:space="preserve">
<value>עכשיו מריץ: {0}</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
</data>
<data name="PlayingNotAvailable" xml:space="preserve">
<value>האפשרות לשחק אינה זמינה כעת. ננסה מאוחר יותר!</value>
</data>
<data name="StillIdling" xml:space="preserve">
<value>עדיין מריץ: {0} ({1})</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StillIdlingList" xml:space="preserve">
<value>עדיין מריץ: {0}</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
</data>
<data name="StoppedIdling" xml:space="preserve">
<value>נעצרה ההרצה: {0} ({1})</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StoppedIdlingList" xml:space="preserve">
<value>נעצרה ההרצה: {0}</value>
<comment>{0} will be replaced by list of the games (IDs, numbers), separated by a comma</comment>
</data>
<data name="UnknownCommand" xml:space="preserve">
<value>פקודה לא מוכרת!</value>
</data>
@@ -271,7 +325,9 @@ StackTrace:
<value>מאשר מתנה: {0}...</value>
<comment>{0} will be replaced by giftID (number)</comment>
</data>
<data name="BotAccountLimited" xml:space="preserve">
<value>החשבון הזה מוגבל, תהליך ההרצה לא יתאפשר עד להסרת ההגבלה!</value>
</data>
<data name="BotAddLicense" xml:space="preserve">
<value>מזהה: {0} | סטטוס: {1}</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by status string</comment>
@@ -317,7 +373,10 @@ StackTrace:
<data name="BotInstanceNotStartingBecauseDisabled" xml:space="preserve">
<value>לא מריץ את הבוט הזה כי הוא אינו מופעל בקובץ ההגדרה!</value>
</data>
<data name="BotInvalidAuthenticatorDuringLogin" xml:space="preserve">
<value>התקבל קוד שגיאה TwoFactorCodeMismatch מספר של {0} פעמים ברציפות. או שפרטי האימות הדו שלבי שהכנסת לא תקפים, או שהזמן שלך לא מסונכרן, מפיל!</value>
<comment>{0} will be replaced by maximum allowed number of failed 2FA attempts</comment>
</data>
<data name="BotLoggedOff" xml:space="preserve">
<value>ניתוק מסטים: {0}</value>
<comment>{0} will be replaced by logging off reason (string)</comment>
@@ -358,7 +417,10 @@ StackTrace:
<value>בבעלותך כבר: {0} | {1}</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="BotPointsBalance" xml:space="preserve">
<value>יתרת נקודות: {0}</value>
<comment>{0} will be replaced by the points balance value (integer)</comment>
</data>
<data name="BotRateLimitExceeded" xml:space="preserve">
<value>חרגת מגבלת התעריפים, ננסה שוב לאחר {0} שניות/דקות...</value>
<comment>{0} will be replaced by translated TimeSpan string (such as "25 minutes")</comment>
@@ -377,8 +439,12 @@ StackTrace:
<data name="BotRemovedExpiredLoginKey" xml:space="preserve">
<value>הוסר מפתח התחברות שתוקפו פג!</value>
</data>
<data name="BotStatusNotIdling" xml:space="preserve">
<value>הבוט לא מריץ דבר.</value>
</data>
<data name="BotStatusLimited" xml:space="preserve">
<value>הבוט מוגבל ולא יכול להפיק קלפים דרך הרצה.</value>
</data>
<data name="BotStatusConnecting" xml:space="preserve">
<value>הבוט מתחבר לרשת Steam.</value>
</data>
@@ -410,8 +476,12 @@ StackTrace:
<data name="BotConnectionLost" xml:space="preserve">
<value>החיבור לרשת Steam אבד. מתחבר מחדש...</value>
</data>
<data name="BotAccountFree" xml:space="preserve">
<value>החשבון כבר לא תפוס: תהליך ההרצה התחדש!</value>
</data>
<data name="BotAccountOccupied" xml:space="preserve">
<value>החשבון נמצא בשימוש כעת: ASF ימשיך את תהליך ההרצה ברגע שהוא יתפנה...</value>
</data>
<data name="BotConnecting" xml:space="preserve">
<value>מתחבר...</value>
</data>
@@ -445,8 +515,14 @@ StackTrace:
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>ה- CurrentCulture המסופק שלך אינו חוקי, ASF ימשיך לפעול עם אפשרות ברירת המחדל!</value>
</data>
<data name="TranslationIncomplete" xml:space="preserve">
<value>ASF ינסה להשתמש בתרבות {0} המועדפת עליך, אך התרגום לשפה זו הושלם רק ב-{1}. אולי תוכל לעזור לנו לשפר את תרגום ה-ASF עבור השפה שלך?</value>
<comment>{0} will be replaced by culture code, such as "en-US", {1} will be replaced by completeness percentage, such as "78.5%"</comment>
</data>
<data name="IdlingGameNotPossible" xml:space="preserve">
<value>ההרצה {0} ({1}) הושבתה באופן זמני, משום ש-ASF לא מסוגל להריץ את משחק זה כרגע.</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name</comment>
</data>
<data name="WarningIdlingGameMismatch" xml:space="preserve">
<value>ASF זיהה חוסר התאמה של מזהה עבור {0} ({1}) והשתמש במזהה {2} במקום זאת.</value>
<comment>{0} will be replaced by game's ID (number), {1} will be replaced by game's name, {2} will be replaced by game's ID (number)</comment>
@@ -455,8 +531,12 @@ StackTrace:
<value>{0} גרסה {1}</value>
<comment>{0} will be replaced by program's name (e.g. "ASF"), {1} will be replaced by program's version (e.g. "1.0.0.0"). This string typically has nothing to translate and you should leave it as it is, unless you need to change the format, e.g. in RTL languages.</comment>
</data>
<data name="BotAccountLocked" xml:space="preserve">
<value>חשבון זה נעול, תהליך ההרצה אינו זמין לצמיתות!</value>
</data>
<data name="BotStatusLocked" xml:space="preserve">
<value>הבוט נעול ולכן לא יכול להפיק קלפים כלל דרך הרצה.</value>
</data>
<data name="ErrorFunctionOnlyInHeadlessMode" xml:space="preserve">
<value>פונקציה זו זמינה רק במצב ללא ראש!</value>
</data>
@@ -467,8 +547,14 @@ StackTrace:
<data name="ErrorAccessDenied" xml:space="preserve">
<value>הגישה נדחתה!</value>
</data>
<data name="WarningPreReleaseVersion" xml:space="preserve">
<value>אתה משתמש בגירסה חדשה יותר מאשר הגירסה הזמינה. אנא שים לב כי גירסאות קדם הפצה נועדו עבור משתמשים אשר יודעים כיצד לדווח על באגים, להתמודד עם בעיות ולתת משוב - תמיכה טכנית לא תינתן.</value>
</data>
<data name="BotStats" xml:space="preserve">
<value>זיכרון שנמצא בשימוש: {0} מגה בייטים.
זמן פעילות התהליך: {1}</value>
<comment>{0} will be replaced by number (in megabytes) of memory being used, {1} will be replaced by translated TimeSpan string (such as "25 minutes"). Please note that this string should include newlines for formatting.</comment>
</data>
<data name="ClearingDiscoveryQueue" xml:space="preserve">
<value>ניקוי תור גילוי סטים #{0}...</value>
<comment>{0} will be replaced by queue number</comment>
@@ -496,7 +582,9 @@ StackTrace:
<value>הדרך לעקיפת הבעיה עבור {0} באגים הופעלה.</value>
<comment>{0} will be replaced by the bug's name provided by ASF</comment>
</data>
<data name="TargetBotNotConnected" xml:space="preserve">
<value>מופע בוט זה לא מחובר!</value>
</data>
<data name="BotWalletBalance" xml:space="preserve">
<value>יתרה בארנק: {1}{0}</value>
<comment>{0} will be replaced by wallet balance value, {1} will be replaced by currency name</comment>
@@ -508,12 +596,21 @@ StackTrace:
<value>לבוט יש רמה {0}.</value>
<comment>{0} will be replaced by bot's level</comment>
</data>
<data name="ActivelyMatchingItems" xml:space="preserve">
<value>מתאים פריטי Steam, שלב #{0}...</value>
<comment>{0} will be replaced by round number</comment>
</data>
<data name="DoneActivelyMatchingItems" xml:space="preserve">
<value>הסתיימה ההתאמה של פריטי Steam, שלב #{0}.</value>
<comment>{0} will be replaced by round number</comment>
</data>
<data name="ErrorAborted" xml:space="preserve">
<value>הופסק!</value>
</data>
<data name="WarningExcessiveBotsCount" xml:space="preserve">
<value>אתה מפעיל יותר חשבונות בוטים אישיים מהמגבלה העליונה המומלצת שלנו ({0}). שים לב שהגדרה זו אינה נתמכת ועלולה לגרום לבעיות שונות הקשורות ל-Steam, כולל השעיית חשבון. עיין בשאלות הנפוצות לפרטים נוספים.</value>
<comment>{0} will be replaced by our maximum recommended bots count (number)</comment>
</data>
<data name="PluginLoaded" xml:space="preserve">
<value>{0} נטען בהצלחה!</value>
<comment>{0} will be replaced by the name of the custom ASF plugin</comment>
@@ -525,52 +622,130 @@ StackTrace:
<data name="NothingFound" xml:space="preserve">
<value>לא נמצא דבר!</value>
</data>
<data name="PluginsWarning" xml:space="preserve">
<value>טענת תוספים מותאמים אישית אחד או מרובים ל-ASF. מכיוון שאיננו יכולים להציע תמיכה עבור הגדרות מופרדות, אנא צור קשר עם המפתחים המתאימים של הפלאגינים שבהם החלטת להשתמש בכל מקרה של בעיות.</value>
</data>
<data name="PleaseWait" xml:space="preserve">
<value>אנא המתן...</value>
</data>
<data name="EnterCommand" xml:space="preserve">
<value>הקש פקודה: </value>
</data>
<data name="Executing" xml:space="preserve">
<value>מבצע...</value>
</data>
<data name="InteractiveConsoleEnabled" xml:space="preserve">
<value>המסוף האינטראקטיבי פעיל כעת, הקלד 'c' כדי להיכנס למצב פקודה.</value>
</data>
<data name="BotGamesToRedeemInBackgroundCount" xml:space="preserve">
<value>לבוט נותרו {0} משחקים בתור ברקע.</value>
<comment>{0} will be replaced by remaining number of games in BGR's queue</comment>
</data>
<data name="ErrorSingleInstanceRequired" xml:space="preserve">
<value>תהליך ASF כבר פועל עבור ספריית העבודה הזו, מפיל!</value>
</data>
<data name="BotHandledConfirmations" xml:space="preserve">
<value>טופלו בהצלחה {0} אישורים!</value>
<comment>{0} will be replaced by number of confirmations</comment>
</data>
<data name="BotExtraIdlingCooldown" xml:space="preserve">
<value>ממתין עד {0} כדי להבטיח שאנו חופשיים להתחיל בהרצה...</value>
<comment>{0} will be replaced by translated TimeSpan string (such as "1 minute")</comment>
</data>
<data name="UpdateCleanup" xml:space="preserve">
<value>מנקה קבצים ישנים לאחר עדכון...</value>
</data>
<data name="BotGeneratingSteamParentalCode" xml:space="preserve">
<value>יוצר קוד הורים של Steam, זה יכול לקחת זמן מה, שקול לשים אותו ב-config במקום...</value>
</data>
<data name="IPCConfigChanged" xml:space="preserve">
<value>תצורת IPC השתנתה!</value>
</data>
<data name="BotTradeOfferResult" xml:space="preserve">
<value>הצעת המסחר {0} נקבעה להיות {1} בשל {2}.</value>
<comment>{0} will be replaced by trade offer ID (number), {1} will be replaced by internal ASF enum name, {2} will be replaced by technical reason why the trade was determined to be in this state</comment>
</data>
<data name="BotInvalidPasswordDuringLogin" xml:space="preserve">
<value>התקבל קוד שגיאה InvalidPassword מספר של {0} פעמים ברציפות. סביר להניח שהסיסמה שלך לחשבון זה שגויה, מפיל!</value>
<comment>{0} will be replaced by maximum allowed number of failed login attempts</comment>
</data>
<data name="Result" xml:space="preserve">
<value>תוצאה: {0}</value>
<comment>{0} will be replaced by generic result of various functions that use this string</comment>
</data>
<data name="WarningUnsupportedEnvironment" xml:space="preserve">
<value>אתה מנסה להפעיל {0} גרסה של ASF בסביבה לא נתמכת: {1}. ספק --התעלם מ-unsupported-environment argument אם אתה באמת יודע מה אתה עושה.</value>
</data>
<data name="WarningUnknownCommandLineArgument" xml:space="preserve">
<value>שורת פקודה לא ידועה: {0}</value>
<comment>{0} will be replaced by unrecognized command that has been provided</comment>
</data>
<data name="ErrorConfigDirectoryNotFound" xml:space="preserve">
<value>לא ניתן לאתר את תיקיית ה-config, מפיל!</value>
</data>
<data name="BotIdlingSelectedGames" xml:space="preserve">
<value>משחק בבחירה {0}: {1}</value>
<comment>{0} will be replaced by internal name of the config property (e.g. "GamesPlayedWhileIdle"), {1} will be replaced by comma-separated list of appIDs that user has chosen</comment>
</data>
<data name="AutomaticFileMigration" xml:space="preserve">
<value>קובץ ה-config שמיקומו {0} יועבר לתחביר העדכני ביותר...</value>
<comment>{0} will be replaced with the relative path to the affected config file</comment>
</data>
<data name="WarningWeakIPCPassword" xml:space="preserve">
<value>נראה שסיסמת ה-IPC שלך חלשה. שקול לבחור חזק יותר להגברת האבטחה. פרטים: {0}</value>
<comment>{0} will be replaced by additional details about the password being considered weak</comment>
</data>
<data name="WarningWeakSteamPassword" xml:space="preserve">
<value>נראה שהסיסמה שלך ב-Steam עבור '{0}' חלשה. שקול לבחור חזק יותר להגברת האבטחה. פרטים: {1}</value>
<comment>{0} will be replaced by the affected bot name, {1} will be replaced by additional details about the password being considered weak</comment>
</data>
<data name="WarningWeakCryptKey" xml:space="preserve">
<value>מפתח ההצפנה שלך נראה חלש. שקול לבחור חזק יותר להגברת האבטחה. פרטים: {0}</value>
<comment>{0} will be replaced by additional details about the encryption key being considered weak</comment>
</data>
<data name="WarningTooShortCryptKey" xml:space="preserve">
<value>מפתח ההצפנה שלך קצר מדי. אנו ממליצים להשתמש באחד שאורכו לפחות {0} בייטים (תווים).</value>
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
</data>
<data name="WarningDefaultCryptKeyUsedForHashing" xml:space="preserve">
<value>אתה משתמש בהגדרה {0} של המאפיין {1}, אך לא סיפקת --cryptkey מותאם אישית. עליך לספק --cryptkey מותאם אישית להגברת האבטחה.</value>
<comment>{0} will be replaced by the name of a particular setting (e.g. "SCrypt"), {1} will be replaced by the name of the property (e.g. "IPCPassword")</comment>
</data>
<data name="WarningDefaultCryptKeyUsedForEncryption" xml:space="preserve">
<value>אתה משתמש בהגדרה {0} של המאפיין {1}, אך לא סיפקת --cryptkey מותאם אישית. זה מביס לחלוטין את ההגנה, מכיוון ש-ASF נאלץ להשתמש במפתח (ידוע) משלו. עליך לספק --cryptkey מותאם אישית כדי לעשות שימוש בהטבת האבטחה שמציעה הגדרה זו.</value>
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
</data>
<data name="WarningRunningAsRoot" xml:space="preserve">
<value>אתה מנסה להפעיל את ASF כמנהל המערכת (שורש). זה גורם לסיכון אבטחה משמעותי למחשב שלך, ומכיוון ש-ASF אינו דורש גישת שורש לצורך פעולתו, אנו ממליצים להפעיל אותו כמשתמש שאינו מנהל במידת האפשר.</value>
</data>
<data name="WarningRunningInUnsupportedEnvironment" xml:space="preserve">
<value>אתה מפעיל את ASF בסביבה לא נתמכת, מספק ארגומנט --ignore-unsupported-environment. שים לב שאיננו מציעים כל סוג של תמיכה בתרחיש זה ואתה עושה זאת על אחריותך בלבד. הוזהרת.</value>
</data>
<data name="FetchingChecksumFromRemoteServer" xml:space="preserve">
<value>מביא checksum מהשרת המרוחק...</value>
</data>
<data name="VerifyingChecksumWithRemoteServer" xml:space="preserve">
<value>מאמת את ה-checksum של הקובץ הבינארי שהורד מול זה מהשרת המרוחק...</value>
</data>
<data name="ChecksumMissing" xml:space="preserve">
<value>השרת המרוחק לא יודע כלום על המהדורה שאליה אנחנו מעדכנים. מצב זה אפשרי אם המהדורה פורסמה לאחרונה - מסרב להמשיך בהליך העדכון באופן מיידי כאמצעי אבטחה נוסף.</value>
</data>
<data name="ChecksumWrong" xml:space="preserve">
<value>שרת מרוחק השיב עם סכום ביקורת אחר, זה עשוי להצביע על הורדה פגומה או התקפת MITM, מסרב להמשיך בהליך העדכון!</value>
</data>
<data name="PatchingFiles" xml:space="preserve">
<value>בונה קבצי ASF...</value>
</data>
<data name="UserInputCryptkey" xml:space="preserve">
<value>נא הכנס את המפתח הקריפטוגרפי שלך: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="ErrorIPNotBanned" xml:space="preserve">
<value>כתובת IP זו {0} לא חסומה!</value>
<comment>{0} will be replaced by an IP address which was requested to be unbanned from using IPC</comment>
</data>
<data name="WarningNoLicense" xml:space="preserve">
<value>ניסית להשתמש בתכונה בתשלום {0} אך אין לך מזהה רישיון חוקי שהוגדר בתצורה הגלובלית של ASF. אנא בדוק את התצורה שלך, מכיוון שהפונקציונליות לא תעבוד ללא פרטים נוספים.</value>
<comment>{0} will be replaced by feature name (e.g. MatchActively)</comment>
</data>
</root>

View File

@@ -62,6 +62,14 @@
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<data name="AcceptingTrade" xml:space="preserve">
<value>შემოთავაზების მიღება {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="AutoUpdateCheckInfo" xml:space="preserve">
<value>ASF ავტომატურად შემოწმედბა ახალ ვერსიისთვის ყველა {0}-ში.</value>
<comment>{0} will be replaced by translated TimeSpan string (such as "24 hours")</comment>
</data>
@@ -78,10 +86,12 @@
<data name="Exiting" xml:space="preserve">
<value>გამოსვლა...</value>
</data>
<data name="WarningFailed" xml:space="preserve">
<value>ვერ მოხერხდა!</value>
</data>

View File

@@ -190,7 +190,10 @@ StackTrace:
<value>Vietinė versija: {0} | Versija serveryje: {1}</value>
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
<data name="UserInputDeviceConfirmation" xml:space="preserve">
<value>Patikrinkite jūsų Steam programėlę telefone, jūs turėjote gauti prisijungimo patvirtinimo pranešima. Parašykite Y jei jūs gavote ir patvirtinote pranešimą, N jei jūs norite pateikti kodą vietoje patvirtinimo pranešimo: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteam2FA" xml:space="preserve">
<value>Prašome įvesti 2FA kodą iš jūsų Steam autentifikavimo programėlės: </value>
<comment>Please note that this translation should end with space</comment>

View File

@@ -0,0 +1,281 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns="" id="root">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<data name="AcceptingTrade" xml:space="preserve">
<value>Godtar handel: {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="AutoUpdateCheckInfo" xml:space="preserve">
<value>ASF vil automatisk se etter nye versjoner hver {0}.</value>
<comment>{0} will be replaced by translated TimeSpan string (such as "24 hours")</comment>
</data>
<data name="Content" xml:space="preserve">
<value>Innhold:
{0}</value>
<comment>{0} will be replaced by content string. Please note that this string should include newline for formatting.</comment>
</data>
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
<value>Konfigurert {0} egenskap er ugyldig: {1}</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
</data>
<data name="ErrorEarlyFatalExceptionInfo" xml:space="preserve">
<value>ASF V{0} har støtt på et kritisk unntak før hovedmodulen for loggføring fikk initiert!</value>
<comment>{0} will be replaced by version number</comment>
</data>
<data name="ErrorEarlyFatalExceptionPrint" xml:space="preserve">
<value>Unntak: {0}() {1}
StackTrace:
{2}</value>
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
</data>
</root>

View File

@@ -191,7 +191,7 @@ StackTrace:
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
<data name="UserInputDeviceConfirmation" xml:space="preserve">
<value>Por favor, verifique seu aplicativo móvel Steam pois você deve ter recebido uma notificação para aprovação do login. Digite Y se você recebeu e aprovou a notificação ou N se você preferir fornecer o código: </value>
<value>Por favor, verifique seu aplicativo móvel Steam, pois você deve ter recebido uma notificação para aprovação do login. Digite Y se você recebeu e aprovou a notificação ou N se você preferir fornecer o código: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteam2FA" xml:space="preserve">

View File

@@ -63,11 +63,11 @@
</value>
</resheader>
<data name="AcceptingTrade" xml:space="preserve">
<value>Takas onaylanıyor: {0}</value>
<value>Takas kabul ediliyor: {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="AutoUpdateCheckInfo" xml:space="preserve">
<value>ASF, her {0} sonra yeni sürümleri kontrol edecektir.</value>
<value>ASF, her {0} 'da bir yeni sürümleri otomatik olarak kontrol edecektir.</value>
<comment>{0} will be replaced by translated TimeSpan string (such as "24 hours")</comment>
</data>
<data name="Content" xml:space="preserve">
@@ -80,7 +80,7 @@
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
</data>
<data name="ErrorEarlyFatalExceptionInfo" xml:space="preserve">
<value>ASF v{0}, çekirdek kayıt günlüğü modülü bile başlatılamadan önce kritik bir hata ile karşılaştı!</value>
<value>ASF V{0}, çekirdek günlük modülü başlatılmadan önce kritik bir hata ile karşılaştı!</value>
<comment>{0} will be replaced by version number</comment>
</data>
<data name="ErrorEarlyFatalExceptionPrint" xml:space="preserve">
@@ -97,7 +97,7 @@ Yığın Kaydı:
<comment>{0} will be replaced by URL of the request</comment>
</data>
<data name="ErrorGlobalConfigNotLoaded" xml:space="preserve">
<value>Genel yapılandırma yüklenemedi, lütfen {0} öğesinin var ve geçerli olduğundan emin olun! Eğer kafanız karıştıysa; wikideki 'setting up / kurulum' rehberine göz atın.</value>
<value>Genel yapılandırma yüklenemedi. {0} 'ın var olduğundan ve geçerli olduğundan emin olun! Kafanız karıştıysa wiki'deki 'kurulum' kılavuzunu izleyin.</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorIsInvalid" xml:space="preserve">
@@ -105,14 +105,14 @@ Yığın Kaydı:
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorNoBotsDefined" xml:space="preserve">
<value>Tanımlanmış bot yok. ASF'yi yapılandırmayı unuttunuz mu? Kafanız karıştıysa wiki'deki 'setting up / kurulum' rehberine bakın.</value>
<value>Hiçbir bot tanımlanmamıştır. ASF'nizi yapılandırmayı unuttunuz mu? Kafanız karıştıysa wiki'deki 'kurulum' kılavuzunu izleyin.</value>
</data>
<data name="ErrorObjectIsNull" xml:space="preserve">
<value>{0} boş!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorParsingObject" xml:space="preserve">
<value>{0} ayrıştırılamadı!</value>
<value>Ayrıştırma {0} başarısız oldu!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
@@ -126,10 +126,10 @@ Yığın Kaydı:
<value>Şu anda çalışan sürüme ait hiçbir dosya olmadığı için güncelleme işlemine devam edilemedi! Bu sürüme otomatik güncelleme yapmak mümkün değil.</value>
</data>
<data name="ErrorUpdateNoAssets" xml:space="preserve">
<value>Sürüm herhangi bir öğe içermediğinden güncelleme devam edemedi!</value>
<value>Bu sürüm herhangi bir varlık içermediğinden güncellemeye devam edilemedi!</value>
</data>
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
<value>Kullanıcı girdisi için bir istek alındı; ancak işlem headless modda çalışıyor!</value>
<value>Kullanıcı giri için bir istek alındı, ancak işlem başsız modunda çalışıyor!</value>
</data>
<data name="Exiting" xml:space="preserve">
<value>Çıkılıyor...</value>
@@ -144,7 +144,7 @@ Yığın Kaydı:
<value>Genel yapılandırma dosyası kaldırıldı!</value>
</data>
<data name="IgnoringTrade" xml:space="preserve">
<value>Takas yoksayılıyor: {0}</value>
<value>Takas görmezden geliniyor: {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="LoggingIn" xml:space="preserve">
@@ -158,7 +158,7 @@ Yığın Kaydı:
<value>Oturumumuz yenileniyor!</value>
</data>
<data name="RejectingTrade" xml:space="preserve">
<value>Reddedilen takas: {0}</value>
<value>Takas reddediliyor: {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="Restarting" xml:space="preserve">
@@ -177,7 +177,7 @@ Yığın Kaydı:
<value>Yeni sürüm kontrol ediliyor...</value>
</data>
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
<value>Yeni sürüm indiriliyor: {0} ({1} MB)... Beklerken, yaptığımız çalışmayı takdir ediyorsanız bağış yapabilirsiniz! :)</value>
<value>Yeni sürüm indiriliyor: {0} ({1} MB)... Beklerken, yapılan işi takdir ediyorsanız bağış yapmayı düşünün! :)</value>
<comment>{0} will be replaced by version string, {1} will be replaced by update size (in megabytes)</comment>
</data>
<data name="UpdateFinished" xml:space="preserve">
@@ -207,7 +207,7 @@ Yığın Kaydı:
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamParentalCode" xml:space="preserve">
<value>Lütfen Steam aile kilidini girin: </value>
<value>Lütfen Steam aile kodunu girin: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamPassword" xml:space="preserve">
@@ -250,7 +250,7 @@ Yığın Kaydı:
<value>Diğer rozet sayfaları kontrol ediliyor...</value>
</data>
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
<value>Seçilen çalıştırma algoritması: {0}</value>
<value>Seçilen kart düşürme algoritması: {0}</value>
<comment>{0} will be replaced by the name of chosen farming algorithm</comment>
</data>
<data name="Done" xml:space="preserve">
@@ -315,7 +315,7 @@ Yığın Kaydı:
<value>Bilinmeyen komut!</value>
</data>
<data name="WarningCouldNotCheckBadges" xml:space="preserve">
<value>Rozet bilgisi alınamadı, daha sonra tekrar deneyeceğiz!</value>
<value>Rozetlerin bilgilerini alamadık, daha sonra tekrar deneyeceğiz!</value>
</data>
<data name="WarningCouldNotCheckCardsStatus" xml:space="preserve">
<value>{0} ({1}) için kartların durumunu kontrol edemedik, daha sonra tekrar deneyeceğiz!</value>
@@ -326,7 +326,7 @@ Yığın Kaydı:
<comment>{0} will be replaced by giftID (number)</comment>
</data>
<data name="BotAccountLimited" xml:space="preserve">
<value>Bu hesap sınırlıdır, çalıştırma işlemi, kısıtlama kaldırılıncaya kadar kullanılamaz!</value>
<value>Bu hesap sınırlıdır, kısıtlama kaldırılana kadar kart düşürmek mümkün değil!</value>
</data>
<data name="BotAddLicense" xml:space="preserve">
<value>ID: {0} | Durum: {1}</value>
@@ -340,7 +340,7 @@ Yığın Kaydı:
<value>Bu bot zaten çalışıyor!</value>
</data>
<data name="BotAuthenticatorConverting" xml:space="preserve">
<value>.maFile biçimi ASF biçimine dönüştürüyor...</value>
<value>.maFile dosya türü ASF'nin kullanacağı dosya türüne dönüştürüyor...</value>
</data>
<data name="BotAuthenticatorImportFinished" xml:space="preserve">
<value>Mobil kimlik doğrulayıcısının aktarılması başarıyla tamamlandı!</value>
@@ -356,10 +356,10 @@ Yığın Kaydı:
<value>Otomatik çalıştırma sürdürülüyor!</value>
</data>
<data name="BotAutomaticIdlingPausedAlready" xml:space="preserve">
<value>Otomatik çalıştırma zaten duraklatılmış!</value>
<value>Otomatik kart düşürme zaten duraklatıldı!</value>
</data>
<data name="BotAutomaticIdlingResumedAlready" xml:space="preserve">
<value>Otomatik çalıştırma zaten sürdürülüyor!</value>
<value>Otomatik çalıştırma zaten devam ediyor!</value>
</data>
<data name="BotConnected" xml:space="preserve">
<value>Steam'e bağlandı!</value>

View File

@@ -1,37 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2023 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using JetBrains.Annotations;
using SteamKit2;
namespace ArchiSteamFarm.Plugins.Interfaces;
[Obsolete($"Use {nameof(IBotCustomMachineInfoProvider)} instead, this interface will be removed in the future version")]
[PublicAPI]
public interface ICustomMachineInfoProvider : IPlugin {
/// <summary>
/// ASF will use this property as the <see cref="IMachineInfoProvider" /> for the bots.
/// Unless you know what you're doing, you should not implement this property yourself and let ASF decide.
/// </summary>
/// <returns><see cref="IMachineInfoProvider" /> that will be used for the bots.</returns>
IMachineInfoProvider MachineInfoProvider { get; }
}

View File

@@ -154,9 +154,7 @@ public static class PluginsCore {
return null;
}
#pragma warning disable CS0612 // TODO: Fair warning, remove ?? fallback in the next release cycle
return results.FirstOrDefault(static result => result != null) ?? await GetCustomMachineInfoProviderFallback().ConfigureAwait(false);
#pragma warning restore CS0612 // TODO: Fair warning, remove ?? fallback in the next release cycle
return results.FirstOrDefault(static result => result != null);
}
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "We don't care about trimmed assemblies, as we need it to work only with the known (used) ones")]
@@ -655,25 +653,6 @@ public static class PluginsCore {
}
}
[Obsolete]
private static async Task<IMachineInfoProvider?> GetCustomMachineInfoProviderFallback() {
if (ActivePlugins == null) {
return null;
}
IList<IMachineInfoProvider> results;
try {
results = await Utilities.InParallel(ActivePlugins.OfType<ICustomMachineInfoProvider>().Select(static plugin => Task.Run(() => plugin.MachineInfoProvider))).ConfigureAwait(false);
} catch (Exception e) {
ASF.ArchiLogger.LogGenericException(e);
return null;
}
return results.FirstOrDefault();
}
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "We don't care about trimmed assemblies, as we need it to work only with the known (used) ones")]
private static HashSet<Assembly>? LoadAssembliesFrom(string path) {
if (string.IsNullOrEmpty(path)) {

View File

@@ -2054,6 +2054,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
case EResult.AccountLoginDeniedNeedTwoFactor:
case EResult.AccountLoginDeniedThrottle:
case EResult.DuplicateRequest: // This will happen if user reacts to popup and tries to use the code afterwards, we have the code saved in ASF, we just need to try again
case EResult.Expired: // Same as Timeout
case EResult.FileNotFound: // User denied approval despite telling us that he accepted it, just try again
case EResult.InvalidPassword:
case EResult.NoConnection:
@@ -2332,7 +2333,6 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
return paymentMethod switch {
EPaymentMethod.ActivationCode => false,
EPaymentMethod.Complimentary => false,
EPaymentMethod.GuestPass => false,
EPaymentMethod.HardwarePromo => false,
_ => !paymentMethod.HasFlag(EPaymentMethod.Complimentary) // Complimentary can also be a flag
};
@@ -2892,9 +2892,26 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
}
if (packagesToRefresh.Count > 0) {
ArchiLogger.LogGenericInfo(Strings.BotRefreshingPackagesData);
await ASF.GlobalDatabase.RefreshPackages(this, packagesToRefresh).ConfigureAwait(false);
ArchiLogger.LogGenericInfo(Strings.Done);
// Since Steam spams with this call, display message on info level only if refresh takes longer time
ArchiLogger.LogGenericTrace(Strings.BotRefreshingPackagesData);
bool displayFinish = false;
Task refreshTask = ASF.GlobalDatabase.RefreshPackages(this, packagesToRefresh);
if (await Task.WhenAny(refreshTask, Task.Delay(5000)).ConfigureAwait(false) != refreshTask) {
ArchiLogger.LogGenericInfo(Strings.BotRefreshingPackagesData);
displayFinish = true;
}
await refreshTask.ConfigureAwait(false);
if (displayFinish) {
ArchiLogger.LogGenericInfo(Strings.Done);
}
ArchiLogger.LogGenericTrace(Strings.Done);
}
if (hasNewEntries) {

View File

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

View File

@@ -19,20 +19,39 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm.Steam.Data;
internal sealed class ConfirmationData {
[JsonProperty(PropertyName = "id", Required = Required.Always)]
internal readonly ulong ID;
[PublicAPI]
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
public sealed class Confirmation {
[JsonProperty(PropertyName = "nonce", Required = Required.Always)]
internal readonly ulong Nonce;
[JsonProperty(PropertyName = "creator_id", Required = Required.Always)]
internal readonly ulong CreatorID;
[JsonProperty(PropertyName = "type", Required = Required.Always)]
internal readonly string TypeText = "";
public EConfirmationType ConfirmationType { get; private set; }
[JsonProperty(PropertyName = "creator_id", Required = Required.Always)]
public ulong CreatorID { get; private set; }
[JsonProperty(PropertyName = "id", Required = Required.Always)]
public ulong ID { get; private set; }
[JsonConstructor]
private Confirmation() { }
[PublicAPI]
public enum EConfirmationType : byte {
Unknown,
Generic,
Trade,
Market,
// We're missing information about definition of number 4 type
PhoneNumberChange = 5,
AccountRecovery = 6
}
}

View File

@@ -19,17 +19,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using System.Collections.Immutable;
using Newtonsoft.Json;
namespace ArchiSteamFarm.Steam.Data;
internal sealed class ConfirmationsResponse : BooleanResponse {
[JsonProperty("needauth", Required = Required.DisallowNull)]
internal readonly bool NeedAuthentication;
[JsonProperty("conf", Required = Required.DisallowNull)]
internal readonly HashSet<ConfirmationData>? Confirmations;
[JsonProperty("conf", Required = Required.Always)]
internal readonly ImmutableHashSet<Confirmation> Confirmations = ImmutableHashSet<Confirmation>.Empty;
[JsonConstructor]
private ConfirmationsResponse() { }

View File

@@ -32,7 +32,6 @@ using ArchiSteamFarm.Localization;
using ArchiSteamFarm.Plugins;
using ArchiSteamFarm.Steam.Cards;
using ArchiSteamFarm.Steam.Data;
using ArchiSteamFarm.Steam.Security;
using ArchiSteamFarm.Steam.Storage;
using ArchiSteamFarm.Storage;
using JetBrains.Annotations;
@@ -417,7 +416,7 @@ public sealed class Trading : IDisposable {
if (mobileTradeResults.Count > 0) {
HashSet<ulong> mobileTradeOfferIDs = mobileTradeResults.Select(static tradeOffer => tradeOffer.TradeOfferID).ToHashSet();
(bool twoFactorSuccess, _, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
(bool twoFactorSuccess, _, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EConfirmationType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
if (twoFactorSuccess) {
foreach (ParseTradeResult mobileTradeResult in mobileTradeResults) {
@@ -445,6 +444,7 @@ public sealed class Trading : IDisposable {
switch (result) {
case ParseTradeResult.EResult.Ignored:
case ParseTradeResult.EResult.Rejected:
case ParseTradeResult.EResult.Blacklisted:
bool accept = await PluginsCore.OnBotTradeOffer(Bot, tradeOffer).ConfigureAwait(false);
if (accept) {

View File

@@ -36,7 +36,6 @@ using ArchiSteamFarm.Helpers;
using ArchiSteamFarm.Localization;
using ArchiSteamFarm.Steam.Data;
using ArchiSteamFarm.Steam.Exchange;
using ArchiSteamFarm.Steam.Security;
using ArchiSteamFarm.Storage;
using ArchiSteamFarm.Web;
using ArchiSteamFarm.Web.Responses;
@@ -57,6 +56,9 @@ public sealed class ArchiWebHandler : IDisposable {
private const string SteamUserService = "ISteamUser";
private const string TwoFactorService = "ITwoFactorService";
[PublicAPI]
public static Uri SteamCheckoutURL => new("https://checkout.steampowered.com");
[PublicAPI]
public static Uri SteamCommunityURL => new("https://steamcommunity.com");
@@ -1559,7 +1561,7 @@ public sealed class ArchiWebHandler : IDisposable {
throw new ArgumentOutOfRangeException(nameof(subID));
}
Uri request = new(SteamStoreURL, $"/checkout/addfreelicense/{subID}");
Uri request = new(SteamCheckoutURL, $"/checkout/addfreelicense/{subID}");
// Extra entry for sessionID
Dictionary<string, string> data = new(2, StringComparer.Ordinal) {
@@ -1853,7 +1855,7 @@ public sealed class ArchiWebHandler : IDisposable {
return resultInSeconds == 0 ? (byte) 0 : (byte) (resultInSeconds / 86400);
}
internal async Task<ConfirmationsResponse?> GetConfirmationsPage(string deviceID, string confirmationHash, ulong time) {
internal async Task<ConfirmationsResponse?> GetConfirmations(string deviceID, string confirmationHash, ulong time) {
if (string.IsNullOrEmpty(deviceID)) {
throw new ArgumentNullException(nameof(deviceID));
}
@@ -2174,7 +2176,7 @@ public sealed class ArchiWebHandler : IDisposable {
foreach (Confirmation confirmation in confirmations) {
data.Add(new KeyValuePair<string, string>("cid[]", confirmation.ID.ToString(CultureInfo.InvariantCulture)));
data.Add(new KeyValuePair<string, string>("ck[]", confirmation.Key.ToString(CultureInfo.InvariantCulture)));
data.Add(new KeyValuePair<string, string>("ck[]", confirmation.Nonce.ToString(CultureInfo.InvariantCulture)));
}
ObjectResponse<BooleanResponse>? response = await UrlPostToJsonObjectWithSession<BooleanResponse>(request, data: data).ConfigureAwait(false);
@@ -2272,14 +2274,17 @@ public sealed class ArchiWebHandler : IDisposable {
string sessionID = Convert.ToBase64String(Encoding.UTF8.GetBytes(steamID.ToString(CultureInfo.InvariantCulture)));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", $".{SteamCheckoutURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", $".{SteamCommunityURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", $".{SteamHelpURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", $".{SteamStoreURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", $".{SteamCheckoutURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", $".{SteamCommunityURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", $".{SteamHelpURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", $".{SteamStoreURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", $".{SteamCheckoutURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", $".{SteamCommunityURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", $".{SteamHelpURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", $".{SteamStoreURL.Host}"));
@@ -2287,6 +2292,7 @@ public sealed class ArchiWebHandler : IDisposable {
// Report proper time when doing timezone-based calculations, see setTimezoneCookies() from https://steamcommunity-a.akamaihd.net/public/shared/javascript/shared_global.js
string timeZoneOffset = $"{(int) DateTimeOffset.Now.Offset.TotalSeconds}{Uri.EscapeDataString(",")}0";
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", $".{SteamCheckoutURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", $".{SteamCommunityURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", $".{SteamHelpURL.Host}"));
WebBrowser.CookieContainer.Add(new Cookie("timezoneOffset", timeZoneOffset, "/", $".{SteamStoreURL.Host}"));

View File

@@ -21,6 +21,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
@@ -33,7 +34,6 @@ using ArchiSteamFarm.Helpers;
using ArchiSteamFarm.Localization;
using ArchiSteamFarm.Steam.Data;
using ArchiSteamFarm.Steam.Exchange;
using ArchiSteamFarm.Steam.Security;
using ArchiSteamFarm.Steam.Storage;
using ArchiSteamFarm.Storage;
using ArchiSteamFarm.Web;
@@ -133,7 +133,7 @@ public sealed class Actions : IAsyncDisposable, IDisposable {
}
[PublicAPI]
public async Task<(bool Success, IReadOnlyCollection<Confirmation>? HandledConfirmations, string Message)> HandleTwoFactorAuthenticationConfirmations(bool accept, Confirmation.EType? acceptedType = null, IReadOnlyCollection<ulong>? acceptedCreatorIDs = null, bool waitIfNeeded = false) {
public async Task<(bool Success, IReadOnlyCollection<Confirmation>? HandledConfirmations, string Message)> HandleTwoFactorAuthenticationConfirmations(bool accept, Confirmation.EConfirmationType? acceptedType = null, IReadOnlyCollection<ulong>? acceptedCreatorIDs = null, bool waitIfNeeded = false) {
if (Bot.BotDatabase.MobileAuthenticator == null) {
return (false, null, Strings.BotNoASFAuthenticator);
}
@@ -149,36 +149,38 @@ public sealed class Actions : IAsyncDisposable, IDisposable {
await Task.Delay(1000).ConfigureAwait(false);
}
HashSet<Confirmation>? confirmations = await Bot.BotDatabase.MobileAuthenticator.GetConfirmations().ConfigureAwait(false);
ImmutableHashSet<Confirmation>? confirmations = await Bot.BotDatabase.MobileAuthenticator.GetConfirmations().ConfigureAwait(false);
if ((confirmations == null) || (confirmations.Count == 0)) {
continue;
}
HashSet<Confirmation> remainingConfirmations = confirmations.ToHashSet();
if (acceptedType.HasValue) {
if (confirmations.RemoveWhere(confirmation => confirmation.Type != acceptedType.Value) > 0) {
if (confirmations.Count == 0) {
if (remainingConfirmations.RemoveWhere(confirmation => confirmation.ConfirmationType != acceptedType.Value) > 0) {
if (remainingConfirmations.Count == 0) {
continue;
}
}
}
if (acceptedCreatorIDs?.Count > 0) {
if (confirmations.RemoveWhere(confirmation => !acceptedCreatorIDs.Contains(confirmation.Creator)) > 0) {
if (confirmations.Count == 0) {
if (remainingConfirmations.RemoveWhere(confirmation => !acceptedCreatorIDs.Contains(confirmation.CreatorID)) > 0) {
if (remainingConfirmations.Count == 0) {
continue;
}
}
}
if (!await Bot.BotDatabase.MobileAuthenticator.HandleConfirmations(confirmations, accept).ConfigureAwait(false)) {
if (!await Bot.BotDatabase.MobileAuthenticator.HandleConfirmations(remainingConfirmations, accept).ConfigureAwait(false)) {
return (false, handledConfirmations?.Values, Strings.WarningFailed);
}
handledConfirmations ??= new Dictionary<ulong, Confirmation>();
foreach (Confirmation? confirmation in confirmations) {
handledConfirmations[confirmation.Creator] = confirmation;
foreach (Confirmation? confirmation in remainingConfirmations) {
handledConfirmations[confirmation.CreatorID] = confirmation;
}
// We've accepted *something*, if caller didn't specify the IDs, that's enough for us
@@ -343,7 +345,7 @@ public sealed class Actions : IAsyncDisposable, IDisposable {
(bool success, _, HashSet<ulong>? mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(targetSteamID, items, token: tradeToken, itemsPerTrade: itemsPerTrade).ConfigureAwait(false);
if ((mobileTradeOfferIDs?.Count > 0) && Bot.HasMobileAuthenticator) {
(bool twoFactorSuccess, _, _) = await HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
(bool twoFactorSuccess, _, _) = await HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EConfirmationType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
if (!twoFactorSuccess) {
return (false, Strings.BotLootingFailed);

View File

@@ -1,61 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2023 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.ComponentModel;
using JetBrains.Annotations;
using Newtonsoft.Json;
namespace ArchiSteamFarm.Steam.Security;
public sealed class Confirmation {
[JsonProperty(Required = Required.Always)]
public ulong Creator { get; }
[JsonProperty(Required = Required.Always)]
public ulong ID { get; }
[JsonProperty(Required = Required.Always)]
public ulong Key { get; }
[JsonProperty(Required = Required.Always)]
public EType Type { get; }
internal Confirmation(ulong id, ulong key, ulong creator, EType type) {
ID = id > 0 ? id : throw new ArgumentOutOfRangeException(nameof(id));
Key = key > 0 ? key : throw new ArgumentOutOfRangeException(nameof(key));
Creator = creator > 0 ? creator : throw new ArgumentOutOfRangeException(nameof(creator));
Type = Enum.IsDefined(type) ? type : throw new InvalidEnumArgumentException(nameof(type), (int) type, typeof(EType));
}
// REF: Internal documentation
[PublicAPI]
public enum EType : byte {
Unknown,
Generic,
Trade,
Market,
// We're missing information about definition of number 4 type
PhoneNumberChange = 5,
AccountRecovery = 6
}
}

View File

@@ -24,6 +24,7 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
@@ -142,7 +143,7 @@ public sealed class MobileAuthenticator : IDisposable {
);
}
internal async Task<HashSet<Confirmation>?> GetConfirmations() {
internal async Task<ImmutableHashSet<Confirmation>?> GetConfirmations() {
if (Bot == null) {
throw new InvalidOperationException(nameof(Bot));
}
@@ -172,38 +173,17 @@ public sealed class MobileAuthenticator : IDisposable {
}
// ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework
ConfirmationsResponse? response = await Bot.ArchiWebHandler.GetConfirmationsPage(deviceID!, confirmationHash!, time).ConfigureAwait(false);
ConfirmationsResponse? response = await Bot.ArchiWebHandler.GetConfirmations(deviceID!, confirmationHash!, time).ConfigureAwait(false);
// ReSharper restore RedundantSuppressNullableWarningExpression - required for .NET Framework
if (response?.Confirmations == null) {
if (response?.Success != true) {
return null;
}
if (!response.Success) {
return null;
foreach (Confirmation? confirmation in response.Confirmations.Where(static confirmation => (confirmation.ConfirmationType == Confirmation.EConfirmationType.Unknown) || !Enum.IsDefined(confirmation.ConfirmationType))) {
Bot.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningUnknownValuePleaseReport, nameof(confirmation.ConfirmationType), confirmation.ConfirmationType));
}
HashSet<Confirmation> result = new();
foreach (ConfirmationData confirmation in response.Confirmations) {
// ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework
if (!Enum.TryParse(confirmation.TypeText!, out Confirmation.EType type) || (type == Confirmation.EType.Unknown)) {
Bot.ArchiLogger.LogNullError(type);
return null;
}
if (!Enum.IsDefined(type)) {
Bot.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningUnknownValuePleaseReport, nameof(type), type));
return null;
}
result.Add(new Confirmation(confirmation.ID, confirmation.Nonce, confirmation.CreatorID, type));
}
return result;
return response.Confirmations;
}
internal async Task<ulong> GetSteamTime() {
@@ -295,7 +275,7 @@ public sealed class MobileAuthenticator : IDisposable {
// We totally ignore actual result returned by those calls, abort only if request timed out
foreach (Confirmation confirmation in confirmations) {
// ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework
bool? confirmationResult = await Bot.ArchiWebHandler.HandleConfirmation(deviceID!, confirmationHash!, time, confirmation.ID, confirmation.Key, accept).ConfigureAwait(false);
bool? confirmationResult = await Bot.ArchiWebHandler.HandleConfirmation(deviceID!, confirmationHash!, time, confirmation.ID, confirmation.Nonce, accept).ConfigureAwait(false);
// ReSharper restore RedundantSuppressNullableWarningExpression - required for .NET Framework

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>5.4.7.2</Version>
<Version>5.4.8.3</Version>
</PropertyGroup>
<PropertyGroup>

View File

@@ -4,14 +4,14 @@
<PackageVersion Include="ConfigureAwaitChecker.Analyzer" Version="5.0.0.1" />
<PackageVersion Include="CryptSharpStandard" Version="1.0.0" />
<PackageVersion Include="Humanizer" Version="2.14.1" />
<PackageVersion Include="JetBrains.Annotations" Version="2022.3.1" />
<PackageVersion Include="JetBrains.Annotations" Version="2023.2.0" />
<PackageVersion Include="Markdig.Signed" Version="0.31.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageVersion Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageVersion Include="MSTest.TestFramework" Version="3.0.4" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageVersion Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageVersion Include="MSTest.TestFramework" Version="3.1.1" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
<PackageVersion Include="NLog.Web.AspNetCore" Version="5.3.0" />
<PackageVersion Include="NLog.Web.AspNetCore" Version="5.3.2" />
<PackageVersion Include="SteamKit2" Version="2.5.0-Beta.1" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />

3
cc.sh
View File

@@ -10,8 +10,7 @@ SOLUTION="${MAIN_PROJECT}.sln"
CONFIGURATION="Release"
OUT="out"
OUT_ASF="${OUT}/result"
OUT_STD="${OUT}/${STEAM_TOKEN_DUMPER_NAME}"
PLUGINS="${MAIN_PROJECT}.OfficialPlugins.ItemsMatcher"
PLUGINS="${MAIN_PROJECT}.OfficialPlugins.ItemsMatcher ${MAIN_PROJECT}.OfficialPlugins.MobileAuthenticator"
ANALYSIS=1
ASF_UI=1

2
wiki

Submodule wiki updated: 3f5f338304...b346256a36