mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2026-01-01 14:10:53 +00:00
@@ -21,7 +21,9 @@
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Linq;
|
||||
using HtmlAgilityPack;
|
||||
using SteamKit2;
|
||||
using System;
|
||||
@@ -371,6 +373,54 @@ namespace ArchiSteamFarm {
|
||||
return response != null; // Steam API doesn't respond with any error code, assume any response is a success
|
||||
}
|
||||
|
||||
internal async Task<List<SteamInventoryItem>> GetInventory() {
|
||||
List<SteamInventoryItem> result = new List<SteamInventoryItem>();
|
||||
try {
|
||||
JObject jobj = await WebBrowser.UrlGetToJObject("http://steamcommunity.com/my/inventory/json/753/6", Cookie).ConfigureAwait(false);
|
||||
IList<JToken> results = jobj.SelectTokens("$.rgInventory.*").ToList();
|
||||
foreach (JToken res in results) {
|
||||
result.Add(JsonConvert.DeserializeObject<SteamInventoryItem>(res.ToString()));
|
||||
}
|
||||
} catch (Exception) {
|
||||
//just return empty list on error
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal async Task<bool> SendTradeOffer(List<SteamInventoryItem> itemsSend, string masterid,string token=null) {
|
||||
string sessionID;
|
||||
if (!Cookie.TryGetValue("sessionid", out sessionID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SteamTradeItemList items = new SteamTradeItemList();
|
||||
foreach (var item in itemsSend) {
|
||||
items.assets.Add(new SteamTradeItem(753, 6, Int32.Parse(item.amount), item.id));
|
||||
}
|
||||
|
||||
SteamTradeOfferRequest trade = new SteamTradeOfferRequest(true, 2, items, new SteamTradeItemList());
|
||||
|
||||
string referer = String.Format("https://steamcommunity.com/tradeoffer/new/?partner={0}", ((Int32)Int64.Parse(masterid)).ToString());
|
||||
|
||||
if (!string.IsNullOrEmpty(token)) {
|
||||
referer += String.Format("&token={0}",token);
|
||||
}
|
||||
|
||||
Dictionary <string, string> postData = new Dictionary<string, string>() {
|
||||
{"sessionid", sessionID},
|
||||
{"serverid","1" },
|
||||
{"partner",masterid },
|
||||
{"tradeoffermessage","sent by ASF" },
|
||||
{"json_tradeoffer",JsonConvert.SerializeObject(trade) },
|
||||
{"trade_offer_create_params",string.IsNullOrEmpty(token)?"":String.Format("{{ \"trade_offer_access_token\":\"{0}\" }}", token) }
|
||||
};
|
||||
HttpResponseMessage response = await WebBrowser.UrlPost("https://steamcommunity.com/tradeoffer/new/send", postData, Cookie, referer).ConfigureAwait(false);
|
||||
if (response == null) {
|
||||
return false;
|
||||
}
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
|
||||
internal async Task<HtmlDocument> GetBadgePage(int page) {
|
||||
if (SteamID == 0 || page == 0) {
|
||||
return null;
|
||||
|
||||
59
ArchiSteamFarm/Bot.cs
Executable file → Normal file
59
ArchiSteamFarm/Bot.cs
Executable file → Normal file
@@ -31,6 +31,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
@@ -56,6 +57,7 @@ namespace ArchiSteamFarm {
|
||||
internal readonly SteamFriends SteamFriends;
|
||||
internal readonly SteamUser SteamUser;
|
||||
internal readonly Trading Trading;
|
||||
private Timer Timer;
|
||||
|
||||
private bool KeepRunning = true;
|
||||
private bool InvalidPassword = false;
|
||||
@@ -70,6 +72,7 @@ namespace ArchiSteamFarm {
|
||||
internal string SteamPassword { get; private set; } = "null";
|
||||
internal string SteamNickname { get; private set; } = "null";
|
||||
internal string SteamApiKey { get; private set; } = "null";
|
||||
internal string SteamTradeToken {get; private set; } = "null";
|
||||
internal string SteamParentalPIN { get; private set; } = "0";
|
||||
internal ulong SteamMasterID { get; private set; } = 0;
|
||||
internal ulong SteamMasterClanID { get; private set; } = 0;
|
||||
@@ -79,6 +82,8 @@ namespace ArchiSteamFarm {
|
||||
internal bool ForwardKeysToOtherBots { get; private set; } = false;
|
||||
internal bool UseAsfAsMobileAuthenticator { get; private set; } = false;
|
||||
internal bool ShutdownOnFarmingFinished { get; private set; } = false;
|
||||
internal bool SendOnFarmingFinished { get; private set; } = false;
|
||||
internal uint SendTradePeriod {get; private set; } = 0;
|
||||
internal HashSet<uint> Blacklist { get; private set; } = new HashSet<uint>();
|
||||
internal bool Statistics { get; private set; } = true;
|
||||
|
||||
@@ -305,6 +310,9 @@ namespace ArchiSteamFarm {
|
||||
case "SteamApiKey":
|
||||
SteamApiKey = value;
|
||||
break;
|
||||
case "SteamTradeToken":
|
||||
SteamTradeToken = value;
|
||||
break;
|
||||
case "SteamParentalPIN":
|
||||
SteamParentalPIN = value;
|
||||
break;
|
||||
@@ -332,6 +340,12 @@ namespace ArchiSteamFarm {
|
||||
case "ShutdownOnFarmingFinished":
|
||||
ShutdownOnFarmingFinished = bool.Parse(value);
|
||||
break;
|
||||
case "SendOnFarmingFinished":
|
||||
SendOnFarmingFinished = bool.Parse(value);
|
||||
break;
|
||||
case "SendTradePeriod":
|
||||
SendTradePeriod = uint.Parse(value);
|
||||
break;
|
||||
case "Blacklist":
|
||||
Blacklist.Clear();
|
||||
foreach (string appID in value.Split(',')) {
|
||||
@@ -411,6 +425,9 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
internal async Task OnFarmingFinished() {
|
||||
if (SendOnFarmingFinished) {
|
||||
await ResponseSendTrade(BotName).ConfigureAwait(false);
|
||||
}
|
||||
if (ShutdownOnFarmingFinished) {
|
||||
await Shutdown().ConfigureAwait(false);
|
||||
}
|
||||
@@ -467,6 +484,35 @@ namespace ArchiSteamFarm {
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
internal static async Task<string> ResponseSendTrade(string botName) {
|
||||
Bot bot;
|
||||
string token=null;
|
||||
if (string.IsNullOrEmpty(botName)) {
|
||||
return "Error, no name specified";
|
||||
}
|
||||
if (!Bots.TryGetValue(botName, out bot)) {
|
||||
return "Couldn't find any bot named " + botName + "!";
|
||||
}
|
||||
if (bot.SendTradePeriod!=0) {
|
||||
bot.Timer.Change(TimeSpan.FromHours(bot.SendTradePeriod),Timeout.InfiniteTimeSpan);
|
||||
}
|
||||
if (bot.SteamMasterID==0) {
|
||||
return "No master set";
|
||||
}
|
||||
if ((!string.IsNullOrEmpty(bot.SteamTradeToken))&&(!bot.SteamTradeToken.Equals("null"))) {
|
||||
token=bot.SteamTradeToken;
|
||||
}
|
||||
List<SteamInventoryItem> inv = await bot.ArchiWebHandler.GetInventory().ConfigureAwait(false);
|
||||
if (inv.Count == 0) {
|
||||
return "Nothing to send";
|
||||
}
|
||||
if (await bot.ArchiWebHandler.SendTradeOffer(inv, bot.SteamMasterID.ToString(),token).ConfigureAwait(false)) {
|
||||
await bot.AcceptAllConfirmations().ConfigureAwait(false);
|
||||
return "Trade offer sent";
|
||||
}
|
||||
return "Error sending trade offer";
|
||||
}
|
||||
|
||||
internal static string Response2FA(string botName) {
|
||||
if (string.IsNullOrEmpty(botName)) {
|
||||
return null;
|
||||
@@ -673,6 +719,8 @@ namespace ArchiSteamFarm {
|
||||
return ResponseStatusAll();
|
||||
case "!stop":
|
||||
return await ResponseStop(BotName).ConfigureAwait(false);
|
||||
case "!loot":
|
||||
return await ResponseSendTrade(BotName).ConfigureAwait(false);
|
||||
default:
|
||||
return "Unrecognized command: " + message;
|
||||
}
|
||||
@@ -700,6 +748,8 @@ namespace ArchiSteamFarm {
|
||||
return await ResponseStop(args[1]).ConfigureAwait(false);
|
||||
case "!status":
|
||||
return ResponseStatus(args[1]);
|
||||
case "!loot":
|
||||
return await ResponseSendTrade(args[1]).ConfigureAwait(false);
|
||||
default:
|
||||
return "Unrecognized command: " + args[0];
|
||||
}
|
||||
@@ -991,6 +1041,15 @@ namespace ArchiSteamFarm {
|
||||
Trading.CheckTrades();
|
||||
|
||||
await CardsFarmer.StartFarming().ConfigureAwait(false);
|
||||
|
||||
if (SendTradePeriod!=0) {
|
||||
Timer = new Timer(
|
||||
async e => await ResponseSendTrade(BotName).ConfigureAwait(false),
|
||||
null,
|
||||
TimeSpan.FromHours(SendTradePeriod), // Delay
|
||||
Timeout.InfiniteTimeSpan // Period
|
||||
);
|
||||
}
|
||||
break;
|
||||
case EResult.NoConnection:
|
||||
case EResult.ServiceUnavailable:
|
||||
|
||||
12
ArchiSteamFarm/SteamInventoryItem.cs
Normal file
12
ArchiSteamFarm/SteamInventoryItem.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
namespace ArchiSteamFarm
|
||||
{
|
||||
public class SteamInventoryItem
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string classid { get; set; }
|
||||
public string instanceid { get; set; }
|
||||
public string amount { get; set; }
|
||||
public int pos { get; set; }
|
||||
}
|
||||
}
|
||||
15
ArchiSteamFarm/SteamTradeItem.cs
Normal file
15
ArchiSteamFarm/SteamTradeItem.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
public class SteamTradeItem {
|
||||
public int appid { get; set; }
|
||||
public int contextid { get; set; }
|
||||
public int amount { get; set; }
|
||||
public string assetid { get; set; }
|
||||
public SteamTradeItem (int aid, int cid, int am, string asset) {
|
||||
appid = aid;
|
||||
contextid = cid;
|
||||
amount = am;
|
||||
assetid = asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
ArchiSteamFarm/SteamTradeItemList.cs
Normal file
14
ArchiSteamFarm/SteamTradeItemList.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
public class SteamTradeItemList {
|
||||
public List<SteamTradeItem> assets { get; set; }
|
||||
public List<string> currency { get; set; }
|
||||
public bool ready { get; set; }
|
||||
public SteamTradeItemList() {
|
||||
assets = new List<SteamTradeItem>();
|
||||
currency = new List<string>();
|
||||
ready = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
ArchiSteamFarm/SteamTradeOfferRequest.cs
Normal file
15
ArchiSteamFarm/SteamTradeOfferRequest.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
public class SteamTradeOfferRequest {
|
||||
public bool newversion { get; set; }
|
||||
public int version { get; set; }
|
||||
public SteamTradeItemList me { get; set; }
|
||||
public SteamTradeItemList them { get; set; }
|
||||
public SteamTradeOfferRequest (bool nv, int v, SteamTradeItemList m, SteamTradeItemList t) {
|
||||
newversion = nv;
|
||||
version = v;
|
||||
me = m;
|
||||
them = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<!-- This is full-fledged example config, you may be also interested in minimal.xml for bare minimum one -->
|
||||
|
||||
|
||||
<!-- This config includes all user-switchable properties that you may want to change on per-bot basis -->
|
||||
<!-- Default values used in config match default ASF values when given config property is not found -->
|
||||
<!-- In other words, if given property is not defined, ASF will assume default pre-programmed value -->
|
||||
@@ -104,6 +104,23 @@
|
||||
<!-- Personally I suggest leaving it at "false", unless you have a reason to close the process after all bots finished farming -->
|
||||
<ShutdownOnFarmingFinished type="bool" value="false"/>
|
||||
|
||||
|
||||
<!-- if this switch set to "true",the bot would try to send trade offer with all cards to master after farming is finished -->
|
||||
<!-- for sucessfull trade offer bot needs SteamMasterID to be set properly -->
|
||||
<!-- if the master is not a friend of this bot, SteamTradeToken would be needed also -->
|
||||
<SendOnFarmingFinished type="bool" value="false"/>
|
||||
|
||||
<!-- If you bot has a lot of cards to farm, and you don't want to wait till it farm them all, you can use this parameter -->
|
||||
<!-- this setting is the time period of auto-sending bot->master trades in hours-->
|
||||
<!-- for example, if you want bot to send you trade offers once a day, set this to 24 -->
|
||||
<!-- if value is "0" no automatic trade offers would be sent -->
|
||||
<SendTradePeriod type="uint" value="0"/>
|
||||
|
||||
<!-- This is needed to send bot->master trades, only if master is not a friend of bot -->
|
||||
<!-- To get this token go (as master!) here: http://steamcommunity.com/id/ryzhehvost/tradeoffers/privacy -->
|
||||
<!-- the token is last part of link in the field "TradeURL", starting after "&token=" -->
|
||||
<SteamTradeToken type="string" value="null"/>
|
||||
|
||||
<!-- This is comma-separated list of IDs that should not be considered for farming -->
|
||||
<!-- Default value includes appIDs that are wrongly appearing on the profile, e.g. Summer Sale, Winter Sale or Monster Summer Game -->
|
||||
<!-- In addition to blacklist defined here, ASF also has global blacklist, which is being updated on as-needed basis, so you don't need to update this entry -->
|
||||
|
||||
Reference in New Issue
Block a user