mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-24 18:26:49 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85466d8b5a | ||
|
|
b6446f5dd2 | ||
|
|
978e6a3d0c | ||
|
|
56cc106c11 | ||
|
|
97e5969362 | ||
|
|
0192bb5491 | ||
|
|
608f30e32f | ||
|
|
949af6b22c | ||
|
|
3b6ec4bf5e | ||
|
|
1647674da0 | ||
|
|
01aa08f0a3 | ||
|
|
f7647f851a | ||
|
|
cfdec679f1 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -72,7 +72,7 @@ jobs:
|
||||
shell: sh
|
||||
run: |
|
||||
if [ -n "${STEAM_TOKEN_DUMPER_TOKEN-}" ] && [ -f "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs" ]; then
|
||||
sed "s/STEAM_TOKEN_DUMPER_TOKEN/${STEAM_TOKEN_DUMPER_TOKEN}/g" "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs" > "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs.new";
|
||||
sed "s/STEAM_TOKEN_DUMPER_TOKEN/${STEAM_TOKEN_DUMPER_TOKEN}/g" "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs" > "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs.new"
|
||||
mv "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs.new" "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs"
|
||||
fi
|
||||
- name: Prepare ArchiSteamFarm.OfficialPlugins.SteamTokenDumper on Windows
|
||||
|
||||
Submodule ASF-WebConfigGenerator updated: f917c604cc...b5ea925d05
2
ASF-ui
2
ASF-ui
Submodule ASF-ui updated: bd00b29fcf...a14d1b3ecf
@@ -89,7 +89,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<(bool Success, string Message)> HandleTwoFactorAuthenticationConfirmations(bool accept, Steam.ConfirmationDetails.EType? acceptedType = null, IReadOnlyCollection<ulong> acceptedTradeOfferIDs = null, bool waitIfNeeded = false) {
|
||||
public async Task<(bool Success, string Message)> HandleTwoFactorAuthenticationConfirmations(bool accept, MobileAuthenticator.Confirmation.EType? acceptedType = null, IReadOnlyCollection<ulong> acceptedCreatorIDs = null, bool waitIfNeeded = false) {
|
||||
if (!Bot.HasMobileAuthenticator) {
|
||||
return (false, Strings.BotNoASFAuthenticator);
|
||||
}
|
||||
@@ -98,55 +98,59 @@ namespace ArchiSteamFarm {
|
||||
return (false, Strings.BotNotConnected);
|
||||
}
|
||||
|
||||
HashSet<ulong> handledTradeOfferIDs = null;
|
||||
ushort handledConfirmationsCount = 0;
|
||||
HashSet<ulong> handledCreatorIDs = null;
|
||||
|
||||
for (byte i = 0; (i == 0) || ((i < WebBrowser.MaxTries) && waitIfNeeded); i++) {
|
||||
if (i > 0) {
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
HashSet<MobileAuthenticator.Confirmation> confirmations = await Bot.BotDatabase.MobileAuthenticator.GetConfirmations(acceptedType).ConfigureAwait(false);
|
||||
HashSet<MobileAuthenticator.Confirmation> confirmations = await Bot.BotDatabase.MobileAuthenticator.GetConfirmations().ConfigureAwait(false);
|
||||
|
||||
if ((confirmations == null) || (confirmations.Count == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we can skip asking for details, we can handle confirmations right away
|
||||
if ((acceptedTradeOfferIDs == null) || (acceptedTradeOfferIDs.Count == 0)) {
|
||||
bool result = await Bot.BotDatabase.MobileAuthenticator.HandleConfirmations(confirmations, accept).ConfigureAwait(false);
|
||||
|
||||
return (result, result ? string.Format(Strings.BotHandledConfirmations, confirmations.Count) : Strings.WarningFailed);
|
||||
if (acceptedType.HasValue) {
|
||||
if (confirmations.RemoveWhere(confirmation => confirmation.Type != acceptedType.Value) > 0) {
|
||||
if (confirmations.Count == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IList<Steam.ConfirmationDetails> results = await Utilities.InParallel(confirmations.Select(Bot.BotDatabase.MobileAuthenticator.GetConfirmationDetails)).ConfigureAwait(false);
|
||||
|
||||
foreach (MobileAuthenticator.Confirmation confirmation in results.Where(details => (details != null) && ((acceptedType.HasValue && (acceptedType.Value != details.Type)) || ((details.TradeOfferID != 0) && !acceptedTradeOfferIDs.Contains(details.TradeOfferID)))).Select(details => details.Confirmation)) {
|
||||
confirmations.Remove(confirmation);
|
||||
}
|
||||
|
||||
if (confirmations.Count == 0) {
|
||||
continue;
|
||||
if ((acceptedCreatorIDs != null) && (acceptedCreatorIDs.Count > 0)) {
|
||||
if (confirmations.RemoveWhere(confirmation => !acceptedCreatorIDs.Contains(confirmation.Creator)) > 0) {
|
||||
if (confirmations.Count == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!await Bot.BotDatabase.MobileAuthenticator.HandleConfirmations(confirmations, accept).ConfigureAwait(false)) {
|
||||
return (false, Strings.WarningFailed);
|
||||
}
|
||||
|
||||
IEnumerable<ulong> handledTradeOfferIDsThisRound = results.Where(details => (details != null) && (details.TradeOfferID != 0)).Select(result => result.TradeOfferID);
|
||||
handledConfirmationsCount += (ushort) confirmations.Count;
|
||||
|
||||
if (handledTradeOfferIDs != null) {
|
||||
handledTradeOfferIDs.UnionWith(handledTradeOfferIDsThisRound);
|
||||
} else {
|
||||
handledTradeOfferIDs = handledTradeOfferIDsThisRound.ToHashSet();
|
||||
}
|
||||
if ((acceptedCreatorIDs != null) && (acceptedCreatorIDs.Count > 0)) {
|
||||
IEnumerable<ulong> handledCreatorIDsThisRound = confirmations.Select(confirmation => confirmation.Creator).Where(acceptedCreatorIDs.Contains);
|
||||
|
||||
// Check if those are all that we were expected to confirm
|
||||
if (acceptedTradeOfferIDs.All(handledTradeOfferIDs.Contains)) {
|
||||
return (true, string.Format(Strings.BotHandledConfirmations, acceptedTradeOfferIDs.Count));
|
||||
if (handledCreatorIDs != null) {
|
||||
handledCreatorIDs.UnionWith(handledCreatorIDsThisRound);
|
||||
} else {
|
||||
handledCreatorIDs = handledCreatorIDsThisRound.ToHashSet();
|
||||
}
|
||||
|
||||
// Check if those are all that we were expected to confirm
|
||||
if (handledCreatorIDs.SetEquals(acceptedCreatorIDs)) {
|
||||
return (true, string.Format(Strings.BotHandledConfirmations, handledConfirmationsCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (!waitIfNeeded, !waitIfNeeded ? Strings.Success : string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries));
|
||||
return (!waitIfNeeded, !waitIfNeeded ? string.Format(Strings.BotHandledConfirmations, handledConfirmationsCount) : string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries));
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
@@ -308,7 +312,7 @@ namespace ArchiSteamFarm {
|
||||
(bool success, HashSet<ulong> mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(targetSteamID, inventory, token: tradeToken).ConfigureAwait(false);
|
||||
|
||||
if ((mobileTradeOfferIDs != null) && (mobileTradeOfferIDs.Count > 0) && Bot.HasMobileAuthenticator) {
|
||||
(bool twoFactorSuccess, _) = await HandleTwoFactorAuthenticationConfirmations(true, Steam.ConfirmationDetails.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
|
||||
(bool twoFactorSuccess, _) = await HandleTwoFactorAuthenticationConfirmations(true, MobileAuthenticator.Confirmation.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
|
||||
|
||||
if (!twoFactorSuccess) {
|
||||
return (false, Strings.BotLootingFailed);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<PackageReference Include="Nito.AsyncEx.Coordination" Version="5.0.0" />
|
||||
<PackageReference Include="NLog" Version="4.7.2" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.2" />
|
||||
<PackageReference Include="SteamKit2" Version="2.3.0-beta.2" />
|
||||
<PackageReference Include="SteamKit2" Version="2.3.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.5.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.5.1" />
|
||||
|
||||
@@ -1633,39 +1633,6 @@ namespace ArchiSteamFarm {
|
||||
return await UrlGetToHtmlDocumentWithSession(SteamCommunityURL, request, false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[ItemCanBeNull]
|
||||
internal async Task<Steam.ConfirmationDetails> GetConfirmationDetails(string deviceID, string confirmationHash, uint time, MobileAuthenticator.Confirmation confirmation) {
|
||||
if (string.IsNullOrEmpty(deviceID) || string.IsNullOrEmpty(confirmationHash) || (time == 0) || (confirmation == null)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(deviceID) + " || " + nameof(confirmationHash) + " || " + nameof(time) + " || " + nameof(confirmation));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Initialized) {
|
||||
for (byte i = 0; (i < ASF.GlobalConfig.ConnectionTimeout) && !Initialized && Bot.IsConnectedAndLoggedOn; i++) {
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (!Initialized) {
|
||||
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
string request = "/mobileconf/details/" + confirmation.ID + "?a=" + Bot.SteamID + "&k=" + WebUtility.UrlEncode(confirmationHash) + "&l=english&m=android&p=" + WebUtility.UrlEncode(deviceID) + "&t=" + time + "&tag=conf";
|
||||
|
||||
Steam.ConfirmationDetails response = await UrlGetToJsonObjectWithSession<Steam.ConfirmationDetails>(SteamCommunityURL, request).ConfigureAwait(false);
|
||||
|
||||
if (response?.Success != true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
response.Confirmation = confirmation;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
internal async Task<IDocument> GetConfirmations(string deviceID, string confirmationHash, uint time) {
|
||||
if (string.IsNullOrEmpty(deviceID) || string.IsNullOrEmpty(confirmationHash) || (time == 0)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(deviceID) + " || " + nameof(confirmationHash) + " || " + nameof(time));
|
||||
|
||||
@@ -2545,7 +2545,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
ushort memoryInMegabytes = (ushort) (GC.GetTotalMemory(false) / 1024 / 1024);
|
||||
TimeSpan uptime = DateTime.UtcNow.Subtract(RuntimeCompatibility.ProcessStartTime);
|
||||
TimeSpan uptime = DateTime.UtcNow.Subtract(RuntimeCompatibility.ProcessStartTime.ToUniversalTime());
|
||||
|
||||
return FormatBotResponse(string.Format(Strings.BotStats, memoryInMegabytes, uptime.ToHumanReadable()));
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using AngleSharp.Dom;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
@@ -289,6 +288,7 @@ namespace ArchiSteamFarm.Json {
|
||||
}
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
public class BooleanResponse {
|
||||
[JsonProperty(PropertyName = "success", Required = Required.Always)]
|
||||
@@ -298,101 +298,7 @@ namespace ArchiSteamFarm.Json {
|
||||
protected BooleanResponse() { }
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
public sealed class ConfirmationDetails : BooleanResponse {
|
||||
internal MobileAuthenticator.Confirmation Confirmation { get; set; }
|
||||
internal ulong TradeOfferID { get; private set; }
|
||||
internal EType Type { get; private set; }
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
[JsonProperty(PropertyName = "html", Required = Required.DisallowNull)]
|
||||
private string HTML {
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(value));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
using IDocument htmlDocument = WebBrowser.StringToHtmlDocument(value).Result;
|
||||
|
||||
if (htmlDocument == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(htmlDocument));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (htmlDocument.SelectSingleNode("//div[@class='mobileconf_trade_area']") != null) {
|
||||
Type = EType.Trade;
|
||||
|
||||
IElement tradeOfferNode = htmlDocument.SelectSingleNode("//div[@class='tradeoffer']");
|
||||
|
||||
if (tradeOfferNode == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(tradeOfferNode));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
string idText = tradeOfferNode.GetAttributeValue("id");
|
||||
|
||||
if (string.IsNullOrEmpty(idText)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(idText));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int index = idText.IndexOf('_');
|
||||
|
||||
if (index < 0) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(index));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (idText.Length <= index) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(idText.Length));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
idText = idText.Substring(index);
|
||||
|
||||
if (!ulong.TryParse(idText, out ulong tradeOfferID) || (tradeOfferID == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(tradeOfferID));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
TradeOfferID = tradeOfferID;
|
||||
} else if (htmlDocument.SelectSingleNode("//div[@class='mobileconf_listing_prices']") != null) {
|
||||
Type = EType.Market;
|
||||
} else {
|
||||
// Normally this should be reported, but under some specific circumstances we might actually receive this one
|
||||
Type = EType.Generic;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
[JsonConstructor]
|
||||
private ConfirmationDetails() { }
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
public class EResultResponse {
|
||||
[JsonProperty(PropertyName = "success", Required = Required.Always)]
|
||||
|
||||
@@ -601,7 +601,11 @@ StackTrace:
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Du verwendest eine Version, die neuer ist als die zuletzt veröffentlichte Version deines Aktualisierungskanals. Bitte bedenke, dass Vorabversionen nur für Benutzer gedacht sind, die wissen wie man Fehler meldet, mit Problemen umgeht und Rückmeldung gibt - es wird keine technische Unterstützung geben.</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Aktuelle Speichernutzung: {0} MB.
|
||||
Prozesslaufzeit: {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>Lösche Steam-Entdeckungsliste #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
@@ -715,7 +719,7 @@ StackTrace:
|
||||
<value>Alte Dateien nach dem Update bereinigen...</value>
|
||||
</data>
|
||||
<data name="BotGeneratingSteamParentalCode" xml:space="preserve">
|
||||
<value>Erstelle Steam-Jugendschutz-Code, das kann einige Zeit dauern. Eventuell sollten Sie stattdessen den Code in der Konfiguration hinterlegen...</value>
|
||||
<value>Erstelle Steam-Jugendschutz-Code, das kann einige Zeit dauern. Eventuell solltest du stattdessen den Code in der Konfiguration hinterlegen...</value>
|
||||
</data>
|
||||
<data name="IPCConfigChanged" xml:space="preserve">
|
||||
<value>Die IPC-Konfiguration wurde geändert!</value>
|
||||
|
||||
@@ -600,7 +600,11 @@ Trazo de pila:
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Está utilizando una versión más reciente que la última versión publicada para su canal de actualización. Por favor, tenga en cuenta que las versiones preliminares están dedicadas a usuarios que saben cómo reportar errores, tratar con problemas y dar sus comentarios - no se dará soporte técnico.</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Uso de memoria actual: {0} MB.
|
||||
Tiempo de actividad del proceso: {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>Despejando la lista de descubrimientos de Steam #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
|
||||
@@ -601,7 +601,11 @@ StackTrace :
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Vous utilisez une version qui est plus récente que la dernière version pour votre canal de mise à jour. Veuillez noter que les pré-versions sont réservées aux utilisateurs qui savent comment signaler un bogue, gérer les soucis et donner un retour - aucun support technique ne sera fourni.</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Utilisation de la mémoire actuelle : {0} Mo.
|
||||
Durée de fonctionnement : {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>Consultation de la liste de découvertes en cours #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
|
||||
@@ -600,7 +600,11 @@ StackTrace:
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Je gebruikt een nieuwere versie dan de laatste versie van je update kanaal. Hou er rekening mee dat pre-release versies alleen geschikt zijn voor gebruikers die weten hoe ze bugs moeten rapporteren, kunnen omgaan met problemen en feedback kunnen geven. Er wordt geen technische ondersteuning geboden.</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Huidig geheugengebruik: {0} MB.
|
||||
Proces uptime: {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>Steam-ontdekkingswachtrij afwerken #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
|
||||
@@ -246,27 +246,27 @@ StackTrace:
|
||||
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
|
||||
</data>
|
||||
<data name="UserInputSteam2FA" xml:space="preserve">
|
||||
<value>Por favor, insira o código gerado pelo autenticador móvel do Steam: </value>
|
||||
<value>Insira o código gerado pelo autenticador móvel do Steam: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamGuard" xml:space="preserve">
|
||||
<value>Por favor, insira o código de autenticação do Steam Guard enviado por e-mail: </value>
|
||||
<value>Insira o código de autenticação do Steam Guard enviado por e-mail: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamLogin" xml:space="preserve">
|
||||
<value>Por favor, insira o seu nome de usuário Steam: </value>
|
||||
<value>Insira o seu nome de usuário Steam: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamParentalCode" xml:space="preserve">
|
||||
<value>Por favor, insira o código do modo família: </value>
|
||||
<value>Insira o código do modo família: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="UserInputSteamPassword" xml:space="preserve">
|
||||
<value>Por favor, insira a sua senha do Steam: </value>
|
||||
<value>Insira a senha da sua conta Steam: </value>
|
||||
<comment>Please note that this translation should end with space</comment>
|
||||
</data>
|
||||
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
|
||||
<value>O valor recebido para {0} é desconhecido, por favor informe: {1}</value>
|
||||
<value>O valor recebido para {0} é desconhecido. Relate o seguinte: {1}</value>
|
||||
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
|
||||
</data>
|
||||
<data name="IPCReady" xml:space="preserve">
|
||||
@@ -546,7 +546,7 @@ StackTrace:
|
||||
<value>Parando...</value>
|
||||
</data>
|
||||
<data name="ErrorBotConfigInvalid" xml:space="preserve">
|
||||
<value>A configuração do bot é inválida. Por favor, verifique o arquivo {0} e tente novamente!</value>
|
||||
<value>A configuração do bot é inválida. Verifique o arquivo {0} e tente novamente!</value>
|
||||
<comment>{0} will be replaced by file's path</comment>
|
||||
</data>
|
||||
<data name="ErrorDatabaseInvalid" xml:space="preserve">
|
||||
@@ -558,7 +558,7 @@ StackTrace:
|
||||
<comment>{0} will be replaced by service name that is being initialized</comment>
|
||||
</data>
|
||||
<data name="WarningPrivacyPolicy" xml:space="preserve">
|
||||
<value>Por favor revise a seção de política de privacidade na nossa wiki se você está preocupado com o que o ASF realmente está fazendo!</value>
|
||||
<value>Consulte a nossa seção de política de privacidade na wiki caso esteja preocupado com o que o ASF está fazendo!</value>
|
||||
</data>
|
||||
<data name="Welcome" xml:space="preserve">
|
||||
<value>Parece que é a sua primeira vez abrindo o programa, bem-vindo(a)!</value>
|
||||
@@ -599,15 +599,19 @@ StackTrace:
|
||||
<value>Acesso negado!</value>
|
||||
</data>
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Você está usando uma versão que é mais nova que a última lançada para o seu canal de atualizações. Por favor, tenha em mente que versões de pré-lançamento são dedicadas a usuários que sabem como relatar bugs, lidar com problemas e dar feedback - nenhum apoio técnico será fornecido.</value>
|
||||
<value>Você está usando uma versão que é mais nova que a última lançada para o seu canal de atualizações. Tenha em mente que versões de pré-lançamento são dedicadas a usuários que sabem como relatar bugs, lidar com problemas e dar feedback - nenhum apoio técnico será fornecido.</value>
|
||||
</data>
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Uso de memória atual: {0} MB.
|
||||
Tempo de execução: {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>Limpando a lista de descobrimento #{0}...</value>
|
||||
<value>Limpando lista de descobrimento de nº {0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="DoneClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>Limpeza da lista de descobrimento #{0} concluída.</value>
|
||||
<value>Limpeza da lista de descobrimento de nº {0} concluída.</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
</data>
|
||||
<data name="BotOwnsOverviewPerGame" xml:space="preserve">
|
||||
@@ -677,7 +681,7 @@ StackTrace:
|
||||
<value>Você carregou um ou mais plugins personalizados no ASF. Como não podemos oferecer suporte para configurações modificadas, por favor contate os desenvolvedores do plugin que você decidiu usar em caso de problemas.</value>
|
||||
</data>
|
||||
<data name="PleaseWait" xml:space="preserve">
|
||||
<value>Por favor, aguarde...</value>
|
||||
<value>Aguarde...</value>
|
||||
</data>
|
||||
<data name="EnterCommand" xml:space="preserve">
|
||||
<value>Digite o comando: </value>
|
||||
@@ -715,7 +719,7 @@ StackTrace:
|
||||
<value>Limpando arquivos antigos após a atualização...</value>
|
||||
</data>
|
||||
<data name="BotGeneratingSteamParentalCode" xml:space="preserve">
|
||||
<value>Gerando o código do Modo Família, isso pode levar um tempo. Considere colocá-lo no arquivo de configuração...</value>
|
||||
<value>Gerando o código do modo família, isso pode levar algum tempo. Considere salvá-lo no arquivo de configuração...</value>
|
||||
</data>
|
||||
<data name="IPCConfigChanged" xml:space="preserve">
|
||||
<value>A configuração IPC foi alterada!</value>
|
||||
|
||||
@@ -601,7 +601,11 @@ StackTrace:
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Folosești o versiune care este mai nouă față de ultima versiune lansată pentru canalul tău de actualizare. Te rugăm să reții că versiunile preliminare sunt dedicate utilizatorilor care știu cum să raporteze defecțiuni, să abordeze problemele și să ofere feedback - nu va fi oferit suport tehnic.</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Utilizare curentă a memoriei: {0} MB.
|
||||
Proces: {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>Se șterge lista de descoperiri Steam #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
|
||||
@@ -601,7 +601,11 @@
|
||||
<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>
|
||||
|
||||
@@ -601,7 +601,11 @@ Yığın izleme:
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>Güncelleme kanalınız için yayınlanmış en son sürümden daha yeni bir sürüm kullanıyorsunuz. Lütfen ön yayın sürümlerinin, hata raporlamayı, sorunlarla başa çıkmayı ve geribildirim yapmayı bilen kişiler için olduğunu unutmayın. Teknik destek verilmeyecektir.</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>Geçerli bellek kullanımı: {0} MB.
|
||||
Süreç çalışma zamanı: {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>Steam keşif kuyruğu #{0} temizleniyor...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
|
||||
@@ -601,7 +601,11 @@
|
||||
<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>Очищення черги знахідок Steam №{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
|
||||
@@ -601,7 +601,11 @@
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>您目前使用的版本高於最新的穩定版本。請注意:預發行版本專用於了解如何回報錯誤、處理問題並提供回饋的用戶——並不提供任何技術支援。</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>目前記憶體使用量:{0} MB。
|
||||
已執行時間:{1}</value>
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used, {1} will be replaced by translated TimeSpan string (such as "25 minutes"). Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
<data name="ClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>正在瀏覽 Steam 探索佇列 #{0}...</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
|
||||
@@ -600,7 +600,11 @@
|
||||
<data name="WarningPreReleaseVersion" xml:space="preserve">
|
||||
<value>你目前使用的版本高於最新的穩定版本。請注意:預覽版本是專門給了解如何回報錯誤、處理問題並提供回饋的使用者使用,並不提供任何技術支援。</value>
|
||||
</data>
|
||||
|
||||
<data name="BotStats" xml:space="preserve">
|
||||
<value>目前記憶體使用量:{0} MB。
|
||||
已執行時間:{1}</value>
|
||||
<comment>{0} will be replaced by number (in megabytes) of memory being used, {1} will be replaced by translated TimeSpan string (such as "25 minutes"). Please note that this string should include newlines for formatting.</comment>
|
||||
</data>
|
||||
<data name="ClearingDiscoveryQueue" xml:space="preserve">
|
||||
<value>正在瀏覽 Steam 探索佇列 #{0}……</value>
|
||||
<comment>{0} will be replaced by queue number</comment>
|
||||
|
||||
@@ -28,14 +28,13 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Dom;
|
||||
using ArchiSteamFarm.Helpers;
|
||||
using ArchiSteamFarm.Json;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
internal sealed class MobileAuthenticator : IDisposable {
|
||||
public sealed class MobileAuthenticator : IDisposable {
|
||||
internal const byte CodeDigits = 5;
|
||||
|
||||
private const byte CodeInterval = 30;
|
||||
@@ -79,44 +78,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
[ItemCanBeNull]
|
||||
internal async Task<Steam.ConfirmationDetails> GetConfirmationDetails(Confirmation confirmation) {
|
||||
if (confirmation == null) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(confirmation));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
(bool success, string deviceID) = await CachedDeviceID.GetValue().ConfigureAwait(false);
|
||||
|
||||
if (!success || string.IsNullOrEmpty(deviceID)) {
|
||||
Bot.ArchiLogger.LogGenericError(string.Format(Strings.WarningFailedWithError, nameof(deviceID)));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
uint time = await GetSteamTime().ConfigureAwait(false);
|
||||
|
||||
if (time == 0) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(time));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
string confirmationHash = GenerateConfirmationHash(time, "conf");
|
||||
|
||||
if (string.IsNullOrEmpty(confirmationHash)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(confirmationHash));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Steam.ConfirmationDetails response = await Bot.ArchiWebHandler.GetConfirmationDetails(deviceID, confirmationHash, time, confirmation).ConfigureAwait(false);
|
||||
|
||||
return response?.Success == true ? response : null;
|
||||
}
|
||||
|
||||
[ItemCanBeNull]
|
||||
internal async Task<HashSet<Confirmation>> GetConfirmations(Steam.ConfirmationDetails.EType? acceptedType = null) {
|
||||
internal async Task<HashSet<Confirmation>> GetConfirmations() {
|
||||
(bool success, string deviceID) = await CachedDeviceID.GetValue().ConfigureAwait(false);
|
||||
|
||||
if (!success || string.IsNullOrEmpty(deviceID)) {
|
||||
@@ -186,6 +148,20 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
string creatorText = confirmationNode.GetAttributeValue("data-creator");
|
||||
|
||||
if (string.IsNullOrEmpty(creatorText)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(creatorText));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!ulong.TryParse(creatorText, out ulong creator) || (creator == 0)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(creator));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
string typeText = confirmationNode.GetAttributeValue("data-type");
|
||||
|
||||
if (string.IsNullOrEmpty(typeText)) {
|
||||
@@ -194,23 +170,19 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Enum.TryParse(typeText, out Steam.ConfirmationDetails.EType type) || (type == Steam.ConfirmationDetails.EType.Unknown)) {
|
||||
if (!Enum.TryParse(typeText, out Confirmation.EType type) || (type == Confirmation.EType.Unknown)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(type));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Enum.IsDefined(typeof(Steam.ConfirmationDetails.EType), type)) {
|
||||
if (!Enum.IsDefined(typeof(Confirmation.EType), type)) {
|
||||
Bot.ArchiLogger.LogGenericError(string.Format(Strings.WarningUnknownValuePleaseReport, nameof(type), type));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (acceptedType.HasValue && (acceptedType.Value != type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Add(new Confirmation(id, key));
|
||||
result.Add(new Confirmation(id, key, creator, type));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -435,17 +407,34 @@ namespace ArchiSteamFarm {
|
||||
return (true, deviceID);
|
||||
}
|
||||
|
||||
internal sealed class Confirmation {
|
||||
public sealed class Confirmation {
|
||||
internal readonly ulong Creator;
|
||||
internal readonly ulong ID;
|
||||
internal readonly ulong Key;
|
||||
internal readonly EType Type;
|
||||
|
||||
internal Confirmation(ulong id, ulong key) {
|
||||
if ((id == 0) || (key == 0)) {
|
||||
throw new ArgumentNullException(nameof(id) + " || " + nameof(key));
|
||||
internal Confirmation(ulong id, ulong key, ulong creator, EType type) {
|
||||
if ((id == 0) || (key == 0) || (creator == 0) || !Enum.IsDefined(typeof(EType), type)) {
|
||||
throw new ArgumentNullException(nameof(id) + " || " + nameof(key) + " || " + nameof(creator) + " || " + nameof(type));
|
||||
}
|
||||
|
||||
ID = id;
|
||||
Key = key;
|
||||
Creator = creator;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,7 +626,7 @@ namespace ArchiSteamFarm {
|
||||
(bool success, HashSet<ulong> mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(listedUser.SteamID, itemsToGive, itemsToReceive, listedUser.TradeToken, true).ConfigureAwait(false);
|
||||
|
||||
if ((mobileTradeOfferIDs != null) && (mobileTradeOfferIDs.Count > 0) && Bot.HasMobileAuthenticator) {
|
||||
(bool twoFactorSuccess, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Steam.ConfirmationDetails.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
|
||||
(bool twoFactorSuccess, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, MobileAuthenticator.Confirmation.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
|
||||
|
||||
if (!twoFactorSuccess) {
|
||||
Bot.ArchiLogger.LogGenericTrace(Strings.WarningFailed);
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
LastChangeNumber = picsChanges.CurrentChangeNumber;
|
||||
|
||||
if ((picsChanges.AppChanges.Count == 0) && (picsChanges.PackageChanges.Count == 0)) {
|
||||
if (picsChanges.RequiresFullAppUpdate || picsChanges.RequiresFullPackageUpdate || ((picsChanges.AppChanges.Count == 0) && (picsChanges.PackageChanges.Count == 0))) {
|
||||
await PluginsCore.OnPICSChangesRestart(picsChanges.CurrentChangeNumber).ConfigureAwait(false);
|
||||
|
||||
return;
|
||||
|
||||
@@ -419,7 +419,7 @@ namespace ArchiSteamFarm {
|
||||
HashSet<ulong> mobileTradeOfferIDs = results.Where(result => (result.TradeResult != null) && (result.TradeResult.Result == ParseTradeResult.EResult.Accepted) && result.RequiresMobileConfirmation).Select(result => result.TradeResult.TradeOfferID).ToHashSet();
|
||||
|
||||
if (mobileTradeOfferIDs.Count > 0) {
|
||||
(bool twoFactorSuccess, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Steam.ConfirmationDetails.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
|
||||
(bool twoFactorSuccess, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, MobileAuthenticator.Confirmation.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
|
||||
|
||||
if (!twoFactorSuccess) {
|
||||
HandledTradeOfferIDs.ExceptWith(mobileTradeOfferIDs);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>4.2.3.5</Version>
|
||||
<Version>4.2.3.6</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
2
wiki
2
wiki
Submodule wiki updated: 2c78fdfd4d...a99f4b7ad6
Reference in New Issue
Block a user