diff --git a/ArchiSteamFarm/Json/Steam.cs b/ArchiSteamFarm/Json/Steam.cs index 1b9a00eaf..015d76e21 100644 --- a/ArchiSteamFarm/Json/Steam.cs +++ b/ArchiSteamFarm/Json/Steam.cs @@ -166,168 +166,87 @@ namespace ArchiSteamFarm.Json { [SuppressMessage("ReSharper", "ClassCannotBeInstantiated")] internal sealed class ConfirmationDetails : BooleanResponse { - internal ulong OtherSteamID64 { - get { - if (_OtherSteamID64 != 0) { - return _OtherSteamID64; - } + internal MobileAuthenticator.Confirmation Confirmation { get; set; } + internal ulong OtherSteamID64 { get; private set; } + internal ulong TradeOfferID { get; private set; } + internal EType Type { get; private set; } - if ((Type != EType.Trade) || (OtherSteamID3 == 0)) { - return 0; - } - - _OtherSteamID64 = new SteamID(OtherSteamID3, EUniverse.Public, EAccountType.Individual); - return _OtherSteamID64; - } - } - - internal ulong TradeOfferID { - get { - if (_TradeOfferID != 0) { - return _TradeOfferID; - } - - if ((Type != EType.Trade) || (DocumentNode == null)) { - return 0; - } - - HtmlNode htmlNode = DocumentNode.SelectSingleNode("//div[@class='tradeoffer']"); - if (htmlNode == null) { - ASF.ArchiLogger.LogNullError(nameof(htmlNode)); - return 0; - } - - string idText = htmlNode.GetAttributeValue("id", null); - if (string.IsNullOrEmpty(idText)) { - ASF.ArchiLogger.LogNullError(nameof(idText)); - return 0; - } - - int index = idText.IndexOf('_'); - if (index < 0) { - ASF.ArchiLogger.LogNullError(nameof(index)); - return 0; - } - - index++; - if (idText.Length <= index) { - ASF.ArchiLogger.LogNullError(nameof(idText.Length)); - return 0; - } - - idText = idText.Substring(index); - if (!ulong.TryParse(idText, out _TradeOfferID) || (_TradeOfferID == 0)) { - ASF.ArchiLogger.LogNullError(nameof(_TradeOfferID)); - return 0; - } - - return _TradeOfferID; - } - } - - internal EType Type { - get { - if (_Type != EType.Unknown) { - return _Type; - } - - if (DocumentNode == null) { - return EType.Unknown; - } - - if (DocumentNode.SelectSingleNode("//div[@class='mobileconf_listing_prices']") != null) { - _Type = EType.Market; - return _Type; - } - - if (DocumentNode.SelectSingleNode("//div[@class='mobileconf_trade_area']") != null) { - _Type = EType.Trade; - return _Type; - } - - // Normally this should be reported, but under some specific circumstances we might actually receive this one - _Type = EType.Generic; - return _Type; - } - } - -#pragma warning disable 649 [JsonProperty(PropertyName = "html", Required = Required.DisallowNull)] - private readonly string HTML; -#pragma warning restore 649 - - private HtmlNode DocumentNode { - get { - if (_DocumentNode != null) { - return _DocumentNode; - } - - if (string.IsNullOrEmpty(HTML)) { - return null; - } - - HtmlDocument htmlDocument = WebBrowser.StringToHtmlDocument(HTML); - if (htmlDocument == null) { - ASF.ArchiLogger.LogNullError(nameof(htmlDocument)); - return null; - } - - _DocumentNode = htmlDocument.DocumentNode; - return _DocumentNode; - } - } - - private uint OtherSteamID3 { - get { - if (_OtherSteamID3 != 0) { - return _OtherSteamID3; - } - - if ((Type != EType.Trade) || (DocumentNode == null)) { - return 0; - } - - HtmlNode htmlNode = DocumentNode.SelectSingleNode("//a/@data-miniprofile"); - if (htmlNode == null) { - ASF.ArchiLogger.LogNullError(nameof(htmlNode)); - return 0; - } - - string miniProfile = htmlNode.GetAttributeValue("data-miniprofile", null); - if (string.IsNullOrEmpty(miniProfile)) { - ASF.ArchiLogger.LogNullError(nameof(miniProfile)); - return 0; - } - - if (!uint.TryParse(miniProfile, out _OtherSteamID3) || (_OtherSteamID3 == 0)) { - ASF.ArchiLogger.LogNullError(nameof(_OtherSteamID3)); - return 0; - } - - return _OtherSteamID3; - } - } - - internal MobileAuthenticator.Confirmation Confirmation { - get => _Confirmation; - + private string HTML { set { - if (value == null) { + if (string.IsNullOrEmpty(value)) { ASF.ArchiLogger.LogNullError(nameof(value)); return; } - _Confirmation = value; + HtmlDocument htmlDocument = WebBrowser.StringToHtmlDocument(value); + if (htmlDocument == null) { + ASF.ArchiLogger.LogNullError(nameof(htmlDocument)); + return; + } + + if (htmlDocument.DocumentNode.SelectSingleNode("//div[@class='mobileconf_trade_area']") != null) { + Type = EType.Trade; + + HtmlNode tradeOfferNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class='tradeoffer']"); + if (tradeOfferNode == null) { + ASF.ArchiLogger.LogNullError(nameof(tradeOfferNode)); + return; + } + + string idText = tradeOfferNode.GetAttributeValue("id", null); + 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; + + HtmlNode htmlNode = htmlDocument.DocumentNode.SelectSingleNode("//a/@data-miniprofile"); + if (htmlNode == null) { + ASF.ArchiLogger.LogNullError(nameof(htmlNode)); + return; + } + + string miniProfile = htmlNode.GetAttributeValue("data-miniprofile", null); + if (string.IsNullOrEmpty(miniProfile)) { + ASF.ArchiLogger.LogNullError(nameof(miniProfile)); + return; + } + + if (!uint.TryParse(miniProfile, out uint steamID3) || (steamID3 == 0)) { + ASF.ArchiLogger.LogNullError(nameof(steamID3)); + return; + } + + OtherSteamID64 = new SteamID(steamID3, EUniverse.Public, EAccountType.Individual); + } else if (htmlDocument.DocumentNode.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; + } } } - private MobileAuthenticator.Confirmation _Confirmation; - private HtmlNode _DocumentNode; - private uint _OtherSteamID3; - private ulong _OtherSteamID64; - private ulong _TradeOfferID; - private EType _Type; - // Deserialized from JSON private ConfirmationDetails() { } @@ -482,29 +401,10 @@ namespace ArchiSteamFarm.Json { internal sealed class TradeOffer { internal readonly HashSet ItemsToGive = new HashSet(); internal readonly HashSet ItemsToReceive = new HashSet(); + internal readonly ulong OtherSteamID64; internal readonly ETradeOfferState State; internal readonly ulong TradeOfferID; - internal ulong OtherSteamID64 { - get { - if (_OtherSteamID64 != 0) { - return _OtherSteamID64; - } - - if (OtherSteamID3 == 0) { - ASF.ArchiLogger.LogNullError(nameof(OtherSteamID3)); - return 0; - } - - _OtherSteamID64 = new SteamID(OtherSteamID3, EUniverse.Public, EAccountType.Individual); - return _OtherSteamID64; - } - } - - private readonly uint OtherSteamID3; - - private ulong _OtherSteamID64; - // Constructed from trades being received internal TradeOffer(ulong tradeOfferID, uint otherSteamID3, ETradeOfferState state) { if ((tradeOfferID == 0) || (otherSteamID3 == 0) || (state == ETradeOfferState.Unknown)) { @@ -512,29 +412,28 @@ namespace ArchiSteamFarm.Json { } TradeOfferID = tradeOfferID; - OtherSteamID3 = otherSteamID3; + OtherSteamID64 = new SteamID(otherSteamID3, EUniverse.Public, EAccountType.Individual); State = state; } internal bool IsFairTypesExchange() { Dictionary> itemsToGivePerGame = new Dictionary>(); foreach (Asset item in ItemsToGive) { - if (!itemsToGivePerGame.TryGetValue(item.RealAppID, out Dictionary itemsPerType)) { + if (itemsToGivePerGame.TryGetValue(item.RealAppID, out Dictionary itemsPerType)) { + itemsPerType[item.Type] = itemsPerType.TryGetValue(item.Type, out uint amount) ? amount + item.Amount : item.Amount; + } else { itemsPerType = new Dictionary { [item.Type] = item.Amount }; itemsToGivePerGame[item.RealAppID] = itemsPerType; - } else { - itemsPerType[item.Type] = itemsPerType.TryGetValue(item.Type, out uint amount) ? amount + item.Amount : item.Amount; } } Dictionary> itemsToReceivePerGame = new Dictionary>(); foreach (Asset item in ItemsToReceive) { - if (!itemsToReceivePerGame.TryGetValue(item.RealAppID, out Dictionary itemsPerType)) { - itemsPerType = new Dictionary { { item.Type, item.Amount } }; - - itemsToReceivePerGame[item.RealAppID] = itemsPerType; - } else { + if (itemsToReceivePerGame.TryGetValue(item.RealAppID, out Dictionary itemsPerType)) { itemsPerType[item.Type] = itemsPerType.TryGetValue(item.Type, out uint amount) ? amount + item.Amount : item.Amount; + } else { + itemsPerType = new Dictionary { { item.Type, item.Amount } }; + itemsToReceivePerGame[item.RealAppID] = itemsPerType; } }