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