· 9 years ago · May 25, 2016, 06:24 PM
1var fs = require('fs');
2var SteamTotp = require('steam-totp');
3var crypto = require('crypto');
4var console = process.console;
5var config = require('./config.js');
6var Steam = require('steam');
7var SteamWebLogOn = require('steam-weblogon');
8var getSteamAPIKey = require('steam-web-api-key');
9var SteamTradeOffers = require('steam-tradeoffers');
10var redisClient, io, requestify;
11var SteamCommunity = require('steamcommunity');
12var community = new SteamCommunity();
13module.exports.init = function(redis, ioSocket, requestifyCore) {
14 io = ioSocket;
15 redisClient = redis.createClient();
16 requestify = requestifyCore;
17}
18var sharedKey = 'saved_response.txt';
19var SteamTotp = require('steam-totp');
20var logOnOptions = {
21 account_name: config.bot.username,
22 password: config.bot.password,
23 two_factor_code: SteamTotp.generateAuthCode(sharedKey)
24};
25var authCode = ''; // code received by email
26
27try {
28 logOnOptions.sha_sentryfile = getSHA1(fs.readFileSync('ssfn0000000000000000000'));
29} catch (e) {
30 if (authCode !== '') {
31 logOnOptions.auth_code = authCode;
32 }
33}
34function getSHA1(bytes) {
35 var shasum = crypto.createHash('sha1');
36 shasum.end(bytes);
37 return shasum.read();
38}
39// if we've saved a server list, use it
40/*
41 if (fs.existsSync('servers')) {
42 Steam.servers = JSON.parse(fs.readFileSync('servers'));
43 }*/
44
45 /*Приём трейдов*/
46function confirmfuckingtrades(){
47var SteamCommunity = require('steamcommunity');
48var community = new SteamCommunity();
49var SteamTotp = require('steam-totp');
50require('./node_modules/steamcommunity/components/confirmations.js');
51var SteamCommunity = require('steamcommunity');
52var SteamTotp = require('steam-totp');
53var code = SteamTotp.generateAuthCode(sharedKey);
54console.log(code);
55var client = new SteamCommunity();
56client.login({
57 "accountName": "login",
58 "password": "pass",
59 "twoFactorCode": code
60}, function(err, sessionId, cookies, steamguard) {
61var hash = require('crypto').createHash('sha1');
62hash.update(Math.random().toString());
63hash = hash.digest('hex');
64device_id = 'android:' + hash;
65console.log(this.device_id);
66var SteamcommunityMobileConfirmations = require('steamcommunity-mobile-confirmations');
67var steamcommunityMobileConfirmations = new SteamcommunityMobileConfirmations(
68{
69 steamid: "steamid64",
70 identity_secret: "saved_response.txt",
71 device_id: this.device_id,
72 webCookie: cookies,
73});
74
75steamcommunityMobileConfirmations.FetchConfirmations((function (err, confirmations)
76{
77 if (err)
78 {
79 console.log(err);
80 return;
81 }
82 console.log('steamcommunityMobileConfirmations.FetchConfirmations received ' + confirmations.length + ' confirmations');
83 if ( ! confirmations.length)
84 {
85 return;
86 }
87 steamcommunityMobileConfirmations.AcceptConfirmation(confirmations[0], (function (err, result)
88 {
89 if (err)
90 {
91 console.log(err);
92 return;
93 }
94 console.log('steamcommunityMobileConfirmations.AcceptConfirmation result: ' + result);
95 }).bind(this));
96}).bind(this));
97
98})
99}
100/*Приём трейдов*/
101
102var steamClient = new Steam.SteamClient();
103var steamUser = new Steam.SteamUser(steamClient);
104var steamFriends = new Steam.SteamFriends(steamClient);
105var steamWebLogOn = new SteamWebLogOn(steamClient, steamUser);
106var offers = new SteamTradeOffers();
107
108var checkingOffers = [],
109 WebSession = false,
110 globalSession;
111
112const redisChannels = {
113 checkItemsList: 'checkItems.list',
114 checkList: 'check.list',
115 checkedList: 'checked.list',
116 betsList: 'bets.list',
117 sendOffersList: 'send.offers.list',
118 tradeoffersList: 'tradeoffers.list',
119 declineList: 'decline.list',
120 usersQueue: 'usersQueue.list'
121}
122
123function steamBotLogger(log){
124 console.tag('SteamBot').log(log);
125}
126steamClient.connect();
127steamClient.on('debug', steamBotLogger);
128steamClient.on('connected', function() {
129 steamUser.logOn(logOnOptions);
130});
131
132steamClient.on('logOnResponse', function(logonResp) {
133 if (logonResp.eresult === Steam.EResult.OK) {
134 steamBotLogger('Logged in!');
135 steamFriends.setPersonaState(Steam.EPersonaState.Online);
136
137 steamWebLogOn.webLogOn(function(sessionID, newCookie) {
138 getSteamAPIKey({
139 sessionID: sessionID,
140 webCookie: newCookie
141 }, function(err, APIKey) {
142 offers.setup({
143 sessionID: sessionID,
144 webCookie: newCookie,
145 APIKey: APIKey
146 }, function(err){
147 WebSession = true;
148 globalSession = sessionID;
149 redisClient.lrange(redisChannels.tradeoffersList, 0, -1, function(err, offers){
150 offers.forEach(function(offer) {
151 checkingOffers.push(offer);
152 });
153 handleOffers();
154 });
155 steamBotLogger('Setup Offers!');
156 });
157
158 });
159 });
160 }
161});
162
163steamClient.on('servers', function(servers) {
164 fs.writeFile('servers', JSON.stringify(servers));
165});
166
167steamUser.on('updateMachineAuth', function(sentry, callback) {
168 fs.writeFileSync('sentry', sentry.bytes);
169 callback({ sha_file: getSHA1(sentry.bytes) });
170});
171
172function handleOffers() {
173 offers.getOffers({
174 get_received_offers: 1,
175 active_only: 1
176 }, function(error, body) {
177 if (
178 body
179 && body.response
180 && body.response.trade_offers_received
181 ) {
182 body.response.trade_offers_received.forEach(function(offer) {
183 if (offer.trade_offer_state == 2) {
184 if(is_checkingOfferExists(offer.tradeofferid)) return;
185
186 if(offer.items_to_give != null && config.admins.indexOf(offer.steamid_other) != -1) {
187 console.tag('SteamBot', 'TradeOffer').log('TRADE OFFER #' + offer.tradeofferid + ' FROM: Admin ' + offer.steamid_other);
188 offers.acceptOffer({tradeOfferId: offer.tradeofferid});
189 return;
190 }
191 if(offer.items_to_give != null) {
192 offers.declineOffer({tradeOfferId: offer.tradeofferid});
193 return;
194 }
195 console.log(offer.steamid_other);
196 console.log(offer.accessToken);
197 offers.getTradeHoldDuration({tradeOfferId : offer.tradeofferid}, function(err, response)
198 {
199 if (response.their != 0)
200 {
201 offers.declineOffer({tradeOfferId: offer.tradeofferid});
202 console.log('Обмен отклонён потому что нет escrow!')
203 return;
204 }
205 console.log(response.their);
206 });
207 if (offer.items_to_receive != null && offer.items_to_give == null) {
208 checkingOffers.push(offer.tradeofferid);
209 console.tag('SteamBot', 'TradeOffer').log('TRADE OFFER #' + offer.tradeofferid + ' FROM: ' + offer.steamid_other);
210 redisClient.multi([
211 ['rpush', redisChannels.tradeoffersList, offer.tradeofferid],
212 ['rpush', redisChannels.checkItemsList, JSON.stringify(offer)],
213 ['rpush', redisChannels.usersQueue, offer.steamid_other]
214 ]).exec(function(){
215 redisClient.lrange(redisChannels.usersQueue, 0, -1, function(err, queues) {
216 io.sockets.emit('queue', queues);
217 });
218 });
219 return;
220 }
221 }
222 });
223 }
224 });
225}
226
227steamUser.on('tradeOffers', function(number) {
228 if (number > 0) {
229 handleOffers();
230 }
231});
232
233
234var parseOffer = function(offer, offerJson){
235 offers.loadPartnerInventory({partnerSteamId: offer.steamid_other, appId: 730, contextId: 2, tradeOfferId: offer.tradeofferid, language: "russian"}, function(err, hitems) {
236 if (err) {
237 redisClient.multi([
238 ['rpush', redisChannels.declineList, offer.tradeofferid],
239 ['lrem', redisChannels.checkItemsList, 0, offerJson],
240 ['lrem', redisChannels.usersQueue, 1, offer.steamid_other]
241 ])
242 .exec(function (err, replies) {
243 parseItemsProcceed = false;
244 return;
245 });
246 return;
247 }
248 var items = offer.items_to_receive;
249 var items_to_check = [], num = 0;
250 for (var i = 0; i < items.length; i++) {
251 for (var j = 0; j < hitems.length; j++) {
252 if (items[i].assetid == hitems[j].id) {
253 items_to_check[num] = {
254 appid:hitems[j].appid,
255 name:hitems[j].market_name,
256 market_hash_name:hitems[j].market_hash_name,
257 classid:hitems[j].classid
258 };
259 var type = hitems[j].type;
260 var rarity = '';
261 var arr = type.split(',');
262 if (arr.length == 2) type = arr[1].trim();
263 if (arr.length == 3) type = arr[2].trim();
264 if (arr.length && arr[0] == 'Ðож') type = '★';
265 switch (type) {
266 case 'ÐрмейÑкое качеÑтво': rarity = 'milspec'; break;
267 case 'Запрещенное': rarity = 'restricted'; break;
268 case 'ЗаÑекреченное': rarity = 'classified'; break;
269 case 'Тайное': rarity = 'covert'; break;
270 case 'Ширпотреб': rarity = 'common'; break;
271 case 'Промышленное качеÑтво': rarity = 'common'; break;
272 case '★': rarity = 'rare'; break;
273 }
274 items_to_check[num].rarity = rarity;
275 num++;
276 break;
277 }
278 }
279 }
280 var value = {
281 offerid: offer.tradeofferid,
282 accountid: offer.steamid_other,
283 items: JSON.stringify(items_to_check)
284 };
285
286 console.tag('SteamBot', 'Offer #' + value.offerid).log(value);
287
288 redisClient.multi([
289 ['rpush', redisChannels.checkList, JSON.stringify(value)],
290 ['lrem', redisChannels.checkItemsList, 0, offerJson]
291 ])
292 .exec(function (err, replies) {
293 parseItemsProcceed = false;
294 });
295
296 });
297}
298
299var checkOfferPrice = function(){
300 requestify.get('http://'+config.domain+'/api/checkOffer', {
301 secretKey: config.secretKey
302 })
303 .then(function(response) {
304 var answer = JSON.parse(response.body);
305
306 if(answer.success){
307 checkProcceed = false;
308 }
309 },function(response){
310 console.tag('SteamBot').error('Something wrong with check offers. Retry...');
311 setTimeout(function(){checkOfferPrice()}, 1000);
312 });
313
314}
315
316var checkNewBet = function(){
317 requestify.get('http://'+config.domain+'/api/newBet', {
318 secretKey: config.secretKey
319 })
320 .then(function(response) {
321 var answer = JSON.parse(response.body);
322 if(answer.success){
323 betsProcceed = false;
324 }
325 },function(response){
326 console.tag('SteamBot').error('Something wrong with send a new bet. Retry...');
327 setTimeout(function(){checkNewBet()}, 1000);
328 });
329}
330
331var checkArrGlobal = [];
332
333var sendTradeOffer = function(appId, partnerSteamId, accessToken, sendItems, message, game, offerJson){
334 try {
335 offers.loadMyInventory({
336 appId: appId,
337 contextId: 2
338 }, function (err, items) {
339 if(err) {
340 console.log(err);
341 sendProcceed = false;
342 return;
343 }
344 var itemsFromMe = [],
345 checkArr = [],
346 num = 0;
347 var i = 0;
348 for (var i = 0; i < sendItems.length; i++) {
349 for (var j = 0; j < items.length; j++) {
350 if (items[j].tradable && (items[j].classid == sendItems[i])) {
351 if ((checkArr.indexOf(items[j].id) == -1) && (checkArrGlobal.indexOf(items[j].id) == -1)) {
352 checkArr[i] = items[j].id;
353 itemsFromMe[num] = {
354 appid: 730,
355 contextid: 2,
356 amount: items[j].amount,
357 assetid: items[j].id
358 };
359 num++;
360 break;
361 }
362 }
363 }
364 }
365 if (num > 0) {
366 offers.makeOffer({
367 partnerSteamId: partnerSteamId,
368 accessToken: accessToken,
369 itemsFromMe: itemsFromMe,
370 itemsFromThem: [],
371 message: message
372 }, function (err, response) {
373 if (err) {
374 console.tag('SteamBot', 'SendPrize').error('Error to send offer:' + err.message);
375 getErrorCode(err.message, function(errCode){
376 if(errCode == 15) {
377 redisClient.lrem(redisChannels.sendOffersList, 0, offerJson, function (err, data) {
378 setPrizeStatus(game, 2);
379 sendProcceed = false;
380 });
381 sendProcceed = false;
382 }
383 sendProcceed = false;
384 });
385 return;
386 }
387 checkArrGlobal = checkArrGlobal.concat(checkArr);
388 console.log(checkArrGlobal);
389 console.log(checkArr);
390 redisClient.lrem(redisChannels.sendOffersList, 0, offerJson, function(err, data){
391 setPrizeStatus(game, 1);
392 sendProcceed = false;
393 });
394 console.tag('SteamBot', 'SendPrize').log('TradeOffer #' + response.tradeofferid +' send!');
395 confirmfuckingtrades();
396 });
397 }else{
398 console.tag('SteamBot', 'SendPrize').log('Items not found!');
399 redisClient.lrem(redisChannels.sendOffersList, 0, offerJson, function(err, data){
400 setPrizeStatus(game, 1);
401 sendProcceed = false;
402 });
403 }
404 });
405
406 }catch(ex){
407 console.tag('SteamBot').error('Error to send the bet');
408 setPrizeStatus(game, 2);
409 sendProcceed = false;
410 }
411};
412
413var setPrizeStatus = function(game, status){
414 requestify.post('http://'+config.domain+'/api/setPrizeStatus', {
415 secretKey: config.secretKey,
416 game: game,
417 status: status
418 })
419 .then(function(response) {
420
421 },function(response){
422 console.tag('SteamBot').log('Something wrong with set prize status. Retry...');
423 setTimeout(function(){setPrizeStatus()}, 1000);
424 });
425}
426
427var is_checkingOfferExists = function(tradeofferid){
428 for(var i = 0, len = checkingOffers.length; i<len; ++i ){
429 var offer = checkingOffers[i];
430 if(offer == tradeofferid){
431 return true;
432 break;
433 }
434 }
435 return false;
436}
437
438var checkedOffersProcceed = function(offerJson){
439 var offer = JSON.parse(offerJson);
440 if (offer.success) {
441 console.tag('SteamBot').log('Procceding accept: #' + offer.offerid);
442 offers.acceptOffer({tradeOfferId: offer.offerid}, function (err, body) {
443 if (!err) {
444 redisClient.multi([
445 ["lrem", redisChannels.tradeoffersList, 0, offer.offerid],
446 ["lrem", redisChannels.usersQueue, 1, offer.steamid64],
447 ["rpush", redisChannels.betsList, offerJson],
448 ["lrem", redisChannels.checkedList, 0, offerJson]
449 ])
450 .exec(function (err, replies) {
451 redisClient.lrange(redisChannels.usersQueue, 0, -1, function(err, queues) {
452 io.sockets.emit('queue', queues);
453 console.tag('SteamBot').log("New bet Accepted!");
454 checkedProcceed = false;
455 });
456 });
457
458 } else {
459 console.tag('SteamBot').error('Error. With accept tradeoffer #' + offer.offerid)
460 .tag('SteamBot').log(err);
461
462 offers.getOffer({tradeOfferId: offer.offerid}, function (err, body){
463 if(body.response.offer){
464 var offerCheck = body.response.offer;
465 if(offerCheck.trade_offer_state == 2) {
466 checkedProcceed = false;
467 return;
468 }
469 if(offerCheck.trade_offer_state == 3){
470 redisClient.multi([
471 ["lrem", redisChannels.tradeoffersList, 0, offer.offerid],
472 ["lrem", redisChannels.usersQueue, 1, offer.steamid64],
473 ["rpush", redisChannels.betsList, offerJson],
474 ["lrem", redisChannels.checkedList, 0, offerJson]
475 ])
476 .exec(function (err, replies) {
477 redisClient.lrange(redisChannels.usersQueue, 0, -1, function(err, queues) {
478 io.sockets.emit('queue', queues);
479 checkedProcceed = false;
480 });
481 });
482 }else{
483 redisClient.multi([
484 ["lrem", redisChannels.tradeoffersList, 0, offer.offerid],
485 ["lrem", redisChannels.usersQueue, 1, offer.steamid64],
486 ["lrem", redisChannels.checkedList, 0, offerJson]
487 ])
488 .exec(function (err, replies) {
489 redisClient.lrange(redisChannels.usersQueue, 0, -1, function(err, queues) {
490 io.sockets.emit('queue', queues);
491 checkedProcceed = false;
492 });
493 });
494 }
495 }
496 })
497 }
498 });
499 }
500}
501
502var declineOffersProcceed = function(offerid){
503 console.tag('SteamBot').log('Procceding decline: #' + offerid);
504 offers.declineOffer({tradeOfferId: offerid}, function (err, body) {
505 if (!err) {
506 console.tag('SteamBot').log('Offer #' + offerid + ' Decline!');
507 redisClient.lrem(redisChannels.declineList, 0, offerid);
508 declineProcceed = false;
509 } else {
510 console.tag('SteamBot').error('Error. With decline tradeoffer #' + offer.offerid)
511 .tag('SteamBot').log(err);
512 declineProcceed = false;
513 }
514 });
515}
516
517var queueProceed = function(){
518 redisClient.llen(redisChannels.checkList, function(err, length) {
519 if (length > 0 && !checkProcceed) {
520 console.tag('SteamBot','Queues').info('CheckOffers:' + length);
521 checkProcceed = true;
522 checkOfferPrice();
523 }
524 });
525 redisClient.llen(redisChannels.checkedList, function(err, length) {
526 if(length > 0 && !checkedProcceed && WebSession) {
527 console.tag('SteamBot','Queues').info('CheckedOffers:' + length);
528 checkedProcceed = true;
529 redisClient.lindex(redisChannels.checkedList, 0,function (err, offer) {
530 checkedOffersProcceed(offer);
531 });
532 }
533 });
534 redisClient.llen(redisChannels.declineList, function(err, length) {
535 if(length > 0 && !declineProcceed && WebSession) {
536 console.tag('SteamBot','Queues').info('DeclineOffers:' + length);
537 declineProcceed = true;
538 redisClient.lindex(redisChannels.declineList, 0,function (err, offer) {
539 declineOffersProcceed(offer);
540 });
541 }
542 });
543 redisClient.llen(redisChannels.betsList, function(err, length) {
544 if (length > 0 && !betsProcceed && !delayForNewGame) {
545 console.tag('SteamBot','Queues').info('Bets:' + length);
546 betsProcceed = true;
547 checkNewBet();
548 }
549 });
550 redisClient.llen(redisChannels.sendOffersList, function(err, length) {
551 if (length > 0 && !sendProcceed && WebSession) {
552 console.tag('SteamBot','Queues').info('Send winner offers:' + length);
553 sendProcceed = true;
554 redisClient.lindex(redisChannels.sendOffersList, 0,function (err, offerJson) {
555 offer = JSON.parse(offerJson);
556 sendTradeOffer(offer.appId, offer.steamid, offer.accessToken, offer.items, '', offer.game, offerJson);
557 });
558 }
559 });
560 redisClient.llen(redisChannels.checkItemsList, function(err, length) {
561 if (length > 0 && !parseItemsProcceed && WebSession) {
562 console.tag('SteamBot','Queues').info('Parse items:' + length);
563 parseItemsProcceed = true;
564 redisClient.lindex(redisChannels.checkItemsList, 0, function (err, offerJson) {
565 offer = JSON.parse(offerJson);
566 parseOffer(offer, offerJson);
567 });
568 }
569 });
570}
571var parseItemsProcceed = false;
572var checkProcceed = false;
573var checkedProcceed = false;
574var declineProcceed = false;
575var betsProcceed = false;
576var sendProcceed = false;
577var delayForNewGame = false;
578setInterval(queueProceed, 1500);
579
580module.exports.handleOffers = handleOffers;
581module.exports.delayForNewGame = function(value){
582 delayForNewGame = value;
583};
584
585
586function getErrorCode(err, callback){
587 var errCode = 0;
588 var match = err.match(/\(([^()]*)\)/);
589 if(match != null && match.length == 2) errCode = match[1];
590 callback(errCode);
591}