|
|
|
|
@@ -199,7 +199,7 @@ namespace ArchiSteamFarm {
|
|
|
|
|
|
|
|
|
|
if (AcceptConfirmationsTimer == null && BotConfig.AcceptConfirmationsPeriod > 0) {
|
|
|
|
|
AcceptConfirmationsTimer = new Timer(
|
|
|
|
|
async e => await AcceptConfirmations().ConfigureAwait(false),
|
|
|
|
|
async e => await AcceptConfirmations(true).ConfigureAwait(false),
|
|
|
|
|
null,
|
|
|
|
|
TimeSpan.FromMinutes(BotConfig.AcceptConfirmationsPeriod), // Delay
|
|
|
|
|
TimeSpan.FromMinutes(BotConfig.AcceptConfirmationsPeriod) // Period
|
|
|
|
|
@@ -223,7 +223,7 @@ namespace ArchiSteamFarm {
|
|
|
|
|
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) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -243,10 +243,14 @@ namespace ArchiSteamFarm {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BotDatabase.SteamGuardAccount.AcceptConfirmation(confirmation);
|
|
|
|
|
if (confirm) {
|
|
|
|
|
BotDatabase.SteamGuardAccount.AcceptConfirmation(confirmation);
|
|
|
|
|
} else {
|
|
|
|
|
BotDatabase.SteamGuardAccount.DenyConfirmation(confirmation);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} 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("If issue persists, consider removing and readding ASF 2FA", BotName);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
@@ -297,17 +301,19 @@ namespace ArchiSteamFarm {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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(" ")) {
|
|
|
|
|
switch (message) {
|
|
|
|
|
case "!2fa":
|
|
|
|
|
return Response2FA(steamID);
|
|
|
|
|
case "!2fano":
|
|
|
|
|
return await Response2FAConfirm(steamID, false).ConfigureAwait(false);
|
|
|
|
|
case "!2faoff":
|
|
|
|
|
return Response2FAOff(steamID);
|
|
|
|
|
case "!2faok":
|
|
|
|
|
return await Response2FAOK(steamID).ConfigureAwait(false);
|
|
|
|
|
return await Response2FAConfirm(steamID, true).ConfigureAwait(false);
|
|
|
|
|
case "!exit":
|
|
|
|
|
return ResponseExit(steamID);
|
|
|
|
|
case "!farm":
|
|
|
|
|
@@ -338,10 +344,12 @@ namespace ArchiSteamFarm {
|
|
|
|
|
switch (args[0]) {
|
|
|
|
|
case "!2fa":
|
|
|
|
|
return Response2FA(steamID, args[1]);
|
|
|
|
|
case "!2fano":
|
|
|
|
|
return await Response2FAConfirm(steamID, args[1], false).ConfigureAwait(false);
|
|
|
|
|
case "!2faoff":
|
|
|
|
|
return Response2FAOff(steamID, args[1]);
|
|
|
|
|
case "!2faok":
|
|
|
|
|
return await Response2FAOK(steamID, args[1]).ConfigureAwait(false);
|
|
|
|
|
return await Response2FAConfirm(steamID, args[1], true).ConfigureAwait(false);
|
|
|
|
|
case "!addlicense":
|
|
|
|
|
if (args.Length > 2) {
|
|
|
|
|
return await ResponseAddLicense(steamID, args[1], args[2]).ConfigureAwait(false);
|
|
|
|
|
@@ -370,9 +378,9 @@ namespace ArchiSteamFarm {
|
|
|
|
|
}
|
|
|
|
|
case "!redeem":
|
|
|
|
|
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 {
|
|
|
|
|
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":
|
|
|
|
|
return await ResponseStart(steamID, args[1]).ConfigureAwait(false);
|
|
|
|
|
@@ -572,7 +580,7 @@ namespace ArchiSteamFarm {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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!";
|
|
|
|
|
} else {
|
|
|
|
|
return "Trade offer failed due to error!";
|
|
|
|
|
@@ -647,7 +655,7 @@ namespace ArchiSteamFarm {
|
|
|
|
|
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)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@@ -656,11 +664,11 @@ namespace ArchiSteamFarm {
|
|
|
|
|
return "That bot doesn't have ASF 2FA enabled!";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await AcceptConfirmations().ConfigureAwait(false);
|
|
|
|
|
await AcceptConfirmations(confirm).ConfigureAwait(false);
|
|
|
|
|
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)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@@ -670,7 +678,7 @@ namespace ArchiSteamFarm {
|
|
|
|
|
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) {
|
|
|
|
|
@@ -682,8 +690,13 @@ namespace ArchiSteamFarm {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Environment.Exit(0);
|
|
|
|
|
return null;
|
|
|
|
|
// Schedule the task after some time so user can receive response
|
|
|
|
|
Task.Run(async () => {
|
|
|
|
|
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
|
|
|
|
Program.Exit();
|
|
|
|
|
}).Forget();
|
|
|
|
|
|
|
|
|
|
return "Done!";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string ResponseFarm(ulong steamID) {
|
|
|
|
|
@@ -739,117 +752,82 @@ namespace ArchiSteamFarm {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
IEnumerator<Bot> iterator = Bots.Values.GetEnumerator();
|
|
|
|
|
Bot currentBot = this;
|
|
|
|
|
while (key != null) {
|
|
|
|
|
if (currentBot == null) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (!string.IsNullOrEmpty(key) && currentBot != null) {
|
|
|
|
|
if (validate && !IsValidCdKey(key)) {
|
|
|
|
|
key = reader.ReadLine();
|
|
|
|
|
continue;
|
|
|
|
|
key = reader.ReadLine(); // Next key
|
|
|
|
|
continue; // Without changing the bot
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ArchiHandler.PurchaseResponseCallback result = await currentBot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
|
|
|
|
if (result == null) {
|
|
|
|
|
break;
|
|
|
|
|
if (currentBot.SteamClient.IsConnected) {
|
|
|
|
|
ArchiHandler.PurchaseResponseCallback result = await currentBot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
|
|
|
|
if (result != null) {
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
key = reader.ReadLine(); // Next key
|
|
|
|
|
break; // Next bot (if needed)
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.AlreadyOwned:
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.BaseGameRequired:
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OnCooldown:
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.RegionLocked:
|
|
|
|
|
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) {
|
|
|
|
|
break; // Next bot, without changing key
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool alreadyHandled = false;
|
|
|
|
|
foreach (Bot bot in Bots.Values) {
|
|
|
|
|
if (bot == this || !bot.SteamClient.IsConnected) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ArchiHandler.PurchaseResponseCallback otherResult = await bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
|
|
|
|
if (otherResult == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (otherResult.PurchaseResult) {
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.DuplicatedKey:
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.InvalidKey:
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK:
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var purchaseResult = result.PurchaseResult;
|
|
|
|
|
var items = result.Items;
|
|
|
|
|
|
|
|
|
|
switch (purchaseResult) {
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.AlreadyOwned:
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.BaseGameRequired:
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OnCooldown:
|
|
|
|
|
case ArchiHandler.PurchaseResponseCallback.EPurchaseResult.RegionLocked:
|
|
|
|
|
response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + purchaseResult + " | Items: " + string.Join("", items));
|
|
|
|
|
if (BotConfig.DistributeKeys) {
|
|
|
|
|
do {
|
|
|
|
|
if (iterator.MoveNext()) {
|
|
|
|
|
currentBot = iterator.Current;
|
|
|
|
|
} else {
|
|
|
|
|
currentBot = null;
|
|
|
|
|
}
|
|
|
|
|
} while (currentBot == this);
|
|
|
|
|
|
|
|
|
|
if (!BotConfig.ForwardKeysToOtherBots) {
|
|
|
|
|
key = reader.ReadLine();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
if (BotConfig.DistributeKeys) {
|
|
|
|
|
do {
|
|
|
|
|
if (iterator.MoveNext()) {
|
|
|
|
|
currentBot = iterator.Current;
|
|
|
|
|
} else {
|
|
|
|
|
currentBot = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!BotConfig.ForwardKeysToOtherBots) {
|
|
|
|
|
key = reader.ReadLine();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool alreadyHandled = false;
|
|
|
|
|
foreach (Bot bot in Bots.Values) {
|
|
|
|
|
if (alreadyHandled) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bot == this) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ArchiHandler.PurchaseResponseCallback otherResult = await bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
if (otherResult == null) {
|
|
|
|
|
break; // We're done with this key
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var otherPurchaseResult = 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.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:
|
|
|
|
|
response.Append(Environment.NewLine + "<" + currentBot.BotName + "> Key: " + key + " | Status: " + purchaseResult + " | Items: " + string.Join("", items));
|
|
|
|
|
if (BotConfig.DistributeKeys) {
|
|
|
|
|
do {
|
|
|
|
|
if (iterator.MoveNext()) {
|
|
|
|
|
currentBot = iterator.Current;
|
|
|
|
|
} else {
|
|
|
|
|
currentBot = null;
|
|
|
|
|
}
|
|
|
|
|
} while (currentBot == this);
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
} while (currentBot == this || (currentBot != null && !currentBot.SteamClient.IsConnected));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -899,8 +877,13 @@ namespace ArchiSteamFarm {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Program.Restart();
|
|
|
|
|
return null;
|
|
|
|
|
// Schedule the task after some time so user can receive response
|
|
|
|
|
Task.Run(async () => {
|
|
|
|
|
await Utilities.SleepAsync(1000).ConfigureAwait(false);
|
|
|
|
|
Program.Restart();
|
|
|
|
|
}).Forget();
|
|
|
|
|
|
|
|
|
|
return "Done!";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<string> ResponseAddLicense(ulong steamID, HashSet<uint> gameIDs) {
|
|
|
|
|
|