· 9 years ago · Nov 21, 2016, 10:04 PM
1// account login information
2var config = require('./config.js');
3var accounts = config.bots;
4var fs = require('fs');
5var SteamID = require('steamid');
6var requestify_one, io;
7
8module.exports.startBots = function(requestifyCore, ioCore) {
9 requestify_one = requestifyCore;
10 io = ioCore;
11
12 var bots = [];
13 var botId = 0;
14
15 for (var index in accounts) {
16 bots[botId] = new steamBot(index);
17 botId++;
18 }
19
20 checkForTrades();
21 setInterval(function() {
22 checkForTrades();
23 }, 30 * 1000);
24
25 function checkForTrades() {
26 requestify_one.post('http://' + config.domain + '/bot-api/checkTrades', {
27 secretKey: config.secretKey
28 }).then(function(response) {
29 //console.log("[Core] Checking for trades...");
30 var result = JSON.parse(response.body);
31 var trades = result.trades;
32
33 for (var i = 0; i < trades.length; i++) {
34 var trade = trades[i];
35
36 for (var a = 0; a < botId; a++) {
37 if (bots[a].getBotId() == trade.bot_id) {
38 if (trade.type == 1) {
39 bots[a].offerTrade(trade);
40 } else if (trade.type == 2) {
41 bots[a].sendTrade(trade);
42 }
43 }
44 }
45 }
46 }, function(response) {
47 console.log("[Core] Cannot check for trades");
48 });
49 }
50};
51
52// steam bot
53var steamBot = function(index) {
54 var botId = index;
55 var account = accounts[index];
56 var processingTrades = [];
57
58 // library
59 var SteamUser = require('steam-user');
60 var SteamTotp = require('steam-totp');
61 var SteamCommunity = require('steamcommunity');
62 var TradeOfferManager = require('steam-tradeoffer-manager');
63 var CMClient = require('steam-client').CMClient;
64 var requestify = require('requestify');
65
66 var cmc = new CMClient();
67 cmc.bind(account.ip);
68
69 var client = new SteamUser(cmc);
70 var community = new SteamCommunity({
71 "localAddress": account.ip
72 });
73 var manager = new TradeOfferManager({
74 "steam": client, // Polling every 30 seconds is fine since we get notifications from Steam
75 "domain": config.domain, // Our domain is example.com
76 "language": "en", // We want English item descriptions,
77 //"community": community
78 });
79 var botInterval;
80
81 if (fs.existsSync('polldata' + account.username + '.json')) {
82 manager.pollData = JSON.parse(fs.readFileSync('polldata' + account.username + '.json'));
83 }
84
85 client.promptSteamGuardCode = false;
86 client.logOn({
87 "accountName": account.username,
88 "password": account.password,
89 "twoFactorCode": SteamTotp.generateAuthCode(account.shared_secret)
90 });
91
92 client.on('loggedOn', function(details) {
93 logMsg("Logged in (IP: " + client.publicIP + ")");
94 client.setPersona(SteamUser.Steam.EPersonaState.Online);
95
96 account.steamid64 = getSteamid();
97 this.steamid64 = account.steamid64;
98 });
99
100 client.on('error', function(e) {
101 logMsg("Error: ");
102 console.log(e);
103 });
104
105 client.on('webSession', function(sessionID, cookies) {
106 manager.setCookies(cookies, function(err) {
107 if (err) {
108 logMsg("Manager error");
109 console.log(err);
110 process.exit(1); // Fatal error since we couldn't get our API key
111 return;
112 }
113
114 //logMsg("Got API key: " + manager.apiKey);
115 });
116 community.setCookies(cookies);
117 community.startConfirmationChecker(30000, account.identity_secret);
118
119 botInterval = updateBotInfo(function() {
120 setInterval(function() {
121 updateBotInfo();
122 }, 300 * 1000);
123 });
124 setTimeout(function() {
125 client.webLogOn();
126 }, 12 * 60 * 60 * 1000);
127 });
128
129 function getSteamid() {
130 var sid = new SteamID();
131 sid.universe = client.steamID.universe;
132 sid.type = client.steamID.type;
133 sid.instance = client.steamID.instance;
134 sid.accountid = client.steamID.accountid;
135
136 return sid.getSteamID64();
137 }
138
139 function updateBotInfo(callback) {
140 manager.loadInventory("730", "2", false, function(err, inventory) {
141 if (err) {
142 logMsg("Error loading inventory");
143 console.log(err);
144 if (typeof callback !== 'undefined') {
145 callback();
146 }
147 } else {
148 requestify.post('http://' + config.domain + '/bot-api/updateInfo', {
149 secretKey: config.secretKey,
150 items: inventory.length,
151 steamid: account.steamid64
152 }).then(function (response) {
153 var result = JSON.parse(response.body);
154 account.bot_id = result.id;
155
156 logMsg("Updated info");
157
158 if (typeof callback !== 'undefined') {
159 callback();
160 }
161 }, function(response) {
162 logMsg("[Error] Cannot update info");
163 if (typeof callback !== 'undefined') {
164 callback();
165 }
166 });
167 }
168 });
169 }
170
171 function logMsg(log){
172 console.log("[Bot][" + account.username + "] " + log);
173 }
174
175 this.offerTrade = function(trade) {
176 if (existsInList(trade.trade_id)) {
177 return false;
178 }
179 addToList(trade.trade_id);
180
181 var offer = manager.createOffer(new TradeOfferManager.SteamID(trade.steamid), trade.trade_token);
182
183 offer.loadPartnerInventory(730, 2, function(err, inventory) {
184 if (err) {
185 logMsg("[Error] Cannot load their inventory (#" + trade.trade_id + ")");
186 console.log(err);
187 removeFromList(trade.trade_id);
188 } else {
189 var tradeItems = JSON.parse(trade.items);
190
191 for (var i = 0; i < inventory.length; i++) {
192 for (var a = 0; a < tradeItems.length; a++) {
193 if (tradeItems[a] == inventory[i].market_hash_name && inventory[i].added != true) {
194 offer.addTheirItem(inventory[i]);
195 inventory[i].added = true;
196 tradeItems[a] = "";
197 }
198 }
199 }
200
201 // check escrow
202 offer.getUserDetails(function(err, me, them) {
203 if (err) {
204 logMsg("[Error] Error while getting user details");
205 console.log(err);
206 removeFromList(trade.trade_id);
207 } else {
208 if (me.escrowDays == 0 && them.escrowDays == 0) {
209 offer.setMessage('Add items to CSGOSTRESS.COM inventory, offer code ' + trade.offer_code);
210 offer.send(function(err, status) {
211 if (err) {
212 logMsg("[Error] Cannot offer trade #" + trade.trade_id);
213 console.log(err);
214 removeFromList(trade.trade_id);
215 } else {
216 logMsg("Trade offer #" + trade.trade_id + " sent, status " + status);
217 updateTradeStatus({
218 id: trade.trade_id,
219 trade_id: offer.id,
220 status: 2
221 });
222 cancelOffer(5 * 60 * 1000, offer.id);
223 removeFromList(trade.trade_id);
224 }
225 });
226 } else {
227 logMsg("[Error] Cannot offer trade (#" + trade.trade_id + "), my escrow " + me.escrowDays + ", their escrow " + them.escrowDays);
228 updateTradeStatus({
229 id: trade.trade_id,
230 status: 6
231 });
232 removeFromList(trade.trade_id);
233 }
234 }
235 });
236 }
237 });
238 };
239
240 function updateTradeStatus(params) {
241 requestify.post('http://' + config.domain + '/bot-api/finishTrade', {
242 secretKey: config.secretKey,
243 params: JSON.stringify(params)
244 }).then(function(response) {
245 var result = JSON.parse(response.body);
246 logMsg("Trade #" + result.id + " status updated");
247 }, function(response) {
248 logMsg("[Error] Cannot update trade");
249 console.log(params);
250 });
251 }
252
253 this.sendTrade = function(trade) {
254 if (existsInList(trade.trade_id)) {
255 return false;
256 }
257 addToList(trade.trade_id);
258
259 var offer = manager.createOffer(new TradeOfferManager.SteamID(trade.steamid), trade.trade_token);
260
261 manager.loadInventory("730", "2", false, function(err, inventory) {
262 if (err) {
263 logMsg("[Error] Cannot load my inventory (#" + trade.trade_id + ")");
264 console.log(err);
265 removeFromList(trade.trade_id);
266 } else {
267 var tradeItems = JSON.parse(trade.items);
268
269 for (var i = 0; i < inventory.length; i++) {
270 for (var a = 0; a < tradeItems.length; a++) {
271 if (tradeItems[a] == inventory[i].market_hash_name && inventory[i].added != true) {
272 offer.addMyItem(inventory[i]);
273 inventory[i].added = true;
274 tradeItems[a] = "";
275 }
276 }
277 }
278
279 // check escrow
280 offer.getUserDetails(function(err, me, them) {
281 if (err) {
282 logMsg("[Error] Error while getting user details");
283 console.log(err);
284 removeFromList(trade.trade_id);
285 } else {
286 if (me.escrowDays == 0 && them.escrowDays == 0) {
287 offer.setMessage('Withdraw from CSGOSTRESS.COM inventory');
288 offer.send(function(err, status) {
289 if (err) {
290 logMsg("[Error] Cannot offer trade #" + trade.trade_id);
291 console.log(err);
292 removeFromList(trade.trade_id);
293 } else {
294 logMsg("Trade offer #" + trade.trade_id + " sent, status " + status);
295 updateTradeStatus({
296 id: trade.trade_id,
297 trade_id: offer.id,
298 status: 2
299 });
300 cancelOffer(10 * 60 * 1000, offer.id);
301 removeFromList(trade.trade_id);
302 }
303 });
304 } else {
305 logMsg("[Error] Cannot offer trade (#" + trade.trade_id + "), my escrow " + me.escrowDays + ", their escrow " + them.escrowDays);
306 updateTradeStatus({
307 id: trade.trade_id,
308 status: 6
309 });
310 removeFromList(trade.trade_id);
311 }
312 }
313 });
314 }
315 });
316 };
317
318 this.getBotId = function() {
319 return account.bot_id;
320 };
321
322 manager.on('pollData', function(pollData) {
323 fs.writeFile('polldata' + account.username + '.json', JSON.stringify(pollData));
324 });
325
326 manager.on('sentOfferChanged', function(offer, oldState) {
327 logMsg(`Offer #${offer.id} changed: ${TradeOfferManager.ETradeOfferState[oldState]} -> ${TradeOfferManager.ETradeOfferState[offer.state]}`);
328 if (offer.state == 3) {
329 updateTradeStatus({
330 trade_id: offer.id,
331 status: offer.state,
332 items: JSON.stringify(offer.itemsToReceive)
333 });
334 //console.log(offer.itemsToReceive);
335 } else {
336 updateTradeStatus({
337 trade_id: offer.id,
338 status: offer.state
339 });
340 }
341 });
342
343 function cancelOffer(time, offerid) {
344 setTimeout(function() {
345 manager.getOffer(offerid, function(err, offer) {
346 if (err) {
347 logMsg("[Error] Cannot cancel offer (1) #" + offerid);
348 console.log(err);
349 } else {
350 if (offer.state == 2) {
351 offer.cancel(function(err) {
352 if (err) {
353 logMsg("[Error] Cannot cancel offer (2) #" + offerid);
354 } else {
355 logMsg("Offer #" + offerid + " cancelled");
356 }
357 });
358 }
359 }
360 });
361 }, time);
362 }
363
364 function addToList(id) {
365 processingTrades.push(id);
366 }
367
368 function removeFromList(id) {
369 var i = processingTrades.indexOf(id);
370 processingTrades.splice(i, 1);
371 }
372
373 function existsInList(id) {
374 return (processingTrades.indexOf(id) > -1);
375 }
376}