mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-20 16:28:38 +00:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54ad58a22d | ||
|
|
790e6baf46 | ||
|
|
c8fb715558 | ||
|
|
2ab5e6013d | ||
|
|
3e0c34e62c | ||
|
|
65b31e5537 | ||
|
|
62a6e38e47 | ||
|
|
0b50a45336 | ||
|
|
8d1d162b02 | ||
|
|
dbe13a1965 | ||
|
|
fc13633f5e | ||
|
|
d0cc10f3c6 | ||
|
|
567931a4cc | ||
|
|
396dc17ab2 | ||
|
|
288cc29338 | ||
|
|
844ca7da94 | ||
|
|
b14b9f87c7 | ||
|
|
8aa086cc27 | ||
|
|
cf00989d84 | ||
|
|
8f2f85282c | ||
|
|
fa12ffd9d0 | ||
|
|
ecb27adedd | ||
|
|
6e9be09944 | ||
|
|
6a79a89a10 | ||
|
|
d67be4f092 | ||
|
|
a8e1039e32 | ||
|
|
2ad9d9e197 | ||
|
|
fd6e2c72d7 | ||
|
|
1eed0f7647 | ||
|
|
c018c08260 | ||
|
|
72fa98cb89 | ||
|
|
71215d695e |
@@ -32,6 +32,16 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal sealed class ArchiHandler : ClientMsgHandler {
|
internal sealed class ArchiHandler : ClientMsgHandler {
|
||||||
|
private readonly Bot Bot;
|
||||||
|
|
||||||
|
internal ArchiHandler(Bot bot) {
|
||||||
|
if (bot == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bot = bot;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
____ _ _ _ _
|
____ _ _ _ _
|
||||||
/ ___| __ _ | || || |__ __ _ ___ | | __ ___
|
/ ___| __ _ | || || |__ __ _ ___ | | __ ___
|
||||||
@@ -257,10 +267,11 @@ namespace ArchiSteamFarm {
|
|||||||
request.Body.key = key;
|
request.Body.key = key;
|
||||||
|
|
||||||
Client.Send(request);
|
Client.Send(request);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await new AsyncJob<PurchaseResponseCallback>(Client, request.SourceJobID);
|
return await new AsyncJob<PurchaseResponseCallback>(Client, request.SourceJobID);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e, Bot.BotName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ namespace ArchiSteamFarm {
|
|||||||
private static int Timeout = GlobalConfig.DefaultHttpTimeout * 1000;
|
private static int Timeout = GlobalConfig.DefaultHttpTimeout * 1000;
|
||||||
|
|
||||||
private readonly Bot Bot;
|
private readonly Bot Bot;
|
||||||
private readonly Dictionary<string, string> Cookie = new Dictionary<string, string>(4);
|
|
||||||
private readonly SemaphoreSlim SessionSemaphore = new SemaphoreSlim(1);
|
private readonly SemaphoreSlim SessionSemaphore = new SemaphoreSlim(1);
|
||||||
|
private readonly WebBrowser WebBrowser;
|
||||||
|
|
||||||
private DateTime LastSessionRefreshCheck = DateTime.MinValue;
|
private DateTime LastSessionRefreshCheck = DateTime.MinValue;
|
||||||
|
|
||||||
@@ -60,6 +60,8 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bot = bot;
|
Bot = bot;
|
||||||
|
|
||||||
|
WebBrowser = new WebBrowser(bot.BotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool Init(SteamClient steamClient, string webAPIUserNonce, string parentalPin) {
|
internal bool Init(SteamClient steamClient, string webAPIUserNonce, string parentalPin) {
|
||||||
@@ -114,15 +116,13 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
Logging.LogGenericInfo("Success!", Bot.BotName);
|
Logging.LogGenericInfo("Success!", Bot.BotName);
|
||||||
|
|
||||||
string steamLogin = authResult["token"].AsString();
|
WebBrowser.CookieContainer.Add(new Cookie("sessionid", sessionID, "/", "." + SteamCommunity));
|
||||||
string steamLoginSecure = authResult["tokensecure"].AsString();
|
|
||||||
|
|
||||||
Cookie["sessionid"] = sessionID;
|
string steamLogin = authResult["token"].Value;
|
||||||
Cookie["steamLogin"] = steamLogin;
|
WebBrowser.CookieContainer.Add(new Cookie("steamLogin", steamLogin, "/", "." + SteamCommunity));
|
||||||
Cookie["steamLoginSecure"] = steamLoginSecure;
|
|
||||||
|
|
||||||
// The below is used for display purposes only
|
string steamLoginSecure = authResult["tokensecure"].Value;
|
||||||
Cookie["webTradeEligibility"] = "{\"allowed\":0,\"reason\":0,\"allowed_at_time\":0,\"steamguard_required_days\":0,\"sales_this_year\":0,\"max_sales_per_year\":0,\"forms_requested\":0}";
|
WebBrowser.CookieContainer.Add(new Cookie("steamLoginSecure", steamLoginSecure, "/", "." + SteamCommunity));
|
||||||
|
|
||||||
if (!UnlockParentalAccount(parentalPin).Result) {
|
if (!UnlockParentalAccount(parentalPin).Result) {
|
||||||
return false;
|
return false;
|
||||||
@@ -135,7 +135,7 @@ namespace ArchiSteamFarm {
|
|||||||
internal async Task<bool?> IsLoggedIn() {
|
internal async Task<bool?> IsLoggedIn() {
|
||||||
HtmlDocument htmlDocument = null;
|
HtmlDocument htmlDocument = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/profile", Cookie).ConfigureAwait(false);
|
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/profile").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htmlDocument == null) {
|
if (htmlDocument == null) {
|
||||||
@@ -186,7 +186,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
XmlDocument response = null;
|
XmlDocument response = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||||
response = await WebBrowser.UrlGetToXML(request, Cookie).ConfigureAwait(false);
|
response = await WebBrowser.UrlGetToXML(request).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
@@ -291,8 +291,9 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sessionID;
|
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
if (string.IsNullOrEmpty(sessionID)) {
|
||||||
|
Logging.LogNullError("sessionID");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,12 +304,12 @@ namespace ArchiSteamFarm {
|
|||||||
{"action", "join"}
|
{"action", "join"}
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlPost(request, data, Cookie).ConfigureAwait(false);
|
result = await WebBrowser.UrlPost(request, data).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -325,8 +326,9 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sessionID;
|
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
if (string.IsNullOrEmpty(sessionID)) {
|
||||||
|
Logging.LogNullError("sessionID");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,12 +341,12 @@ namespace ArchiSteamFarm {
|
|||||||
{"tradeofferid", tradeID.ToString()}
|
{"tradeofferid", tradeID.ToString()}
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false);
|
result = await WebBrowser.UrlPost(request, data, referer).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -359,7 +361,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
JObject jObject = null;
|
JObject jObject = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && jObject == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && jObject == null; i++) {
|
||||||
jObject = await WebBrowser.UrlGetToJObject(SteamCommunityURL + "/my/inventory/json/753/6?trading=1", Cookie).ConfigureAwait(false);
|
jObject = await WebBrowser.UrlGetToJObject(SteamCommunityURL + "/my/inventory/json/753/6?trading=1").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jObject == null) {
|
if (jObject == null) {
|
||||||
@@ -394,8 +396,9 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sessionID;
|
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
if (string.IsNullOrEmpty(sessionID)) {
|
||||||
|
Logging.LogNullError("sessionID");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,12 +437,12 @@ namespace ArchiSteamFarm {
|
|||||||
{"trade_offer_create_params", string.IsNullOrEmpty(token) ? "" : $"{{\"trade_offer_access_token\":\"{token}\"}}"}
|
{"trade_offer_create_params", string.IsNullOrEmpty(token) ? "" : $"{{\"trade_offer_access_token\":\"{token}\"}}"}
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false);
|
result = await WebBrowser.UrlPost(request, data, referer).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -459,7 +462,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
HtmlDocument htmlDocument = null;
|
HtmlDocument htmlDocument = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/badges?l=english&p=" + page, Cookie).ConfigureAwait(false);
|
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/badges?p=" + page).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htmlDocument == null) {
|
if (htmlDocument == null) {
|
||||||
@@ -481,7 +484,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
HtmlDocument htmlDocument = null;
|
HtmlDocument htmlDocument = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && htmlDocument == null; i++) {
|
||||||
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/gamecards/" + appID + "?l=english", Cookie).ConfigureAwait(false);
|
htmlDocument = await WebBrowser.UrlGetToHtmlDocument(SteamCommunityURL + "/my/gamecards/" + appID).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htmlDocument == null) {
|
if (htmlDocument == null) {
|
||||||
@@ -497,12 +500,12 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlGet(SteamCommunityURL + "/my/inventory", Cookie).ConfigureAwait(false);
|
result = await WebBrowser.UrlGet(SteamCommunityURL + "/my/inventory").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -519,8 +522,9 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sessionID;
|
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamCommunityURL, "sessionid");
|
||||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
if (string.IsNullOrEmpty(sessionID)) {
|
||||||
|
Logging.LogNullError("sessionID");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,12 +533,12 @@ namespace ArchiSteamFarm {
|
|||||||
{ "sessionid", sessionID }
|
{ "sessionid", sessionID }
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = null;
|
bool result = false;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && !result; i++) {
|
||||||
response = await WebBrowser.UrlPost(request, data, Cookie).ConfigureAwait(false);
|
result = await WebBrowser.UrlPost(request, data).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (!result) {
|
||||||
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -557,7 +561,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
HttpResponseMessage response = null;
|
HttpResponseMessage response = null;
|
||||||
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
for (byte i = 0; i < WebBrowser.MaxRetries && response == null; i++) {
|
||||||
response = await WebBrowser.UrlPost(request, data, Cookie, referer).ConfigureAwait(false);
|
response = await WebBrowser.UrlPostToResponse(request, data, referer).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
@@ -567,10 +571,13 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
IEnumerable<string> setCookieValues;
|
IEnumerable<string> setCookieValues;
|
||||||
if (!response.Headers.TryGetValues("Set-Cookie", out setCookieValues)) {
|
if (!response.Headers.TryGetValues("Set-Cookie", out setCookieValues)) {
|
||||||
|
response.Dispose();
|
||||||
Logging.LogNullError("setCookieValues", Bot.BotName);
|
Logging.LogNullError("setCookieValues", Bot.BotName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.Dispose();
|
||||||
|
|
||||||
foreach (string setCookieValue in setCookieValues) {
|
foreach (string setCookieValue in setCookieValues) {
|
||||||
if (!setCookieValue.Contains("steamparental=")) {
|
if (!setCookieValue.Contains("steamparental=")) {
|
||||||
continue;
|
continue;
|
||||||
@@ -583,8 +590,8 @@ namespace ArchiSteamFarm {
|
|||||||
setCookie = setCookie.Substring(0, index);
|
setCookie = setCookie.Substring(0, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cookie["steamparental"] = setCookie;
|
|
||||||
Logging.LogGenericInfo("Success!", Bot.BotName);
|
Logging.LogGenericInfo("Success!", Bot.BotName);
|
||||||
|
WebBrowser.CookieContainer.Add(new Cookie("steamparental", setCookie, "/", "." + SteamCommunity));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace ArchiSteamFarm {
|
|||||||
internal sealed class Bot {
|
internal sealed class Bot {
|
||||||
private const ulong ArchiSCFarmGroup = 103582791440160998;
|
private const ulong ArchiSCFarmGroup = 103582791440160998;
|
||||||
private const ushort CallbackSleep = 500; // In miliseconds
|
private const ushort CallbackSleep = 500; // In miliseconds
|
||||||
|
private const ushort MaxSteamMessageLength = 2048;
|
||||||
|
|
||||||
internal static readonly Dictionary<string, Bot> Bots = new Dictionary<string, Bot>();
|
internal static readonly Dictionary<string, Bot> Bots = new Dictionary<string, Bot>();
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ namespace ArchiSteamFarm {
|
|||||||
internal bool KeepRunning { get; private set; }
|
internal bool KeepRunning { get; private set; }
|
||||||
|
|
||||||
private bool InvalidPassword, LoggedInElsewhere;
|
private bool InvalidPassword, LoggedInElsewhere;
|
||||||
private string AuthCode, TwoFactorAuth;
|
private string AuthCode, TwoFactorCode;
|
||||||
|
|
||||||
internal static async Task RefreshCMs(uint cellID) {
|
internal static async Task RefreshCMs(uint cellID) {
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
@@ -163,7 +164,7 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchiHandler = new ArchiHandler();
|
ArchiHandler = new ArchiHandler(this);
|
||||||
SteamClient.AddHandler(ArchiHandler);
|
SteamClient.AddHandler(ArchiHandler);
|
||||||
|
|
||||||
CallbackManager = new CallbackManager(SteamClient);
|
CallbackManager = new CallbackManager(SteamClient);
|
||||||
@@ -199,7 +200,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
if (AcceptConfirmationsTimer == null && BotConfig.AcceptConfirmationsPeriod > 0) {
|
if (AcceptConfirmationsTimer == null && BotConfig.AcceptConfirmationsPeriod > 0) {
|
||||||
AcceptConfirmationsTimer = new Timer(
|
AcceptConfirmationsTimer = new Timer(
|
||||||
async e => await AcceptConfirmations().ConfigureAwait(false),
|
async e => await AcceptConfirmations(true).ConfigureAwait(false),
|
||||||
null,
|
null,
|
||||||
TimeSpan.FromMinutes(BotConfig.AcceptConfirmationsPeriod), // Delay
|
TimeSpan.FromMinutes(BotConfig.AcceptConfirmationsPeriod), // Delay
|
||||||
TimeSpan.FromMinutes(BotConfig.AcceptConfirmationsPeriod) // Period
|
TimeSpan.FromMinutes(BotConfig.AcceptConfirmationsPeriod) // Period
|
||||||
@@ -223,7 +224,7 @@ namespace ArchiSteamFarm {
|
|||||||
Start().Forget();
|
Start().Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task AcceptConfirmations(Confirmation.ConfirmationType allowedConfirmationType = Confirmation.ConfirmationType.Unknown) {
|
internal async Task AcceptConfirmations(bool confirm, Confirmation.ConfirmationType allowedConfirmationType = Confirmation.ConfirmationType.Unknown) {
|
||||||
if (BotDatabase.SteamGuardAccount == null) {
|
if (BotDatabase.SteamGuardAccount == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -243,10 +244,14 @@ namespace ArchiSteamFarm {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (confirm) {
|
||||||
BotDatabase.SteamGuardAccount.AcceptConfirmation(confirmation);
|
BotDatabase.SteamGuardAccount.AcceptConfirmation(confirmation);
|
||||||
|
} else {
|
||||||
|
BotDatabase.SteamGuardAccount.DenyConfirmation(confirmation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (SteamGuardAccount.WGTokenInvalidException) {
|
} catch (SteamGuardAccount.WGTokenInvalidException) {
|
||||||
Logging.LogGenericWarning("Accepting confirmation: Failed!", BotName);
|
Logging.LogGenericWarning("Handling confirmation: Failed!", BotName);
|
||||||
Logging.LogGenericWarning("Confirmation could not be accepted because of invalid token exception", BotName);
|
Logging.LogGenericWarning("Confirmation could not be accepted because of invalid token exception", BotName);
|
||||||
Logging.LogGenericWarning("If issue persists, consider removing and readding ASF 2FA", BotName);
|
Logging.LogGenericWarning("If issue persists, consider removing and readding ASF 2FA", BotName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -267,13 +272,21 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userNonce = await SteamUser.RequestWebAPIUserNonce();
|
SteamUser.WebAPIUserNonceCallback callback;
|
||||||
if (userNonce == null || userNonce.Result != EResult.OK || string.IsNullOrEmpty(userNonce.Nonce)) {
|
|
||||||
|
try {
|
||||||
|
callback = await SteamUser.RequestWebAPIUserNonce();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logging.LogGenericException(e, BotName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback == null || callback.Result != EResult.OK || string.IsNullOrEmpty(callback.Nonce)) {
|
||||||
Start().Forget();
|
Start().Forget();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ArchiWebHandler.Init(SteamClient, userNonce.Nonce, BotConfig.SteamParentalPIN)) {
|
if (!ArchiWebHandler.Init(SteamClient, callback.Nonce, BotConfig.SteamParentalPIN)) {
|
||||||
Start().Forget();
|
Start().Forget();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -297,17 +310,19 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!message.StartsWith("!")) {
|
if (!message.StartsWith("!")) {
|
||||||
return await ResponseRedeem(steamID, BotName, message, true).ConfigureAwait(false);
|
return await ResponseRedeem(steamID, message.Replace(",", Environment.NewLine), true).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message.Contains(" ")) {
|
if (!message.Contains(" ")) {
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case "!2fa":
|
case "!2fa":
|
||||||
return Response2FA(steamID);
|
return Response2FA(steamID);
|
||||||
|
case "!2fano":
|
||||||
|
return await Response2FAConfirm(steamID, false).ConfigureAwait(false);
|
||||||
case "!2faoff":
|
case "!2faoff":
|
||||||
return Response2FAOff(steamID);
|
return Response2FAOff(steamID);
|
||||||
case "!2faok":
|
case "!2faok":
|
||||||
return await Response2FAOK(steamID).ConfigureAwait(false);
|
return await Response2FAConfirm(steamID, true).ConfigureAwait(false);
|
||||||
case "!exit":
|
case "!exit":
|
||||||
return ResponseExit(steamID);
|
return ResponseExit(steamID);
|
||||||
case "!farm":
|
case "!farm":
|
||||||
@@ -338,10 +353,12 @@ namespace ArchiSteamFarm {
|
|||||||
switch (args[0]) {
|
switch (args[0]) {
|
||||||
case "!2fa":
|
case "!2fa":
|
||||||
return Response2FA(steamID, args[1]);
|
return Response2FA(steamID, args[1]);
|
||||||
|
case "!2fano":
|
||||||
|
return await Response2FAConfirm(steamID, args[1], false).ConfigureAwait(false);
|
||||||
case "!2faoff":
|
case "!2faoff":
|
||||||
return Response2FAOff(steamID, args[1]);
|
return Response2FAOff(steamID, args[1]);
|
||||||
case "!2faok":
|
case "!2faok":
|
||||||
return await Response2FAOK(steamID, args[1]).ConfigureAwait(false);
|
return await Response2FAConfirm(steamID, args[1], true).ConfigureAwait(false);
|
||||||
case "!addlicense":
|
case "!addlicense":
|
||||||
if (args.Length > 2) {
|
if (args.Length > 2) {
|
||||||
return await ResponseAddLicense(steamID, args[1], args[2]).ConfigureAwait(false);
|
return await ResponseAddLicense(steamID, args[1], args[2]).ConfigureAwait(false);
|
||||||
@@ -370,9 +387,9 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
case "!redeem":
|
case "!redeem":
|
||||||
if (args.Length > 2) {
|
if (args.Length > 2) {
|
||||||
return await ResponseRedeem(steamID, args[1], args[2], false).ConfigureAwait(false);
|
return await ResponseRedeem(steamID, args[1], args[2].Replace(",", Environment.NewLine), false).ConfigureAwait(false);
|
||||||
} else {
|
} else {
|
||||||
return await ResponseRedeem(steamID, BotName, args[1], false).ConfigureAwait(false);
|
return await ResponseRedeem(steamID, BotName, args[1].Replace(",", Environment.NewLine), false).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
case "!start":
|
case "!start":
|
||||||
return await ResponseStart(steamID, args[1]).ConfigureAwait(false);
|
return await ResponseStart(steamID, args[1]).ConfigureAwait(false);
|
||||||
@@ -393,7 +410,7 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2FA tokens are expiring soon, use limiter only when we don't have any pending
|
// 2FA tokens are expiring soon, use limiter only when we don't have any pending
|
||||||
if (TwoFactorAuth == null) {
|
if (TwoFactorCode == null) {
|
||||||
await Program.LimitSteamRequestsAsync().ConfigureAwait(false);
|
await Program.LimitSteamRequestsAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +461,9 @@ namespace ArchiSteamFarm {
|
|||||||
// But here we're dealing with WinAuth authenticator
|
// But here we're dealing with WinAuth authenticator
|
||||||
Logging.LogGenericInfo("ASF requires a few more steps to complete authenticator import...", BotName);
|
Logging.LogGenericInfo("ASF requires a few more steps to complete authenticator import...", BotName);
|
||||||
|
|
||||||
InitializeLoginAndPassword();
|
if (!InitializeLoginAndPassword()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UserLogin userLogin = new UserLogin(BotConfig.SteamLogin, BotConfig.SteamPassword);
|
UserLogin userLogin = new UserLogin(BotConfig.SteamLogin, BotConfig.SteamPassword);
|
||||||
LoginResult loginResult;
|
LoginResult loginResult;
|
||||||
@@ -452,6 +471,9 @@ namespace ArchiSteamFarm {
|
|||||||
switch (loginResult) {
|
switch (loginResult) {
|
||||||
case LoginResult.Need2FA:
|
case LoginResult.Need2FA:
|
||||||
userLogin.TwoFactorCode = Program.GetUserInput(Program.EUserInputType.TwoFactorAuthentication, BotName);
|
userLogin.TwoFactorCode = Program.GetUserInput(Program.EUserInputType.TwoFactorAuthentication, BotName);
|
||||||
|
if (string.IsNullOrEmpty(userLogin.TwoFactorCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Logging.LogGenericError("Unhandled situation: " + loginResult, BotName);
|
Logging.LogGenericError("Unhandled situation: " + loginResult, BotName);
|
||||||
@@ -572,7 +594,7 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (await ArchiWebHandler.SendTradeOffer(inventory, BotConfig.SteamMasterID, BotConfig.SteamTradeToken).ConfigureAwait(false)) {
|
if (await ArchiWebHandler.SendTradeOffer(inventory, BotConfig.SteamMasterID, BotConfig.SteamTradeToken).ConfigureAwait(false)) {
|
||||||
await AcceptConfirmations(Confirmation.ConfirmationType.Trade).ConfigureAwait(false);
|
await AcceptConfirmations(true, Confirmation.ConfirmationType.Trade).ConfigureAwait(false);
|
||||||
return "Trade offer sent successfully!";
|
return "Trade offer sent successfully!";
|
||||||
} else {
|
} else {
|
||||||
return "Trade offer failed due to error!";
|
return "Trade offer failed due to error!";
|
||||||
@@ -647,7 +669,7 @@ namespace ArchiSteamFarm {
|
|||||||
return bot.Response2FAOff(steamID);
|
return bot.Response2FAOff(steamID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> Response2FAOK(ulong steamID) {
|
private async Task<string> Response2FAConfirm(ulong steamID, bool confirm) {
|
||||||
if (steamID == 0 || !IsMaster(steamID)) {
|
if (steamID == 0 || !IsMaster(steamID)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -656,11 +678,11 @@ namespace ArchiSteamFarm {
|
|||||||
return "That bot doesn't have ASF 2FA enabled!";
|
return "That bot doesn't have ASF 2FA enabled!";
|
||||||
}
|
}
|
||||||
|
|
||||||
await AcceptConfirmations().ConfigureAwait(false);
|
await AcceptConfirmations(confirm).ConfigureAwait(false);
|
||||||
return "Done!";
|
return "Done!";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> Response2FAOK(ulong steamID, string botName) {
|
private static async Task<string> Response2FAConfirm(ulong steamID, string botName, bool confirm) {
|
||||||
if (steamID == 0 || string.IsNullOrEmpty(botName)) {
|
if (steamID == 0 || string.IsNullOrEmpty(botName)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -670,7 +692,7 @@ namespace ArchiSteamFarm {
|
|||||||
return "Couldn't find any bot named " + botName + "!";
|
return "Couldn't find any bot named " + botName + "!";
|
||||||
}
|
}
|
||||||
|
|
||||||
return await bot.Response2FAOK(steamID).ConfigureAwait(false);
|
return await bot.Response2FAConfirm(steamID, confirm).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ResponseExit(ulong steamID) {
|
private static string ResponseExit(ulong steamID) {
|
||||||
@@ -682,8 +704,13 @@ namespace ArchiSteamFarm {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment.Exit(0);
|
// Schedule the task after some time so user can receive response
|
||||||
return null;
|
Task.Run(async () => {
|
||||||
|
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
||||||
|
Program.Exit();
|
||||||
|
}).Forget();
|
||||||
|
|
||||||
|
return "Done!";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ResponseFarm(ulong steamID) {
|
private string ResponseFarm(ulong steamID) {
|
||||||
@@ -739,92 +766,74 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder response = new StringBuilder();
|
StringBuilder response = new StringBuilder();
|
||||||
using (StringReader reader = new StringReader(message)) {
|
using (StringReader reader = new StringReader(message))
|
||||||
|
using (IEnumerator<Bot> iterator = Bots.Values.GetEnumerator()) {
|
||||||
string key = reader.ReadLine();
|
string key = reader.ReadLine();
|
||||||
IEnumerator<Bot> iterator = Bots.Values.GetEnumerator();
|
|
||||||
Bot currentBot = this;
|
Bot currentBot = this;
|
||||||
while (key != null) {
|
while (!string.IsNullOrEmpty(key) && currentBot != null) {
|
||||||
if (currentBot == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validate && !IsValidCdKey(key)) {
|
if (validate && !IsValidCdKey(key)) {
|
||||||
key = reader.ReadLine();
|
key = reader.ReadLine(); // Next key
|
||||||
continue;
|
continue; // Without changing the bot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentBot.SteamClient.IsConnected) {
|
||||||
ArchiHandler.PurchaseResponseCallback result = await currentBot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
ArchiHandler.PurchaseResponseCallback result = await currentBot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
||||||
if (result == null) {
|
if (result != null) {
|
||||||
break;
|
switch (result.PurchaseResult) {
|
||||||
}
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.DuplicatedKey:
|
||||||
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.InvalidKey:
|
||||||
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK:
|
||||||
|
response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + result.PurchaseResult + " | Items: " + string.Join("", result.Items));
|
||||||
|
|
||||||
var purchaseResult = result.PurchaseResult;
|
key = reader.ReadLine(); // Next key
|
||||||
var items = result.Items;
|
break; // Next bot (if needed)
|
||||||
|
|
||||||
switch (purchaseResult) {
|
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.AlreadyOwned:
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.AlreadyOwned:
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.BaseGameRequired:
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.BaseGameRequired:
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OnCooldown:
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OnCooldown:
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.RegionLocked:
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.RegionLocked:
|
||||||
response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + purchaseResult + " | Items: " + string.Join("", items));
|
response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + result.PurchaseResult + " | Items: " + string.Join("", result.Items));
|
||||||
|
|
||||||
|
if (!BotConfig.ForwardKeysToOtherBots) {
|
||||||
|
key = reader.ReadLine(); // Next key
|
||||||
|
break; // Next bot (if needed)
|
||||||
|
}
|
||||||
|
|
||||||
if (BotConfig.DistributeKeys) {
|
if (BotConfig.DistributeKeys) {
|
||||||
do {
|
break; // Next bot, without changing key
|
||||||
if (iterator.MoveNext()) {
|
|
||||||
currentBot = iterator.Current;
|
|
||||||
} else {
|
|
||||||
currentBot = null;
|
|
||||||
}
|
|
||||||
} while (currentBot == this);
|
|
||||||
|
|
||||||
if (!BotConfig.ForwardKeysToOtherBots) {
|
|
||||||
key = reader.ReadLine();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!BotConfig.ForwardKeysToOtherBots) {
|
|
||||||
key = reader.ReadLine();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alreadyHandled = false;
|
bool alreadyHandled = false;
|
||||||
foreach (Bot bot in Bots.Values) {
|
foreach (Bot bot in Bots.Values) {
|
||||||
if (alreadyHandled) {
|
if (bot == this || !bot.SteamClient.IsConnected) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bot == this) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchiHandler.PurchaseResponseCallback otherResult = await bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
ArchiHandler.PurchaseResponseCallback otherResult = await bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
||||||
|
|
||||||
if (otherResult == null) {
|
if (otherResult == null) {
|
||||||
break; // We're done with this key
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var otherPurchaseResult = otherResult.PurchaseResult;
|
switch (otherResult.PurchaseResult) {
|
||||||
var otherItems = otherResult.Items;
|
|
||||||
|
|
||||||
switch (otherPurchaseResult) {
|
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK:
|
|
||||||
alreadyHandled = true; // We're done with this key
|
|
||||||
response.Append(Environment.NewLine + "<" + bot.BotName + "> Key: " + key + " | Status: " + otherPurchaseResult + " | Items: " + string.Join("", otherItems));
|
|
||||||
break;
|
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.DuplicatedKey:
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.DuplicatedKey:
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.InvalidKey:
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.InvalidKey:
|
||||||
alreadyHandled = true; // This key doesn't work, don't try to redeem it anymore
|
|
||||||
response.Append(Environment.NewLine + "<" + bot.BotName + "> Key: " + key + " | Status: " + otherPurchaseResult + " | Items: " + string.Join("", otherItems));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
response.Append(Environment.NewLine + "<" + bot.BotName + "> Key: " + key + " | Status: " + otherPurchaseResult + " | Items: " + string.Join("", otherItems));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key = reader.ReadLine();
|
|
||||||
break;
|
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK:
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK:
|
||||||
response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + purchaseResult + " | Items: " + string.Join("", items));
|
alreadyHandled = true; // This key is already handled, as we either redeemed it or we're sure it's dupe/invalid
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Append(Environment.NewLine + "<" + bot.BotName + "> Key: " + key + " | Status: " + otherResult.PurchaseResult + " | Items: " + string.Join("", otherResult.Items));
|
||||||
|
|
||||||
|
if (alreadyHandled) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key = reader.ReadLine(); // Next key
|
||||||
|
break; // Next bot (if needed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (BotConfig.DistributeKeys) {
|
if (BotConfig.DistributeKeys) {
|
||||||
do {
|
do {
|
||||||
if (iterator.MoveNext()) {
|
if (iterator.MoveNext()) {
|
||||||
@@ -832,24 +841,7 @@ namespace ArchiSteamFarm {
|
|||||||
} else {
|
} else {
|
||||||
currentBot = null;
|
currentBot = null;
|
||||||
}
|
}
|
||||||
} while (currentBot == this);
|
} while (currentBot == this || (currentBot != null && !currentBot.SteamClient.IsConnected));
|
||||||
}
|
|
||||||
key = reader.ReadLine();
|
|
||||||
break;
|
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.DuplicatedKey:
|
|
||||||
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.InvalidKey:
|
|
||||||
response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + purchaseResult + " | Items: " + string.Join("", items));
|
|
||||||
if (BotConfig.DistributeKeys && !BotConfig.ForwardKeysToOtherBots) {
|
|
||||||
do {
|
|
||||||
if (iterator.MoveNext()) {
|
|
||||||
currentBot = iterator.Current;
|
|
||||||
} else {
|
|
||||||
currentBot = null;
|
|
||||||
}
|
|
||||||
} while (currentBot == this);
|
|
||||||
}
|
|
||||||
key = reader.ReadLine();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -899,8 +891,13 @@ namespace ArchiSteamFarm {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Schedule the task after some time so user can receive response
|
||||||
|
Task.Run(async () => {
|
||||||
|
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
||||||
Program.Restart();
|
Program.Restart();
|
||||||
return null;
|
}).Forget();
|
||||||
|
|
||||||
|
return "Done!";
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ResponseAddLicense(ulong steamID, HashSet<uint> gameIDs) {
|
private async Task<string> ResponseAddLicense(ulong steamID, HashSet<uint> gameIDs) {
|
||||||
@@ -949,8 +946,8 @@ namespace ArchiSteamFarm {
|
|||||||
return await bot.ResponseAddLicense(steamID, gamesToRedeem).ConfigureAwait(false);
|
return await bot.ResponseAddLicense(steamID, gamesToRedeem).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ResponseOwns(ulong steamID, string games) {
|
private async Task<string> ResponseOwns(ulong steamID, string query) {
|
||||||
if (steamID == 0 || string.IsNullOrEmpty(games) || !IsMaster(steamID)) {
|
if (steamID == 0 || string.IsNullOrEmpty(query) || !IsMaster(steamID)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -959,37 +956,42 @@ namespace ArchiSteamFarm {
|
|||||||
return "List of owned games is empty!";
|
return "List of owned games is empty!";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this is uint
|
|
||||||
uint appID;
|
|
||||||
if (uint.TryParse(games, out appID)) {
|
|
||||||
string ownedName;
|
|
||||||
if (ownedGames.TryGetValue(appID, out ownedName)) {
|
|
||||||
return "Owned already: " + appID + " | " + ownedName;
|
|
||||||
} else {
|
|
||||||
return "Not owned yet: " + appID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder response = new StringBuilder();
|
StringBuilder response = new StringBuilder();
|
||||||
|
|
||||||
// This is a string
|
string[] games = query.Split(',');
|
||||||
foreach (KeyValuePair<uint, string> game in ownedGames) {
|
foreach (string game in games) {
|
||||||
if (game.Value.IndexOf(games, StringComparison.OrdinalIgnoreCase) < 0) {
|
// Check if this is appID
|
||||||
|
uint appID;
|
||||||
|
if (uint.TryParse(game, out appID)) {
|
||||||
|
string ownedName;
|
||||||
|
if (ownedGames.TryGetValue(appID, out ownedName)) {
|
||||||
|
response.Append(Environment.NewLine + "Owned already: " + appID + " | " + ownedName);
|
||||||
|
} else {
|
||||||
|
response.Append(Environment.NewLine + "Not owned yet: " + appID);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.AppendLine(Environment.NewLine + "Owned already: " + game.Key + " | " + game.Value);
|
// This is a string, so check our entire library
|
||||||
|
foreach (KeyValuePair<uint, string> ownedGame in ownedGames) {
|
||||||
|
if (ownedGame.Value.IndexOf(game, StringComparison.OrdinalIgnoreCase) < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Append(Environment.NewLine + "Owned already: " + ownedGame.Key + " | " + ownedGame.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.Length > 0) {
|
if (response.Length > 0) {
|
||||||
return response.ToString();
|
return response.ToString();
|
||||||
} else {
|
} else {
|
||||||
return "Not owned yet: " + games;
|
return "Not owned yet: " + query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> ResponseOwns(ulong steamID, string botName, string games) {
|
private static async Task<string> ResponseOwns(ulong steamID, string botName, string query) {
|
||||||
if (steamID == 0 || string.IsNullOrEmpty(botName) || string.IsNullOrEmpty(games)) {
|
if (steamID == 0 || string.IsNullOrEmpty(botName) || string.IsNullOrEmpty(query)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -998,7 +1000,7 @@ namespace ArchiSteamFarm {
|
|||||||
return "Couldn't find any bot named " + botName + "!";
|
return "Couldn't find any bot named " + botName + "!";
|
||||||
}
|
}
|
||||||
|
|
||||||
return await bot.ResponseOwns(steamID, games).ConfigureAwait(false);
|
return await bot.ResponseOwns(steamID, query).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ResponsePlay(ulong steamID, HashSet<uint> gameIDs) {
|
private async Task<string> ResponsePlay(ulong steamID, HashSet<uint> gameIDs) {
|
||||||
@@ -1147,9 +1149,31 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (new SteamID(steamID).IsChatAccount) {
|
if (new SteamID(steamID).IsChatAccount) {
|
||||||
SteamFriends.SendChatRoomMessage(steamID, EChatEntryType.ChatMsg, message);
|
SendMessageToChannel(steamID, message);
|
||||||
} else {
|
} else {
|
||||||
SteamFriends.SendChatMessage(steamID, EChatEntryType.ChatMsg, message);
|
SendMessageToUser(steamID, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendMessageToChannel(ulong steamID, string message) {
|
||||||
|
if (steamID == 0 || string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < message.Length; i += MaxSteamMessageLength - 6) {
|
||||||
|
string messagePart = (i > 0 ? "..." : "") + message.Substring(i, Math.Min(MaxSteamMessageLength - 6, message.Length - i)) + (MaxSteamMessageLength - 6 < message.Length - i ? "..." : "");
|
||||||
|
SteamFriends.SendChatRoomMessage(steamID, EChatEntryType.ChatMsg, messagePart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendMessageToUser(ulong steamID, string message) {
|
||||||
|
if (steamID == 0 || string.IsNullOrEmpty(message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < message.Length; i += MaxSteamMessageLength - 6) {
|
||||||
|
string messagePart = (i > 0 ? "..." : "") + message.Substring(i, Math.Min(MaxSteamMessageLength - 6, message.Length - i)) + (MaxSteamMessageLength - 6 < message.Length - i ? "..." : "");
|
||||||
|
SteamFriends.SendChatMessage(steamID, EChatEntryType.ChatMsg, messagePart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1160,7 +1184,9 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
Logging.LogGenericInfo("Linking new ASF MobileAuthenticator...", BotName);
|
Logging.LogGenericInfo("Linking new ASF MobileAuthenticator...", BotName);
|
||||||
|
|
||||||
InitializeLoginAndPassword();
|
if (!InitializeLoginAndPassword()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UserLogin userLogin = new UserLogin(BotConfig.SteamLogin, BotConfig.SteamPassword);
|
UserLogin userLogin = new UserLogin(BotConfig.SteamLogin, BotConfig.SteamPassword);
|
||||||
LoginResult loginResult;
|
LoginResult loginResult;
|
||||||
@@ -1168,6 +1194,9 @@ namespace ArchiSteamFarm {
|
|||||||
switch (loginResult) {
|
switch (loginResult) {
|
||||||
case LoginResult.NeedEmail:
|
case LoginResult.NeedEmail:
|
||||||
userLogin.EmailCode = Program.GetUserInput(Program.EUserInputType.SteamGuard, BotName);
|
userLogin.EmailCode = Program.GetUserInput(Program.EUserInputType.SteamGuard, BotName);
|
||||||
|
if (string.IsNullOrEmpty(userLogin.EmailCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Logging.LogGenericError("Unhandled situation: " + loginResult, BotName);
|
Logging.LogGenericError("Unhandled situation: " + loginResult, BotName);
|
||||||
@@ -1182,6 +1211,9 @@ namespace ArchiSteamFarm {
|
|||||||
switch (linkResult) {
|
switch (linkResult) {
|
||||||
case AuthenticatorLinker.LinkResult.MustProvidePhoneNumber:
|
case AuthenticatorLinker.LinkResult.MustProvidePhoneNumber:
|
||||||
authenticatorLinker.PhoneNumber = Program.GetUserInput(Program.EUserInputType.PhoneNumber, BotName);
|
authenticatorLinker.PhoneNumber = Program.GetUserInput(Program.EUserInputType.PhoneNumber, BotName);
|
||||||
|
if (string.IsNullOrEmpty(authenticatorLinker.PhoneNumber)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Logging.LogGenericError("Unhandled situation: " + linkResult, BotName);
|
Logging.LogGenericError("Unhandled situation: " + linkResult, BotName);
|
||||||
@@ -1191,7 +1223,12 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
BotDatabase.SteamGuardAccount = authenticatorLinker.LinkedAccount;
|
BotDatabase.SteamGuardAccount = authenticatorLinker.LinkedAccount;
|
||||||
|
|
||||||
AuthenticatorLinker.FinalizeResult finalizeResult = authenticatorLinker.FinalizeAddAuthenticator(Program.GetUserInput(Program.EUserInputType.SMS, BotName));
|
string sms = Program.GetUserInput(Program.EUserInputType.SMS, BotName);
|
||||||
|
if (string.IsNullOrEmpty(sms)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticatorLinker.FinalizeResult finalizeResult = authenticatorLinker.FinalizeAddAuthenticator(sms);
|
||||||
if (finalizeResult != AuthenticatorLinker.FinalizeResult.Success) {
|
if (finalizeResult != AuthenticatorLinker.FinalizeResult.Success) {
|
||||||
Logging.LogGenericError("Unhandled situation: " + finalizeResult, BotName);
|
Logging.LogGenericError("Unhandled situation: " + finalizeResult, BotName);
|
||||||
DelinkMobileAuthenticator();
|
DelinkMobileAuthenticator();
|
||||||
@@ -1227,16 +1264,24 @@ namespace ArchiSteamFarm {
|
|||||||
SteamFriends.JoinChat(BotConfig.SteamMasterClanID);
|
SteamFriends.JoinChat(BotConfig.SteamMasterClanID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeLoginAndPassword() {
|
private bool InitializeLoginAndPassword() {
|
||||||
if (string.IsNullOrEmpty(BotConfig.SteamLogin)) {
|
if (string.IsNullOrEmpty(BotConfig.SteamLogin)) {
|
||||||
BotConfig.SteamLogin = Program.GetUserInput(Program.EUserInputType.Login, BotName);
|
BotConfig.SteamLogin = Program.GetUserInput(Program.EUserInputType.Login, BotName);
|
||||||
|
if (string.IsNullOrEmpty(BotConfig.SteamLogin)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(BotConfig.SteamPassword) && string.IsNullOrEmpty(BotDatabase.LoginKey)) {
|
if (string.IsNullOrEmpty(BotConfig.SteamPassword) && string.IsNullOrEmpty(BotDatabase.LoginKey)) {
|
||||||
BotConfig.SteamPassword = Program.GetUserInput(Program.EUserInputType.Password, BotName);
|
BotConfig.SteamPassword = Program.GetUserInput(Program.EUserInputType.Password, BotName);
|
||||||
|
if (string.IsNullOrEmpty(BotConfig.SteamPassword)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnConnected(SteamClient.ConnectedCallback callback) {
|
private void OnConnected(SteamClient.ConnectedCallback callback) {
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
return;
|
return;
|
||||||
@@ -1265,10 +1310,18 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeLoginAndPassword();
|
if (!InitializeLoginAndPassword()) {
|
||||||
|
Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Logging.LogGenericInfo("Logging in...", BotName);
|
Logging.LogGenericInfo("Logging in...", BotName);
|
||||||
|
|
||||||
|
// If we have ASF 2FA enabled, we can always provide TwoFactorCode, and save a request
|
||||||
|
if (BotDatabase.SteamGuardAccount != null) {
|
||||||
|
TwoFactorCode = BotDatabase.SteamGuardAccount.GenerateSteamGuardCode();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Please remove me immediately after https://github.com/SteamRE/SteamKit/issues/254 gets fixed
|
// TODO: Please remove me immediately after https://github.com/SteamRE/SteamKit/issues/254 gets fixed
|
||||||
if (Program.GlobalConfig.HackIgnoreMachineID) {
|
if (Program.GlobalConfig.HackIgnoreMachineID) {
|
||||||
Logging.LogGenericWarning("Using workaround for broken GenerateMachineID()!", BotName);
|
Logging.LogGenericWarning("Using workaround for broken GenerateMachineID()!", BotName);
|
||||||
@@ -1278,7 +1331,7 @@ namespace ArchiSteamFarm {
|
|||||||
AuthCode = AuthCode,
|
AuthCode = AuthCode,
|
||||||
LoginID = LoginID,
|
LoginID = LoginID,
|
||||||
LoginKey = BotDatabase.LoginKey,
|
LoginKey = BotDatabase.LoginKey,
|
||||||
TwoFactorCode = TwoFactorAuth,
|
TwoFactorCode = TwoFactorCode,
|
||||||
SentryFileHash = sentryHash,
|
SentryFileHash = sentryHash,
|
||||||
ShouldRememberPassword = true
|
ShouldRememberPassword = true
|
||||||
});
|
});
|
||||||
@@ -1291,7 +1344,7 @@ namespace ArchiSteamFarm {
|
|||||||
AuthCode = AuthCode,
|
AuthCode = AuthCode,
|
||||||
LoginID = LoginID,
|
LoginID = LoginID,
|
||||||
LoginKey = BotDatabase.LoginKey,
|
LoginKey = BotDatabase.LoginKey,
|
||||||
TwoFactorCode = TwoFactorAuth,
|
TwoFactorCode = TwoFactorCode,
|
||||||
SentryFileHash = sentryHash,
|
SentryFileHash = sentryHash,
|
||||||
ShouldRememberPassword = true
|
ShouldRememberPassword = true
|
||||||
});
|
});
|
||||||
@@ -1338,7 +1391,7 @@ namespace ArchiSteamFarm {
|
|||||||
Logging.LogGenericInfo("Reconnecting...", BotName);
|
Logging.LogGenericInfo("Reconnecting...", BotName);
|
||||||
|
|
||||||
// 2FA tokens are expiring soon, use limiter only when we don't have any pending
|
// 2FA tokens are expiring soon, use limiter only when we don't have any pending
|
||||||
if (TwoFactorAuth == null) {
|
if (TwoFactorCode == null) {
|
||||||
await Program.LimitSteamRequestsAsync().ConfigureAwait(false);
|
await Program.LimitSteamRequestsAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1493,12 +1546,20 @@ namespace ArchiSteamFarm {
|
|||||||
switch (callback.Result) {
|
switch (callback.Result) {
|
||||||
case EResult.AccountLogonDenied:
|
case EResult.AccountLogonDenied:
|
||||||
AuthCode = Program.GetUserInput(Program.EUserInputType.SteamGuard, BotName);
|
AuthCode = Program.GetUserInput(Program.EUserInputType.SteamGuard, BotName);
|
||||||
|
if (string.IsNullOrEmpty(AuthCode)) {
|
||||||
|
Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EResult.AccountLoginDeniedNeedTwoFactor:
|
case EResult.AccountLoginDeniedNeedTwoFactor:
|
||||||
if (BotDatabase.SteamGuardAccount == null) {
|
if (BotDatabase.SteamGuardAccount == null) {
|
||||||
TwoFactorAuth = Program.GetUserInput(Program.EUserInputType.TwoFactorAuthentication, BotName);
|
TwoFactorCode = Program.GetUserInput(Program.EUserInputType.TwoFactorAuthentication, BotName);
|
||||||
|
if (string.IsNullOrEmpty(TwoFactorCode)) {
|
||||||
|
Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
TwoFactorAuth = BotDatabase.SteamGuardAccount.GenerateSteamGuardCode();
|
Logging.LogGenericWarning("2FA code was invalid despite of using ASF 2FA. Invalid authenticator or bad timing?", BotName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EResult.InvalidPassword:
|
case EResult.InvalidPassword:
|
||||||
@@ -1517,18 +1578,22 @@ namespace ArchiSteamFarm {
|
|||||||
string maFilePath = Path.Combine(Program.ConfigDirectory, callback.ClientSteamID.ConvertToUInt64() + ".maFile");
|
string maFilePath = Path.Combine(Program.ConfigDirectory, callback.ClientSteamID.ConvertToUInt64() + ".maFile");
|
||||||
if (File.Exists(maFilePath)) {
|
if (File.Exists(maFilePath)) {
|
||||||
ImportAuthenticator(maFilePath);
|
ImportAuthenticator(maFilePath);
|
||||||
} else if (TwoFactorAuth == null && BotConfig.UseAsfAsMobileAuthenticator) {
|
} else if (TwoFactorCode == null && BotConfig.UseAsfAsMobileAuthenticator) {
|
||||||
LinkMobileAuthenticator();
|
LinkMobileAuthenticator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset one-time-only access tokens
|
// Reset one-time-only access tokens
|
||||||
AuthCode = TwoFactorAuth = null;
|
AuthCode = TwoFactorCode = null;
|
||||||
|
|
||||||
ResetGamesPlayed();
|
ResetGamesPlayed();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(BotConfig.SteamParentalPIN)) {
|
if (string.IsNullOrEmpty(BotConfig.SteamParentalPIN)) {
|
||||||
BotConfig.SteamParentalPIN = Program.GetUserInput(Program.EUserInputType.SteamParentalPIN, BotName);
|
BotConfig.SteamParentalPIN = Program.GetUserInput(Program.EUserInputType.SteamParentalPIN, BotName);
|
||||||
|
if (string.IsNullOrEmpty(BotConfig.SteamParentalPIN)) {
|
||||||
|
Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ArchiWebHandler.Init(SteamClient, callback.WebAPIUserNonce, BotConfig.SteamParentalPIN)) {
|
if (!ArchiWebHandler.Init(SteamClient, callback.WebAPIUserNonce, BotConfig.SteamParentalPIN)) {
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
bool farmedSomething = false;
|
bool farmedSomething = false;
|
||||||
|
|
||||||
|
do {
|
||||||
// Now the algorithm used for farming depends on whether account is restricted or not
|
// Now the algorithm used for farming depends on whether account is restricted or not
|
||||||
if (Bot.BotConfig.CardDropsRestricted) { // If we have restricted card drops, we use complex algorithm
|
if (Bot.BotConfig.CardDropsRestricted) { // If we have restricted card drops, we use complex algorithm
|
||||||
Logging.LogGenericInfo("Chosen farming algorithm: Complex", Bot.BotName);
|
Logging.LogGenericInfo("Chosen farming algorithm: Complex", Bot.BotName);
|
||||||
@@ -141,18 +142,12 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} while (await IsAnythingToFarm().ConfigureAwait(false));
|
||||||
|
|
||||||
CurrentGamesFarming.Clear();
|
CurrentGamesFarming.Clear();
|
||||||
CurrentGamesFarming.TrimExcess();
|
CurrentGamesFarming.TrimExcess();
|
||||||
NowFarming = false;
|
NowFarming = false;
|
||||||
|
|
||||||
// We finished our queue for now, make sure that everything is indeed farmed before proceeding further
|
|
||||||
// Some games could be added in the meantime
|
|
||||||
if (await IsAnythingToFarm().ConfigureAwait(false)) {
|
|
||||||
StartFarming().Forget();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logging.LogGenericInfo("Farming finished!", Bot.BotName);
|
Logging.LogGenericInfo("Farming finished!", Bot.BotName);
|
||||||
await Bot.OnFarmingFinished(farmedSomething).ConfigureAwait(false);
|
await Bot.OnFarmingFinished(farmedSomething).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
@@ -207,10 +202,6 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> IsAnythingToFarm() {
|
private async Task<bool> IsAnythingToFarm() {
|
||||||
if (NowFarming) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logging.LogGenericInfo("Checking badges...", Bot.BotName);
|
Logging.LogGenericInfo("Checking badges...", Bot.BotName);
|
||||||
|
|
||||||
// Find the number of badge pages
|
// Find the number of badge pages
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ namespace ArchiSteamFarm {
|
|||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal bool Debug { get; private set; } = false;
|
internal bool Debug { get; private set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
internal bool Headless { get; private set; } = false;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
internal bool AutoUpdates { get; private set; } = true;
|
internal bool AutoUpdates { get; private set; } = true;
|
||||||
|
|
||||||
|
|||||||
@@ -82,17 +82,21 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
private static Timer AutoUpdatesTimer;
|
private static Timer AutoUpdatesTimer;
|
||||||
private static EMode Mode = EMode.Normal;
|
private static EMode Mode = EMode.Normal;
|
||||||
|
private static WebBrowser WebBrowser;
|
||||||
|
|
||||||
internal static async Task CheckForUpdate() {
|
internal static async Task CheckForUpdate() {
|
||||||
string oldExeFile = ExecutableFile + ".old";
|
string oldExeFile = ExecutableFile + ".old";
|
||||||
|
|
||||||
// We booted successfully so we can now remove old exe file
|
// We booted successfully so we can now remove old exe file
|
||||||
if (File.Exists(oldExeFile)) {
|
if (File.Exists(oldExeFile)) {
|
||||||
|
// It's entirely possible that old process is still running, allow at least a second before trying to remove the file
|
||||||
|
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File.Delete(oldExeFile);
|
File.Delete(oldExeFile);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e);
|
||||||
return;
|
Logging.LogGenericError("Could not remove old ASF binary, please remove " + oldExeFile + " manually in order for update function to work!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,6 +174,11 @@ namespace ArchiSteamFarm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (File.Exists(oldExeFile)) {
|
||||||
|
Logging.LogGenericWarning("Refusing to proceed with auto update as old " + oldExeFile + " binary could not be removed, please remove it manually");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Auto update logic starts here
|
// Auto update logic starts here
|
||||||
if (releaseResponse.Assets == null) {
|
if (releaseResponse.Assets == null) {
|
||||||
Logging.LogGenericWarning("Could not proceed with update because that version doesn't include assets!");
|
Logging.LogGenericWarning("Could not proceed with update because that version doesn't include assets!");
|
||||||
@@ -247,13 +256,19 @@ namespace ArchiSteamFarm {
|
|||||||
Restart();
|
Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void Exit(int exitCode = 0) {
|
||||||
|
WCF.StopServer();
|
||||||
|
Environment.Exit(exitCode);
|
||||||
|
}
|
||||||
|
|
||||||
internal static void Restart() {
|
internal static void Restart() {
|
||||||
try {
|
try {
|
||||||
Process.Start(ExecutableFile, string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
|
Process.Start(ExecutableFile, string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
|
||||||
Environment.Exit(0);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task LimitSteamRequestsAsync() {
|
internal static async Task LimitSteamRequestsAsync() {
|
||||||
@@ -269,6 +284,11 @@ namespace ArchiSteamFarm {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GlobalConfig.Headless) {
|
||||||
|
Logging.LogGenericWarning("Received a request for user input, but process is running in headless mode!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
string result;
|
string result;
|
||||||
lock (ConsoleLock) {
|
lock (ConsoleLock) {
|
||||||
ConsoleIsBusy = true;
|
ConsoleIsBusy = true;
|
||||||
@@ -295,7 +315,7 @@ namespace ArchiSteamFarm {
|
|||||||
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter steam parental PIN: ");
|
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "Please enter steam parental PIN: ");
|
||||||
break;
|
break;
|
||||||
case EUserInputType.RevocationCode:
|
case EUserInputType.RevocationCode:
|
||||||
Console.Write((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation);
|
Console.WriteLine((string.IsNullOrEmpty(botName) ? "" : "<" + botName + "> ") + "PLEASE WRITE DOWN YOUR REVOCATION CODE: " + extraInformation);
|
||||||
Console.Write("Hit enter once ready...");
|
Console.Write("Hit enter once ready...");
|
||||||
break;
|
break;
|
||||||
case EUserInputType.TwoFactorAuthentication:
|
case EUserInputType.TwoFactorAuthentication:
|
||||||
@@ -337,19 +357,21 @@ namespace ArchiSteamFarm {
|
|||||||
if (GlobalConfig == null) {
|
if (GlobalConfig == null) {
|
||||||
Logging.LogGenericError("Global config could not be loaded, please make sure that ASF.json exists and is valid!");
|
Logging.LogGenericError("Global config could not be loaded, please make sure that ASF.json exists and is valid!");
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
Environment.Exit(1);
|
Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalDatabase = GlobalDatabase.Load();
|
GlobalDatabase = GlobalDatabase.Load();
|
||||||
if (GlobalDatabase == null) {
|
if (GlobalDatabase == null) {
|
||||||
Logging.LogGenericError("Global database could not be loaded!");
|
Logging.LogGenericError("Global database could not be loaded!");
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
Environment.Exit(1);
|
Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchiWebHandler.Init();
|
ArchiWebHandler.Init();
|
||||||
WebBrowser.Init();
|
WebBrowser.Init();
|
||||||
WCF.Init();
|
WCF.Init();
|
||||||
|
|
||||||
|
WebBrowser = new WebBrowser("Main");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseArgs(string[] args) {
|
private static void ParseArgs(string[] args) {
|
||||||
@@ -445,7 +467,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
// If we ran ASF as a client, we're done by now
|
// If we ran ASF as a client, we're done by now
|
||||||
if (Mode == EMode.Client) {
|
if (Mode == EMode.Client) {
|
||||||
Environment.Exit(0);
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// From now on it's server mode
|
// From now on it's server mode
|
||||||
@@ -454,7 +476,7 @@ namespace ArchiSteamFarm {
|
|||||||
if (!Directory.Exists(ConfigDirectory)) {
|
if (!Directory.Exists(ConfigDirectory)) {
|
||||||
Logging.LogGenericError("Config directory doesn't exist!");
|
Logging.LogGenericError("Config directory doesn't exist!");
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
Environment.Exit(1);
|
Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckForUpdate().Wait();
|
CheckForUpdate().Wait();
|
||||||
@@ -494,7 +516,7 @@ namespace ArchiSteamFarm {
|
|||||||
ShutdownResetEvent.WaitOne();
|
ShutdownResetEvent.WaitOne();
|
||||||
|
|
||||||
// We got a signal to shutdown
|
// We got a signal to shutdown
|
||||||
Environment.Exit(0);
|
Exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("2.0.2.2")]
|
[assembly: AssemblyVersion("2.0.2.8")]
|
||||||
[assembly: AssemblyFileVersion("2.0.2.2")]
|
[assembly: AssemblyFileVersion("2.0.2.8")]
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await tradeOffers.ForEachAsync(ParseTrade).ConfigureAwait(false);
|
await tradeOffers.ForEachAsync(ParseTrade).ConfigureAwait(false);
|
||||||
await Bot.AcceptConfirmations(Confirmation.ConfirmationType.Trade).ConfigureAwait(false);
|
await Bot.AcceptConfirmations(true, Confirmation.ConfirmationType.Trade).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ParseTrade(Steam.TradeOffer tradeOffer) {
|
private async Task ParseTrade(Steam.TradeOffer tradeOffer) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
@@ -35,6 +36,27 @@ namespace ArchiSteamFarm {
|
|||||||
return Task.WhenAll(sequence.Select(action));
|
return Task.WhenAll(sequence.Select(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static string GetCookieValue(this CookieContainer cookieContainer, string URL, string name) {
|
||||||
|
if (string.IsNullOrEmpty(URL) || string.IsNullOrEmpty(name)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CookieCollection cookies = cookieContainer.GetCookies(new Uri(URL));
|
||||||
|
if (cookies == null || cookies.Count == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Cookie cookie in cookies) {
|
||||||
|
if (!cookie.Name.Equals(name, StringComparison.Ordinal)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cookie.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
internal static Task SleepAsync(int miliseconds) {
|
internal static Task SleepAsync(int miliseconds) {
|
||||||
if (miliseconds < 0) {
|
if (miliseconds < 0) {
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ namespace ArchiSteamFarm {
|
|||||||
internal static void Init() {
|
internal static void Init() {
|
||||||
if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHostname)) {
|
if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHostname)) {
|
||||||
Program.GlobalConfig.WCFHostname = Program.GetUserInput(Program.EUserInputType.WCFHostname);
|
Program.GlobalConfig.WCFHostname = Program.GetUserInput(Program.EUserInputType.WCFHostname);
|
||||||
|
if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHostname)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
URL = "http://" + Program.GlobalConfig.WCFHostname + ":" + Program.GlobalConfig.WCFPort + "/ASF";
|
URL = "http://" + Program.GlobalConfig.WCFHostname + ":" + Program.GlobalConfig.WCFPort + "/ASF";
|
||||||
|
|||||||
@@ -23,37 +23,31 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using HtmlAgilityPack;
|
using HtmlAgilityPack;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
internal static class WebBrowser {
|
internal sealed class WebBrowser {
|
||||||
internal const byte MaxRetries = 5; // Defines maximum number of retries, UrlRequest() does not handle retry by itself (it's app responsibility)
|
internal const byte MaxRetries = 5; // Defines maximum number of retries, UrlRequest() does not handle retry by itself (it's app responsibility)
|
||||||
|
|
||||||
private const byte MaxConnections = 10; // Defines maximum number of connections per ServicePoint. Be careful, as it also defines maximum number of sockets in CLOSE_WAIT state
|
private const byte MaxConnections = 10; // Defines maximum number of connections per ServicePoint. Be careful, as it also defines maximum number of sockets in CLOSE_WAIT state
|
||||||
private const byte MaxIdleTime = 15; // In seconds, how long socket is allowed to stay in CLOSE_WAIT state after there are no connections to it
|
private const byte MaxIdleTime = 15; // In seconds, how long socket is allowed to stay in CLOSE_WAIT state after there are no connections to it
|
||||||
|
|
||||||
private static readonly string DefaultUserAgent = "ArchiSteamFarm/" + Program.Version;
|
private static readonly string DefaultUserAgent = "ArchiSteamFarm/" + Program.Version;
|
||||||
private static readonly HttpClient HttpClient = new HttpClient(new HttpClientHandler {
|
|
||||||
UseCookies = false
|
internal readonly CookieContainer CookieContainer = new CookieContainer();
|
||||||
}) {
|
|
||||||
Timeout = TimeSpan.FromSeconds(60)
|
private readonly HttpClient HttpClient;
|
||||||
};
|
private readonly string Identifier;
|
||||||
|
|
||||||
internal static void Init() {
|
internal static void Init() {
|
||||||
HttpClient.Timeout = TimeSpan.FromSeconds(Program.GlobalConfig.HttpTimeout);
|
|
||||||
|
|
||||||
// Most web services expect that UserAgent is set, so we declare it globally
|
|
||||||
// Any request can override that on as-needed basis (see: RequestOptions.FakeUserAgent)
|
|
||||||
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(DefaultUserAgent);
|
|
||||||
|
|
||||||
// Set max connection limit from default of 2 to desired value
|
// Set max connection limit from default of 2 to desired value
|
||||||
ServicePointManager.DefaultConnectionLimit = MaxConnections;
|
ServicePointManager.DefaultConnectionLimit = MaxConnections;
|
||||||
|
|
||||||
@@ -63,67 +57,114 @@ namespace ArchiSteamFarm {
|
|||||||
// Don't use Expect100Continue, we're sure about our POSTs, save some TCP packets
|
// Don't use Expect100Continue, we're sure about our POSTs, save some TCP packets
|
||||||
ServicePointManager.Expect100Continue = false;
|
ServicePointManager.Expect100Continue = false;
|
||||||
|
|
||||||
// Reuse ports if possible
|
#if !__MonoCS__
|
||||||
// TODO: Mono doesn't support that feature yet
|
// Reuse ports if possible (since .NET 4.6+)
|
||||||
//ServicePointManager.ReusePort = true;
|
//ServicePointManager.ReusePort = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<HttpResponseMessage> UrlGet(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
internal WebBrowser(string identifier) {
|
||||||
|
if (string.IsNullOrEmpty(identifier)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier = identifier;
|
||||||
|
|
||||||
|
HttpClientHandler httpClientHandler = new HttpClientHandler {
|
||||||
|
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
||||||
|
CookieContainer = CookieContainer
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpClient = new HttpClient(httpClientHandler) {
|
||||||
|
Timeout = TimeSpan.FromSeconds(Program.GlobalConfig.HttpTimeout)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Most web services expect that UserAgent is set, so we declare it globally
|
||||||
|
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(DefaultUserAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<bool> UrlGet(string request, string referer = null) {
|
||||||
|
if (string.IsNullOrEmpty(request)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponseMessage response = await UrlGetToResponse(request, referer).ConfigureAwait(false);
|
||||||
|
if (response == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Dispose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<bool> UrlPost(string request, Dictionary<string, string> data = null, string referer = null) {
|
||||||
|
if (string.IsNullOrEmpty(request)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponseMessage response = await UrlPostToResponse(request, data, referer).ConfigureAwait(false);
|
||||||
|
if (response == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Dispose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<HttpResponseMessage> UrlGetToResponse(string request, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await UrlRequest(request, HttpMethod.Get, null, cookies, referer).ConfigureAwait(false);
|
return await UrlRequest(request, HttpMethod.Get, null, referer).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<HttpResponseMessage> UrlPost(string request, Dictionary<string, string> data = null, Dictionary<string, string> cookies = null, string referer = null) {
|
internal async Task<HttpResponseMessage> UrlPostToResponse(string request, Dictionary<string, string> data = null, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await UrlRequest(request, HttpMethod.Post, data, cookies, referer).ConfigureAwait(false);
|
return await UrlRequest(request, HttpMethod.Post, data, referer).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<string> UrlGetToContent(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
internal async Task<string> UrlGetToContent(string request, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer).ConfigureAwait(false);
|
HttpResponseMessage httpResponse = await UrlGetToResponse(request, referer).ConfigureAwait(false);
|
||||||
if (httpResponse == null) {
|
if (httpResponse == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpResponse.Content == null) {
|
string result = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
return null;
|
httpResponse.Dispose();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
internal async Task<Stream> UrlGetToStream(string request, string referer = null) {
|
||||||
}
|
|
||||||
|
|
||||||
internal static async Task<Stream> UrlGetToStream(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponseMessage httpResponse = await UrlGet(request, cookies, referer).ConfigureAwait(false);
|
HttpResponseMessage httpResponse = await UrlGetToResponse(request, referer).ConfigureAwait(false);
|
||||||
if (httpResponse == null) {
|
if (httpResponse == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpResponse.Content == null) {
|
Stream result = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||||
return null;
|
httpResponse.Dispose();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
internal async Task<HtmlDocument> UrlGetToHtmlDocument(string request, string referer = null) {
|
||||||
}
|
|
||||||
|
|
||||||
internal static async Task<HtmlDocument> UrlGetToHtmlDocument(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false);
|
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||||
if (string.IsNullOrEmpty(content)) {
|
if (string.IsNullOrEmpty(content)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -135,12 +176,12 @@ namespace ArchiSteamFarm {
|
|||||||
return htmlDocument;
|
return htmlDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<JObject> UrlGetToJObject(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
internal async Task<JObject> UrlGetToJObject(string request, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false);
|
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||||
if (string.IsNullOrEmpty(content)) {
|
if (string.IsNullOrEmpty(content)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -149,20 +190,20 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
jObject = JObject.Parse(content);
|
jObject = JObject.Parse(content);
|
||||||
} catch (Exception e) {
|
} catch (JsonException e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e, Identifier);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return jObject;
|
return jObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<XmlDocument> UrlGetToXML(string request, Dictionary<string, string> cookies = null, string referer = null) {
|
internal async Task<XmlDocument> UrlGetToXML(string request, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request)) {
|
if (string.IsNullOrEmpty(request)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string content = await UrlGetToContent(request, cookies, referer).ConfigureAwait(false);
|
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
|
||||||
if (string.IsNullOrEmpty(content)) {
|
if (string.IsNullOrEmpty(content)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -172,14 +213,14 @@ namespace ArchiSteamFarm {
|
|||||||
try {
|
try {
|
||||||
xmlDocument.LoadXml(content);
|
xmlDocument.LoadXml(content);
|
||||||
} catch (XmlException e) {
|
} catch (XmlException e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e, Identifier);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return xmlDocument;
|
return xmlDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<HttpResponseMessage> UrlRequest(string request, HttpMethod httpMethod, Dictionary<string, string> data = null, Dictionary<string, string> cookies = null, string referer = null) {
|
private async Task<HttpResponseMessage> UrlRequest(string request, HttpMethod httpMethod, Dictionary<string, string> data = null, string referer = null) {
|
||||||
if (string.IsNullOrEmpty(request) || httpMethod == null) {
|
if (string.IsNullOrEmpty(request) || httpMethod == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -194,19 +235,11 @@ namespace ArchiSteamFarm {
|
|||||||
try {
|
try {
|
||||||
requestMessage.Content = new FormUrlEncodedContent(data);
|
requestMessage.Content = new FormUrlEncodedContent(data);
|
||||||
} catch (UriFormatException e) {
|
} catch (UriFormatException e) {
|
||||||
Logging.LogGenericException(e);
|
Logging.LogGenericException(e, Identifier);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookies != null && cookies.Count > 0) {
|
|
||||||
StringBuilder cookieHeader = new StringBuilder();
|
|
||||||
foreach (KeyValuePair<string, string> cookie in cookies) {
|
|
||||||
cookieHeader.Append(cookie.Key + "=" + cookie.Value + ";");
|
|
||||||
}
|
|
||||||
requestMessage.Headers.Add("Cookie", cookieHeader.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(referer)) {
|
if (!string.IsNullOrEmpty(referer)) {
|
||||||
requestMessage.Headers.Referrer = new Uri(referer);
|
requestMessage.Headers.Referrer = new Uri(referer);
|
||||||
}
|
}
|
||||||
@@ -218,15 +251,14 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseMessage == null) {
|
if (responseMessage == null || !responseMessage.IsSuccessStatusCode) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!responseMessage.IsSuccessStatusCode) {
|
|
||||||
if (Debugging.IsDebugBuild || Program.GlobalConfig.Debug) {
|
if (Debugging.IsDebugBuild || Program.GlobalConfig.Debug) {
|
||||||
Logging.LogGenericError("Request: " + request + " failed!");
|
Logging.LogGenericError("Request: " + request + " failed!", Identifier);
|
||||||
Logging.LogGenericError("Status code: " + responseMessage.StatusCode);
|
if (responseMessage != null) {
|
||||||
Logging.LogGenericError("Content: " + Environment.NewLine + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false));
|
Logging.LogGenericError("Status code: " + responseMessage.StatusCode, Identifier);
|
||||||
|
Logging.LogGenericError("Content: " + Environment.NewLine + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false), Identifier);
|
||||||
|
responseMessage.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"Debug": false,
|
"Debug": false,
|
||||||
|
"Headless": false,
|
||||||
"AutoUpdates": true,
|
"AutoUpdates": true,
|
||||||
"UpdateChannel": 1,
|
"UpdateChannel": 1,
|
||||||
"SteamProtocol": 6,
|
"SteamProtocol": 6,
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ namespace ConfigGenerator {
|
|||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
public bool Debug { get; set; } = false;
|
public bool Debug { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
|
public bool Headless { get; set; } = false;
|
||||||
|
|
||||||
[JsonProperty(Required = Required.DisallowNull)]
|
[JsonProperty(Required = Required.DisallowNull)]
|
||||||
public bool AutoUpdates { get; set; } = true;
|
public bool AutoUpdates { get; set; } = true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user