· 9 years ago · Nov 28, 2016, 08:54 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 logMsg("Got web session");
117 community.setCookies(cookies);
118 community.startConfirmationChecker(30000, account.identity_secret);
119
120 botInterval = updateBotInfo(function() {
121 setInterval(function() {
122 updateBotInfo();
123 }, 500 * 1000);
124 });
125 setTimeout(function() {
126 client.webLogOn();
127 }, 10 * 60 * 1000);
128 });
129
130 function getSteamid() {
131 var sid = new SteamID();
132 sid.universe = client.steamID.universe;
133 sid.type = client.steamID.type;
134 sid.instance = client.steamID.instance;
135 sid.accountid = client.steamID.accountid;
136
137 return sid.getSteamID64();
138 }
139
140 function updateBotInfo(callback) {
141 manager.loadInventory("730", "2", false, function(err, inventory) {
142 if (err) {
143 logMsg("Error loading inventory");
144 console.log(err);
145 if (typeof callback !== 'undefined') {
146 callback();
147 }
148 } else {
149 requestify.post('http://' + config.domain + '/bot-api/updateInfo', {
150 secretKey: config.secretKey,
151 items: inventory.length,
152 steamid: account.steamid64
153 }).then(function (response) {
154 var result = JSON.parse(response.body);
155 account.bot_id = result.id;
156
157 logMsg("Updated info");
158
159 if (typeof callback !== 'undefined') {
160 callback();
161 }
162 }, function(response) {
163 logMsg("[Error] Cannot update info");
164 if (typeof callback !== 'undefined') {
165 callback();
166 }
167 });
168 }
169 });
170 }
171
172 function logMsg(log){
173 console.log("[Bot][" + account.username + "] " + log);
174 }
175
176 this.offerTrade = function(trade) {
177 if (existsInList(trade.trade_id)) {
178 return false;
179 }
180 addToList(trade.trade_id);
181
182 var offer = manager.createOffer(new TradeOfferManager.SteamID(trade.steamid), trade.trade_token);
183
184 offer.loadPartnerInventory(730, 2, function(err, inventory) {
185 if (err) {
186 logMsg("[Error] Cannot load their inventory (#" + trade.trade_id + ")");
187 console.log(err);
188 removeFromList(trade.trade_id);
189 } else {
190 var tradeItems = JSON.parse(trade.items);
191
192 for (var i = 0; i < inventory.length; i++) {
193 for (var a = 0; a < tradeItems.length; a++) {
194 if (tradeItems[a] == inventory[i].market_hash_name && inventory[i].added != true) {
195 offer.addTheirItem(inventory[i]);
196 inventory[i].added = true;
197 tradeItems[a] = "";
198 }
199 }
200 }
201
202 // check escrow
203 offer.getUserDetails(function(err, me, them) {
204 if (err) {
205 logMsg("[Error] Error while getting user details");
206 console.log(err);
207 removeFromList(trade.trade_id);
208 } else {
209 if (me.escrowDays == 0 && them.escrowDays == 0) {
210 offer.setMessage('Add items to CSGOSTRESS.COM inventory, offer code ' + trade.offer_code);
211 offer.send(function(err, status) {
212 if (err) {
213 logMsg("[Error] Cannot offer trade #" + trade.trade_id);
214 console.log(err);
215 removeFromList(trade.trade_id);
216 } else {
217 logMsg("Trade offer #" + trade.trade_id + " sent, status " + status);
218 updateTradeStatus({
219 id: trade.trade_id,
220 trade_id: offer.id,
221 status: 2
222 });
223 cancelOffer(7 * 60 * 1000, offer.id);
224 removeFromList(trade.trade_id);
225 }
226 });
227 } else {
228 logMsg("[Error] Cannot offer trade (#" + trade.trade_id + "), my escrow " + me.escrowDays + ", their escrow " + them.escrowDays);
229 updateTradeStatus({
230 id: trade.trade_id,
231 status: 6
232 });
233 removeFromList(trade.trade_id);
234 }
235 }
236 });
237 }
238 });
239 };
240
241 function updateTradeStatus(params) {
242 requestify.post('http://' + config.domain + '/bot-api/finishTrade', {
243 secretKey: config.secretKey,
244 params: JSON.stringify(params)
245 }).then(function(response) {
246 var result = JSON.parse(response.body);
247 logMsg("Trade #" + result.id + " status updated");
248 }, function(response) {
249 logMsg("[Error] Cannot update trade");
250 console.log(params);
251 });
252 }
253
254 this.sendTrade = function(trade) {
255 if (existsInList(trade.trade_id)) {
256 return false;
257 }
258 addToList(trade.trade_id);
259
260 var offer = manager.createOffer(new TradeOfferManager.SteamID(trade.steamid), trade.trade_token);
261
262 manager.loadInventory("730", "2", false, function(err, inventory) {
263 if (err) {
264 logMsg("[Error] Cannot load my inventory (#" + trade.trade_id + ")");
265 console.log(err);
266 removeFromList(trade.trade_id);
267 } else {
268 var tradeItems = JSON.parse(trade.items);
269
270 for (var i = 0; i < inventory.length; i++) {
271 for (var a = 0; a < tradeItems.length; a++) {
272 if (tradeItems[a] == inventory[i].market_hash_name && inventory[i].added != true) {
273 offer.addMyItem(inventory[i]);
274 inventory[i].added = true;
275 tradeItems[a] = "";
276 }
277 }
278 }
279
280 // check escrow
281 offer.getUserDetails(function(err, me, them) {
282 if (err) {
283 logMsg("[Error] Error while getting user details");
284 console.log(err);
285 removeFromList(trade.trade_id);
286 } else {
287 if (me.escrowDays == 0 && them.escrowDays == 0) {
288 offer.setMessage('Withdraw from CSGOSTRESS.COM inventory');
289 offer.send(function(err, status) {
290 if (err) {
291 logMsg("[Error] Cannot offer trade #" + trade.trade_id);
292 console.log(err);
293 removeFromList(trade.trade_id);
294 } else {
295 logMsg("Trade offer #" + trade.trade_id + " sent, status " + status);
296 updateTradeStatus({
297 id: trade.trade_id,
298 trade_id: offer.id,
299 status: 2
300 });
301 cancelOffer(10 * 60 * 1000, offer.id);
302 removeFromList(trade.trade_id);
303 }
304 });
305 } else {
306 logMsg("[Error] Cannot offer trade (#" + trade.trade_id + "), my escrow " + me.escrowDays + ", their escrow " + them.escrowDays);
307 updateTradeStatus({
308 id: trade.trade_id,
309 status: 6
310 });
311 removeFromList(trade.trade_id);
312 }
313 }
314 });
315 }
316 });
317 };
318
319 this.getBotId = function() {
320 return account.bot_id;
321 };
322
323 manager.on('pollData', function(pollData) {
324 fs.writeFile('polldata' + account.username + '.json', JSON.stringify(pollData));
325 });
326
327 manager.on('sentOfferChanged', function(offer, oldState) {
328 logMsg(`Offer #${offer.id} changed: ${TradeOfferManager.ETradeOfferState[oldState]} -> ${TradeOfferManager.ETradeOfferState[offer.state]}`);
329 if (offer.state == 3) {
330 updateTradeStatus({
331 trade_id: offer.id,
332 status: offer.state,
333 items: JSON.stringify(offer.itemsToReceive)
334 });
335 //console.log(offer.itemsToReceive);
336 } else {
337 updateTradeStatus({
338 trade_id: offer.id,
339 status: offer.state
340 });
341 }
342 });
343
344 function cancelOffer(time, offerid) {
345 setTimeout(function() {
346 manager.getOffer(offerid, function(err, offer) {
347 if (err) {
348 logMsg("[Error] Cannot cancel offer (1) #" + offerid);
349 console.log(err);
350 } else {
351 if (offer.state == 2) {
352 offer.cancel(function(err) {
353 if (err) {
354 logMsg("[Error] Cannot cancel offer (2) #" + offerid);
355 } else {
356 logMsg("Offer #" + offerid + " cancelled");
357 }
358 });
359 }
360 }
361 });
362 }, time);
363 }
364
365 function addToList(id) {
366 processingTrades.push(id);
367 }
368
369 function removeFromList(id) {
370 var i = processingTrades.indexOf(id);
371 processingTrades.splice(i, 1);
372 }
373
374 function existsInList(id) {
375 return (processingTrades.indexOf(id) > -1);
376 }
377}