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