diff --git a/ArchiSteamFarm/ArchiWebHandler.cs b/ArchiSteamFarm/ArchiWebHandler.cs index 8bb94eb88..e1a38cc47 100644 --- a/ArchiSteamFarm/ArchiWebHandler.cs +++ b/ArchiSteamFarm/ArchiWebHandler.cs @@ -61,19 +61,23 @@ namespace ArchiSteamFarm { } Logging.LogGenericInfo(Bot.BotName, "Unlocking parental account..."); - Dictionary postData = new Dictionary() { - { "pin", parentalPin } + Dictionary data = new Dictionary() { + { "pin", parentalPin } }; - HttpResponseMessage response = await WebBrowser.UrlPost("https://steamcommunity.com/parental/ajaxunlock", postData, Cookie, "https://steamcommunity.com/").ConfigureAwait(false); + HttpResponseMessage response = null; + for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) { + response = await WebBrowser.UrlPost("https://steamcommunity.com/parental/ajaxunlock", data, Cookie, "https://steamcommunity.com/").ConfigureAwait(false); + } + if (response == null) { - Logging.LogGenericInfo(Bot.BotName, "Failed!"); + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); return; } IEnumerable setCookieValues; if (!response.Headers.TryGetValues("Set-Cookie", out setCookieValues)) { - Logging.LogGenericInfo(Bot.BotName, "Failed!"); + Logging.LogNullError(Bot.BotName, "setCookieValues"); return; } @@ -87,7 +91,7 @@ namespace ArchiSteamFarm { } } - Logging.LogGenericInfo(Bot.BotName, "Failed!"); + Logging.LogGenericWarning(Bot.BotName, "Failed to unlock parental account!"); } internal ArchiWebHandler(Bot bot, string apiKey) { @@ -153,11 +157,10 @@ namespace ArchiSteamFarm { string steamLogin = authResult["token"].AsString(); string steamLoginSecure = authResult["tokensecure"].AsString(); - Cookie.Clear(); - Cookie.Add("sessionid", sessionID); - Cookie.Add("steamLogin", steamLogin); - Cookie.Add("steamLoginSecure", steamLoginSecure); - Cookie.Add("birthtime", "-473356799"); // ( ͡° ͜ʖ ͡°) + Cookie["sessionid"] = sessionID; + Cookie["steamLogin"] = steamLogin; + Cookie["steamLoginSecure"] = steamLoginSecure; + Cookie["birthtime"] = "-473356799"; await UnlockParentalAccount(parentalPin).ConfigureAwait(false); return true; @@ -168,8 +171,13 @@ namespace ArchiSteamFarm { return false; } - HtmlDocument htmlDocument = await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/my/profile", Cookie).ConfigureAwait(false); + HtmlDocument htmlDocument = null; + for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) { + htmlDocument = await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/my/profile", Cookie).ConfigureAwait(false); + } + if (htmlDocument == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); return null; } @@ -193,25 +201,25 @@ namespace ArchiSteamFarm { return null; } - KeyValue response; - using (dynamic iEconService = WebAPI.GetInterface("IEconService")) { - // Timeout + KeyValue response = null; + using (dynamic iEconService = WebAPI.GetInterface("IEconService", ApiKey)) { iEconService.Timeout = Timeout; - try { - response = iEconService.GetTradeOffers( - key: ApiKey, - get_received_offers: 1, - active_only: 1, - secure: true - ); - } catch (Exception e) { - Logging.LogGenericException(Bot.BotName, e); - return null; + for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) { + try { + response = iEconService.GetTradeOffers( + get_received_offers: 1, + active_only: 1, + secure: true + ); + } catch (Exception e) { + Logging.LogGenericException(Bot.BotName, e); + } } } if (response == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); return null; } @@ -262,44 +270,64 @@ namespace ArchiSteamFarm { return result; } - internal async Task JoinClan(ulong clanID) { + internal async Task JoinClan(ulong clanID) { if (clanID == 0) { - return; + return false; } string sessionID; if (!Cookie.TryGetValue("sessionid", out sessionID)) { - return; + return false; } string request = "https://steamcommunity.com/gid/" + clanID; - Dictionary postData = new Dictionary() { + Dictionary data = new Dictionary() { {"sessionID", sessionID}, {"action", "join"} }; - await WebBrowser.UrlPost(request, postData, Cookie).ConfigureAwait(false); + HttpResponseMessage response = null; + for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) { + response = await WebBrowser.UrlPost(request, data, Cookie).ConfigureAwait(false); + } + + if (response == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); + return false; + } + + return true; } - internal async Task LeaveClan(ulong clanID) { + internal async Task LeaveClan(ulong clanID) { if (clanID == 0) { - return; + return false; } string sessionID; if (!Cookie.TryGetValue("sessionid", out sessionID)) { - return; + return false; } string request = GetHomeProcess(); - Dictionary postData = new Dictionary() { + Dictionary data = new Dictionary() { {"sessionID", sessionID}, {"action", "leaveGroup"}, {"groupId", clanID.ToString()} }; - await WebBrowser.UrlPost(request, postData, Cookie).ConfigureAwait(false); + HttpResponseMessage response = null; + for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) { + response = await WebBrowser.UrlPost(request, data, Cookie).ConfigureAwait(false); + } + + if (response == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); + return false; + } + + return true; } internal async Task AcceptTradeOffer(ulong tradeID) { @@ -312,84 +340,81 @@ namespace ArchiSteamFarm { return false; } - string referer = "https://steamcommunity.com/tradeoffer/" + tradeID + "/"; - string request = referer + "accept"; + string referer = "https://steamcommunity.com/tradeoffer/" + tradeID; + string request = referer + "/accept"; - Dictionary postData = new Dictionary() { + Dictionary data = new Dictionary() { {"sessionid", sessionID}, {"serverid", "1"}, {"tradeofferid", tradeID.ToString()} }; - HttpResponseMessage result = await WebBrowser.UrlPost(request, postData, Cookie, referer).ConfigureAwait(false); - if (result == null) { + HttpResponseMessage response = null; + for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) { + response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false); + } + + if (response == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); return false; } - bool success = result.IsSuccessStatusCode; - - if (!success) { - Logging.LogGenericWarning(Bot.BotName, "Request failed, reason: " + result.ReasonPhrase); - switch (result.StatusCode) { - case HttpStatusCode.InternalServerError: - Logging.LogGenericWarning(Bot.BotName, "That might be caused by 7-days trade lock from new device"); - Logging.LogGenericWarning(Bot.BotName, "Try again in 7 days, declining that offer for now"); - DeclineTradeOffer(tradeID); - break; - } - } - - return success; + return true; } internal bool DeclineTradeOffer(ulong tradeID) { - if (ApiKey == null) { + if (tradeID == 0 || ApiKey == null) { return false; } - if (tradeID == 0) { - return false; - } - - KeyValue response; - using (dynamic iEconService = WebAPI.GetInterface("IEconService")) { - // Timeout + KeyValue response = null; + using (dynamic iEconService = WebAPI.GetInterface("IEconService", ApiKey)) { iEconService.Timeout = Timeout; - try { - response = iEconService.DeclineTradeOffer( - key: ApiKey, - tradeofferid: tradeID.ToString(), - method: WebRequestMethods.Http.Post, - secure: true - ); - } catch (Exception e) { - Logging.LogGenericException(Bot.BotName, e); - return false; + for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) { + try { + response = iEconService.DeclineTradeOffer( + tradeofferid: tradeID.ToString(), + method: WebRequestMethods.Http.Post, + secure: true + ); + } catch (Exception e) { + Logging.LogGenericException(Bot.BotName, e); + } } } - return response != null; // Steam API doesn't respond with any error code, assume any response is a success + if (response == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); + return false; + } + + return true; } internal async Task> GetInventory() { + JObject jObject = null; + for (byte i = 0; i < WebBrowser.MaxRetries && jObject == null; i++) { + jObject = await WebBrowser.UrlGetToJObject("https://steamcommunity.com/my/inventory/json/753/6", Cookie).ConfigureAwait(false); + } + + if (jObject == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); + return null; + } + List result = new List(); - try { - JObject jObject = await WebBrowser.UrlGetToJObject("https://steamcommunity.com/my/inventory/json/753/6", Cookie).ConfigureAwait(false); - IEnumerable jTokens = jObject.SelectTokens("$.rgInventory.*"); - foreach (JToken jToken in jTokens) { - result.Add(JsonConvert.DeserializeObject(jToken.ToString())); - } - } catch (Exception e) { - Logging.LogGenericException(Bot.BotName, e); + IEnumerable jTokens = jObject.SelectTokens("$.rgInventory.*"); + foreach (JToken jToken in jTokens) { + result.Add(JsonConvert.DeserializeObject(jToken.ToString())); } return result; } - internal async Task SendTradeOffer(List items, ulong partnerID, string token = null) { - if (items == null || partnerID == 0) { + internal async Task SendTradeOffer(List inventory, ulong partnerID, string token = null) { + if (inventory == null || inventory.Count == 0 || partnerID == 0) { return false; } @@ -399,8 +424,7 @@ namespace ArchiSteamFarm { } SteamTradeOfferRequest trade = new SteamTradeOfferRequest(); - - foreach (SteamItem item in items) { + foreach (SteamItem item in inventory) { trade.me.assets.Add(new SteamItem() { appid = "753", contextid = "6", @@ -412,7 +436,7 @@ namespace ArchiSteamFarm { string referer = "https://steamcommunity.com/tradeoffer/new"; string request = referer + "/send"; - Dictionary postData = new Dictionary() { + Dictionary data = new Dictionary() { {"sessionid", sessionID}, {"serverid", "1"}, {"partner", partnerID.ToString()}, @@ -421,28 +445,53 @@ namespace ArchiSteamFarm { {"trade_offer_create_params", string.IsNullOrEmpty(token) ? "" : string.Format("{{ \"trade_offer_access_token\":\"{0}\" }}", token)} // TODO: This should be rewrote }; - HttpResponseMessage response = await WebBrowser.UrlPost(request, postData, Cookie, referer).ConfigureAwait(false); + HttpResponseMessage response = null; + for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) { + response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false); + } + if (response == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); return false; } return true; } - internal async Task GetBadgePage(int page) { - if (SteamID == 0 || page == 0) { + internal async Task GetBadgePage(byte page) { + if (page == 0 || SteamID == 0) { return null; } - return await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/profiles/" + SteamID + "/badges?l=english&p=" + page, Cookie).ConfigureAwait(false); + HtmlDocument htmlDocument = null; + for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) { + htmlDocument = await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/profiles/" + SteamID + "/badges?l=english&p=" + page, Cookie).ConfigureAwait(false); + } + + if (htmlDocument == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); + return null; + } + + return htmlDocument; } internal async Task GetGameCardsPage(ulong appID) { - if (SteamID == 0 || appID == 0) { + if (appID == 0 || SteamID == 0) { return null; } - return await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/profiles/" + SteamID + "/gamecards/" + appID + "?l=english", Cookie).ConfigureAwait(false); + HtmlDocument htmlDocument = null; + for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) { + htmlDocument = await WebBrowser.UrlGetToHtmlDocument("https://steamcommunity.com/profiles/" + SteamID + "/gamecards/" + appID + "?l=english", Cookie).ConfigureAwait(false); + } + + if (htmlDocument == null) { + Logging.LogGenericWTF(Bot.BotName, "Request failed even after " + WebBrowser.MaxRetries + " tries"); + return null; + } + + return htmlDocument; } } } diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index 5f8f9c0b6..0829ed903 100644 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -182,7 +182,7 @@ namespace ArchiSteamFarm { null, TimeSpan.FromHours(SendTradePeriod), // Delay TimeSpan.FromHours(SendTradePeriod) // Period - ); + ); } // Before attempting to connect, initialize our list of CMs @@ -513,7 +513,7 @@ namespace ArchiSteamFarm { } List inventory = await bot.ArchiWebHandler.GetInventory().ConfigureAwait(false); - if (inventory.Count == 0) { + if (inventory == null || inventory.Count == 0) { return "Nothing to send, inventory seems empty!"; } diff --git a/ArchiSteamFarm/CMsgClientClanInviteAction.cs b/ArchiSteamFarm/CMsgClientClanInviteAction.cs index 1b92feca8..21c91d466 100644 --- a/ArchiSteamFarm/CMsgClientClanInviteAction.cs +++ b/ArchiSteamFarm/CMsgClientClanInviteAction.cs @@ -28,14 +28,12 @@ using System.IO; namespace ArchiSteamFarm { internal sealed class CMsgClientClanInviteAction : ISteamSerializableMessage, ISteamSerializable { - EMsg ISteamSerializableMessage.GetEMsg() { - return EMsg.ClientAcknowledgeClanInvite; - } - internal ulong GroupID = 0; internal bool AcceptInvite = true; - public CMsgClientClanInviteAction() { } + EMsg ISteamSerializableMessage.GetEMsg() { + return EMsg.ClientAcknowledgeClanInvite; + } void ISteamSerializable.Serialize(Stream stream) { if (stream == null) { diff --git a/ArchiSteamFarm/CardsFarmer.cs b/ArchiSteamFarm/CardsFarmer.cs index 63a955c24..9a2371c82 100755 --- a/ArchiSteamFarm/CardsFarmer.cs +++ b/ArchiSteamFarm/CardsFarmer.cs @@ -161,11 +161,11 @@ namespace ArchiSteamFarm { return; } - var maxPages = 1; + byte maxPages = 1; HtmlNodeCollection htmlNodeCollection = htmlDocument.DocumentNode.SelectNodes("//a[@class='pagelink']"); if (htmlNodeCollection != null && htmlNodeCollection.Count > 0) { HtmlNode htmlNode = htmlNodeCollection[htmlNodeCollection.Count - 1]; - if (!int.TryParse(htmlNode.InnerText, out maxPages)) { + if (!byte.TryParse(htmlNode.InnerText, out maxPages)) { maxPages = 1; // Should never happen } } @@ -173,7 +173,7 @@ namespace ArchiSteamFarm { GamesToFarm.Clear(); // Find APPIDs we need to farm - for (var page = 1; page <= maxPages; page++) { + for (byte page = 1; page <= maxPages; page++) { if (page > 1) { // Because we fetched page number 1 already Logging.LogGenericInfo(Bot.BotName, "Checking page: " + page + "/" + maxPages); htmlDocument = await Bot.ArchiWebHandler.GetBadgePage(page).ConfigureAwait(false); @@ -306,7 +306,7 @@ namespace ArchiSteamFarm { Logging.LogGenericInfo(Bot.BotName, "Sending signal to stop farming"); FarmResetEvent.Set(); - for (var i = 0; i < 5 && NowFarming; i++) { + for (byte i = 0; i < 5 && NowFarming; i++) { Logging.LogGenericInfo(Bot.BotName, "Waiting for reaction..."); await Utilities.SleepAsync(1000).ConfigureAwait(false); } diff --git a/ArchiSteamFarm/Logging.cs b/ArchiSteamFarm/Logging.cs index 0177503ba..d63378cc3 100644 --- a/ArchiSteamFarm/Logging.cs +++ b/ArchiSteamFarm/Logging.cs @@ -56,6 +56,10 @@ namespace ArchiSteamFarm { } } + internal static void LogGenericWTF(string botName, string message, [CallerMemberName] string previousMethodName = "") { + Log("[!!] WTF: " + previousMethodName + "() <" + botName + "> " + message + ", WTF?"); + } + internal static void LogGenericError(string botName, string message, [CallerMemberName] string previousMethodName = "") { Log("[!!] ERROR: " + previousMethodName + "() <" + botName + "> " + message); } @@ -70,6 +74,10 @@ namespace ArchiSteamFarm { } } + internal static void LogGenericException(Exception exception, [CallerMemberName] string previousMethodName = "") { + LogGenericException("ASF", exception, previousMethodName); + } + internal static void LogGenericWarning(string botName, string message, [CallerMemberName] string previousMethodName = "") { Log("[!] WARNING: " + previousMethodName + "() <" + botName + "> " + message); } @@ -82,6 +90,10 @@ namespace ArchiSteamFarm { Log("[*] NOTICE: " + previousMethodName + "() <" + botName + "> " + message); } + internal static void LogNullError(string botName, string nullObjectName, [CallerMemberName] string previousMethodName = "") { + LogGenericError(botName, nullObjectName + " is null!", previousMethodName); + } + [Conditional("DEBUG")] internal static void LogGenericDebug(string botName, string message, [CallerMemberName] string previousMethodName = "") { Log("[#] DEBUG: " + previousMethodName + "() <" + botName + "> " + message); diff --git a/ArchiSteamFarm/Utilities.cs b/ArchiSteamFarm/Utilities.cs index 18b4322e6..920c6e6bd 100644 --- a/ArchiSteamFarm/Utilities.cs +++ b/ArchiSteamFarm/Utilities.cs @@ -22,7 +22,6 @@ */ -using System; using System.Text.RegularExpressions; using System.Threading.Tasks; diff --git a/ArchiSteamFarm/WCF.cs b/ArchiSteamFarm/WCF.cs index ea83a8ca9..8143b3474 100644 --- a/ArchiSteamFarm/WCF.cs +++ b/ArchiSteamFarm/WCF.cs @@ -1,7 +1,6 @@ using System; using System.ServiceModel; using System.ServiceModel.Channels; -using System.Threading.Tasks; namespace ArchiSteamFarm { [ServiceContract] diff --git a/ArchiSteamFarm/WebBrowser.cs b/ArchiSteamFarm/WebBrowser.cs index 070ab0115..f226e4662 100644 --- a/ArchiSteamFarm/WebBrowser.cs +++ b/ArchiSteamFarm/WebBrowser.cs @@ -34,30 +34,41 @@ using System.Xml; namespace ArchiSteamFarm { internal static class WebBrowser { + private const string FakeUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"; + + internal const byte MaxRetries = 5; internal const byte HttpTimeout = 180; // In seconds - private static readonly HttpClientHandler HttpClientHandler = new HttpClientHandler { UseCookies = false }; + private static readonly HttpClientHandler HttpClientHandler = new HttpClientHandler { + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate, + UseCookies = false + }; + private static readonly HttpClient HttpClient = new HttpClient(HttpClientHandler) { Timeout = TimeSpan.FromSeconds(HttpTimeout) }; internal static void Init() { + // Declare default UserAgent HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd("ArchiSteamFarm/" + Program.Version); - // Don't limit maximum number of allowed concurrent connections - // It's application's responsibility to handle that stuff + // Some web servers might go crazy if we don't specify some extra headers + HttpClient.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest"); + + // Increase limit of maximum number of allowed concurrent connections + // Default is 2 which is usually too low for what we're doing ServicePointManager.DefaultConnectionLimit = int.MaxValue; // Don't use Expect100Continue, we don't need to do that ServicePointManager.Expect100Continue = false; } - private static async Task UrlRequest(string request, HttpMethod httpMethod, Dictionary data = null, Dictionary cookies = null, string referer = null) { + private static async Task UrlRequest(string request, HttpMethod httpMethod, Dictionary data = null, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request) || httpMethod == null) { return null; } HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, request); - if (httpMethod == HttpMethod.Post && data != null) { + if (data != null) { requestMessage.Content = new FormUrlEncodedContent(data); } @@ -73,6 +84,10 @@ namespace ArchiSteamFarm { requestMessage.Headers.Referrer = new Uri(referer); } + if (fakeUserAgent) { + requestMessage.Headers.UserAgent.ParseAdd(FakeUserAgent); + } + HttpResponseMessage responseMessage; try { @@ -88,28 +103,33 @@ namespace ArchiSteamFarm { return responseMessage; } - internal static async Task UrlGet(string request, Dictionary cookies = null, string referer = null) { + internal static async Task UrlGet(string request, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request)) { return null; } - return await UrlRequest(request, HttpMethod.Get, null, cookies, referer).ConfigureAwait(false); + return await UrlRequest(request, HttpMethod.Get, null, cookies, referer, fakeUserAgent).ConfigureAwait(false); } - internal static async Task UrlPost(string request, Dictionary postData = null, Dictionary cookies = null, string referer = null) { + internal static async Task UrlPost(string request, Dictionary data = null, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request)) { return null; } - return await UrlRequest(request, HttpMethod.Post, postData, cookies, referer).ConfigureAwait(false); + return await UrlRequest(request, HttpMethod.Post, data, cookies, referer, fakeUserAgent).ConfigureAwait(false); } internal static async Task HttpResponseToHtmlDocument(HttpResponseMessage httpResponse) { - if (httpResponse == null || httpResponse.Content == null) { + if (httpResponse == null) { return null; } - string content = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + HttpContent httpContent = httpResponse.Content; + if (httpContent == null) { + return null; + } + + string content = await httpContent.ReadAsStringAsync().ConfigureAwait(false); if (string.IsNullOrEmpty(content)) { return null; } @@ -121,38 +141,96 @@ namespace ArchiSteamFarm { return htmlDocument; } - internal static async Task UrlGetToContent(string request, Dictionary cookies = null, string referer = null) { + internal static async Task UrlGetToContent(string request, Dictionary cookies, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request)) { return null; } - HttpResponseMessage responseMessage = await UrlGet(request, cookies, referer).ConfigureAwait(false); - if (responseMessage == null || responseMessage.Content == null) { + HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer, fakeUserAgent).ConfigureAwait(false); + if (httpResponse == null) { return null; } - return await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); + HttpContent httpContent = httpResponse.Content; + if (httpContent == null) { + return null; + } + + return await httpContent.ReadAsStringAsync().ConfigureAwait(false); } - internal static async Task UrlPostToContent(string request, Dictionary postData = null, Dictionary cookies = null, string referer = null) { + internal static async Task UrlPostToContent(string request, Dictionary data = null, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request)) { return null; } - HttpResponseMessage responseMessage = await UrlPost(request, postData, cookies, referer).ConfigureAwait(false); - if (responseMessage == null || responseMessage.Content == null) { + HttpResponseMessage httpResponse = await UrlPost(request, data, cookies, referer, fakeUserAgent).ConfigureAwait(false); + if (httpResponse == null) { return null; } - return await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); + HttpContent httpContent = httpResponse.Content; + if (httpContent == null) { + return null; + } + + return await httpContent.ReadAsStringAsync().ConfigureAwait(false); } - internal static async Task UrlGetToTitle(string request, Dictionary cookies = null, string referer = null) { + internal static async Task UrlPostToJObject(string request, Dictionary data = null, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request)) { return null; } - HtmlDocument htmlDocument = await UrlGetToHtmlDocument(request, cookies, referer).ConfigureAwait(false); + string content = await UrlPostToContent(request, data, cookies, referer, fakeUserAgent).ConfigureAwait(false); + if (string.IsNullOrEmpty(content)) { + return null; + } + + JObject jObject; + + try { + jObject = JObject.Parse(content); + } catch (Exception e) { + Logging.LogGenericException(e); + return null; + } + + return jObject; + } + + internal static async Task UrlGetToHtmlDocument(string request, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { + if (string.IsNullOrEmpty(request)) { + return null; + } + + HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer, fakeUserAgent).ConfigureAwait(false); + if (httpResponse == null) { + return null; + } + + return await HttpResponseToHtmlDocument(httpResponse).ConfigureAwait(false); + } + + internal static async Task UrlPostToHtmlDocument(string request, Dictionary data = null, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { + if (string.IsNullOrEmpty(request)) { + return null; + } + + HttpResponseMessage httpResponse = await UrlPost(request, data, cookies, referer, fakeUserAgent).ConfigureAwait(false); + if (httpResponse == null) { + return null; + } + + return await HttpResponseToHtmlDocument(httpResponse).ConfigureAwait(false); + } + + internal static async Task UrlGetToTitle(string request, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { + if (string.IsNullOrEmpty(request)) { + return null; + } + + HtmlDocument htmlDocument = await UrlGetToHtmlDocument(request, cookies, referer, fakeUserAgent).ConfigureAwait(false); if (htmlDocument == null) { return null; } @@ -165,25 +243,12 @@ namespace ArchiSteamFarm { return htmlNode.InnerText; } - internal static async Task UrlGetToHtmlDocument(string request, Dictionary cookies = null, string referer = null) { + internal static async Task UrlGetToJArray(string request, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request)) { return null; } - HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer).ConfigureAwait(false); - if (httpResponse == null) { - return null; - } - - return await HttpResponseToHtmlDocument(httpResponse).ConfigureAwait(false); - } - - internal static async Task UrlGetToJArray(string request, Dictionary cookies = null, string referer = null) { - if (string.IsNullOrEmpty(request)) { - return null; - } - - string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false); + string content = await UrlGetToContent(request, cookies, referer, fakeUserAgent).ConfigureAwait(false); if (string.IsNullOrEmpty(content)) { return null; } @@ -193,19 +258,19 @@ namespace ArchiSteamFarm { try { jArray = JArray.Parse(content); } catch (Exception e) { - Logging.LogGenericException("WebBrowser", e); + Logging.LogGenericException(e); return null; } return jArray; } - internal static async Task UrlGetToJObject(string request, Dictionary cookies = null, string referer = null) { + internal static async Task UrlGetToJObject(string request, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request)) { return null; } - string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false); + string content = await UrlGetToContent(request, cookies, referer, fakeUserAgent).ConfigureAwait(false); if (string.IsNullOrEmpty(content)) { return null; } @@ -215,19 +280,19 @@ namespace ArchiSteamFarm { try { jObject = JObject.Parse(content); } catch (Exception e) { - Logging.LogGenericException("WebBrowser", e); + Logging.LogGenericException(e); return null; } return jObject; } - internal static async Task UrlGetToXML(string request, Dictionary cookies = null, string referer = null) { + internal static async Task UrlGetToXML(string request, Dictionary cookies = null, string referer = null, bool fakeUserAgent = false) { if (string.IsNullOrEmpty(request)) { return null; } - string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false); + string content = await UrlGetToContent(request, cookies, referer, fakeUserAgent).ConfigureAwait(false); if (string.IsNullOrEmpty(content)) { return null; } @@ -237,7 +302,7 @@ namespace ArchiSteamFarm { try { xmlDocument.LoadXml(content); } catch (XmlException e) { - Logging.LogGenericException("WebBrowser", e); + Logging.LogGenericException(e); return null; }