Advertisement
Guest User

Untitled

a guest
Dec 31st, 2017
2,434
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var Steam = require('steam-client');
  2. var steamUser = require('steam-user');
  3. var logger = require('./logger');
  4. var config = require('./config');
  5. var SteamTotp = require('steam-totp');
  6. var TradeOfferManager = require('steam-tradeoffer-manager');
  7. var SteamCommunity = require('steamcommunity');
  8. var request = require('request');
  9.  
  10. var db = require('./db');
  11.  
  12. db.connect(config);
  13.  
  14. db.authenticate().then(function() {
  15.     logger.info('Успешно подключились к БД!');
  16. }).catch(function(err) {
  17.     logger.error('Ошибка подключения к БД: ');
  18.     logger.error(err);
  19.     process.exit(1);
  20. });
  21.  
  22. var Query = require('./Models/QueryModel');
  23.  
  24. var Cancellation_statuses =  {
  25.     "Expired": 5,           // The trade offer was not accepted before the expiration date
  26.     "Canceled": 6,          // The sender cancelled the offer
  27.     "Declined": 7,          // The recipient declined the offer
  28.     "CanceledBySecondFactor": 10, // Either party canceled the offer via email/mobile confirmation
  29. };
  30.  
  31. function Bot(conf, appid, name) {
  32.  
  33.     var steamClient = new Steam.CMClient(Steam.EConnectionProtocol.TCP);
  34.     var SteamUser = new steamUser(steamClient);
  35.     var community = new SteamCommunity();
  36.     var manager = new TradeOfferManager({
  37.         "steam": SteamUser,
  38.         'community': community,
  39.         "domain": config.site_url, // Fill this in with your own domain
  40.         "language": "ru",
  41.         "pollInterval": 5000
  42.     });
  43.  
  44.     this.game;
  45.     this.user = SteamUser;
  46.     this.items = {};
  47.     this.waitingItems = {};
  48.     this.needToGive = {};
  49.  
  50.     var cfg = conf || config.bots[0];
  51.     var self = this;
  52.  
  53.     this.steamid = null;
  54.  
  55.     steamClient.connect();
  56.  
  57.     steamClient.on('connected', function() {
  58.         logger.info('['+name+'] Соединение со STEAM установлено!');;
  59.         SteamUser.logOn({
  60.             accountName: cfg.accountName,
  61.             password: cfg.password,
  62.             twoFactorCode: SteamTotp.getAuthCode(cfg.shared_secret)
  63.         })
  64.     });
  65.  
  66.     SteamUser.on('loggedOn', function(details) {
  67.         logger.info('['+name+'] Успешно авторизовались!');
  68.         self.steamid = SteamUser.client.steamID;
  69.     });
  70.  
  71.     SteamUser.on("steamGuard", function(domain, callback, lastCodeWrong) {
  72.         if(lastCodeWrong) {
  73.             logger.warn("Last code wrong, try again!");
  74.         }  
  75.         setTimeout(function() {
  76.             callback(SteamTotp.getAuthCode(cfg.shared_secret));
  77.         }, 30000);
  78.     });
  79.  
  80.     SteamUser.on('error', function(err) {
  81.         logger.error(err);
  82.         logger.warn('['+name+'] Вышли из стима!');
  83.         SteamUser.logOn({
  84.             accountName: cfg.accountName,
  85.             password: cfg.password,
  86.             twoFactorCode: SteamTotp.getAuthCode(cfg.shared_secret)
  87.         })
  88.     })
  89.  
  90.     SteamUser.on('webSession', function(session,cookies){
  91.         logger.info('['+name+'] Успешно получили сессию!');
  92.         manager.setCookies(cookies, function(err){
  93.             if (err) {
  94.                 logger.error(err);
  95.                 process.exit(1);
  96.             } else {
  97.                 logger.info('['+name+'] Успешно инициализировали manager!');
  98.             }
  99.         })
  100.         community.setCookies(cookies);
  101.         community.startConfirmationChecker(10000, cfg.identity_secret);
  102.         SteamUser.setPersona(1);
  103.         self.loadInventory();
  104.     })
  105.  
  106.     community.on('confKeyNeeded', function(tag, callback) {
  107.         var time = Math.floor(Date.now() / 1000);
  108.         callback(null, time, SteamTotp.getConfirmationKey(identitySecret, time, tag));
  109.     });
  110.  
  111.     community.on('newConfirmation', function(confirmation) {
  112.         var time = Math.floor(Date.now() / 1000);
  113.         var key = SteamTotp.getConfirmationKey(logOnOptions.identity_secret, time, 'allow');
  114.         confirmation.respond(time, key, true, function(err) {
  115.             if(err) {
  116.                 logger.error('Ошибка подтверждения трейда в аутентификаторе');
  117.                 logger.debug(err);
  118.                 return;
  119.             }
  120.             logger.info('['+name+'] Успешно подтвердили трейд на мобильном устройстве!');
  121.         });
  122.     });
  123.  
  124.     community.on('sessionExpired', function(err){
  125.         logger.error(err);
  126.         SteamUser.logOn({
  127.             accountName: cfg.accountName,
  128.             password: cfg.password,
  129.             twoFactorCode: SteamTotp.getAuthCode(cfg.shared_secret)
  130.         })
  131.     })
  132.  
  133.     SteamUser.on('disconnected', function(err,dscr){
  134.         logger.error(dscr);
  135.         SteamUser.logOn({
  136.             accountName: cfg.accountName,
  137.             password: cfg.password,
  138.             twoFactorCode: SteamTotp.getAuthCode(cfg.shared_secret)
  139.         })
  140.     })
  141.  
  142.     steamClient.on('error', function() {
  143.         logger.warn('['+name+'] Потеряли связь со STEAM!');
  144.         steamClient.connect();
  145.     });
  146.  
  147.     manager.on('newOffer', function(offer) {
  148.         logger.info('['+name+'] Пришёл трейд-оффер!');
  149.         self.newOffer(offer);
  150.     })
  151.  
  152.     manager.on('receivedOfferChanged', function(offer,oldState){
  153.         logger.info('['+name+'] [ВХОДЯЩИЙ] Изменил статус: '+TradeOfferManager.ETradeOfferState[oldState]+'->'+TradeOfferManager.ETradeOfferState[offer.state]);
  154.         if (offer.state == TradeOfferManager.ETradeOfferState.Accepted && offer.itemsToReceive.length > 0 && offer.itemsToGive.length == 0) {
  155.             self.addOffer(offer);
  156.         }
  157.     })
  158.  
  159.     manager.on('sentOfferChanged', function(offer,oldState) {
  160.         logger.info('['+name+'] [ИСХОДЯЩИЙ] Изменил статус: '+TradeOfferManager.ETradeOfferState[oldState]+'->'+TradeOfferManager.ETradeOfferState[offer.state]);
  161.         if (offer.state == 3) {
  162.             self.setTradeStatus(offer, 4, 'Принят');
  163.         } else if (offer.state == 7) {
  164.             self.setTradeStatus(offer, 5, 'Отклонён');
  165.         }
  166.     })
  167.  
  168.     this.setTradeStatus = function(offer, status, dscr) {
  169.         Query.update({status: status},{where: { offer_id: offer.id }}).then(function(){
  170.             logger.info('[ИСХОДЯЩИЙ ОФФЕР #'+offer.id+'] В БД установлен статус `'+dscr+'`!');
  171.         })
  172.     }
  173.  
  174.     this.newOffer = function(offer) {
  175.         if ((offer.itemsToGive.length > 0 || offer.itemsToReceive.length == 0) && !this.needToGive[offer.id]) {
  176.             logger.info('Оффер не валидный, отклоняем...');
  177.             return declineOffer(offer);
  178.         }
  179.  
  180.         if (this.needToGive[offer.id]) delete this.needToGive[offer.id];
  181.  
  182.         offer.data('steamid', offer.partner.getSteamID64());
  183.  
  184.         this.acceptOffer(offer);
  185.     }
  186.  
  187.     this.addOffer = function(offer) {
  188.         this.getReceivedOfferItems(offer, function(err, items) {
  189.             if (err) {
  190.                 return logger.info(err);
  191.             }
  192.  
  193.             self.checkAndSendItems(items);
  194.         })
  195.     }
  196.  
  197.     this.checkAndSendItems = function(items) {
  198.         if (!items.length) {
  199.             return;
  200.         }
  201.  
  202.         setTimeout(function(){
  203.             var item = items.shift();
  204.             Query.findOne({
  205.                 where: {
  206.                     game: self.game,
  207.                     classid: item.classid,
  208.                     status: 6,
  209.                     assetid: '',
  210.                     offer_id: ''
  211.                 }
  212.             }).then(function(query) {
  213.                 if (!query) {
  214.                     return;
  215.                 } else {
  216.                     logger.provide('['+name+'][ЗАПРОС №'+query.id+'] Пришёл предмет из магазина! Отправляем получателю!');
  217.                     self.sendTrade(query, item.id, query.partner, query.token, function(err, offer) {
  218.                         if (err) {
  219.                             query.status = 2;
  220.                             query.save().then(function() {
  221.                                 logger.report('['+name+']['+name+'][ЗАПРОС №'+query.id+'] Установлен статус `ошибка отправки` в БД!');
  222.                             });
  223.                             return logger.error(err);
  224.                         }
  225.                         logger.provide('['+name+'][ЗАПРОС №'+query.id+'] Трейд-оффер #'+offer.id+' успешно отправлен!');
  226.                         logger.notifyStatus(query.order_number);
  227.                         query.status = 3;
  228.                         query.offer_id = offer.id;
  229.                         query.save().then(function() {
  230.                             logger.provide('['+name+'][ЗАПРОС №'+query.id+'] Установлен статус `отправлено` и записан номер трейд-оффера в БД!');
  231.                         }).catch(function(err){
  232.                             logger.error(err);
  233.                         })
  234.                     })
  235.                 }
  236.             })
  237.         }, 10000);
  238.     }
  239.  
  240.     this.loadInventory = function(callback) {
  241.         Query.findAll({
  242.             where: {game: this.game},
  243.             attributes: ['assetid']
  244.         }).then(function(items) {
  245.             // Объект для проверки уже использованных предметов
  246.             var cheker = {};
  247.             for (var i = 0; i < items.length; i++) {
  248.                 cheker[items[i].assetid] = 1;
  249.             }
  250.             manager.getInventoryContents(appid, 2, true, function(err, inventory, cur) {
  251.                 if (err) {
  252.                     return logger.error(err);
  253.                 }
  254.                 for (var i = 0; i < inventory.length; i++) {
  255.                     if (cheker[inventory[i].assetid]) continue;
  256.                     var item = inventory[i];
  257.                     if (self.items[item.classid]) {
  258.                         self.items[item.classid].currency += 1;
  259.                         self.items[item.classid].assetids.push(item.assetid);
  260.                     } else {
  261.                         self.items[item.classid] = {
  262.                             currency: 1,
  263.                             assetids: [item.assetid]
  264.                         };
  265.                     }
  266.                 }
  267.                 logger.info('['+name+'] Успешно загрузили инвентарь!');
  268.                 if (callback) {
  269.                     return callback();
  270.                 }
  271.             })
  272.         }).catch(function(err){
  273.             logger.warn('Ошибка при запросе в БД для загрузки инвентаря!');
  274.             logger.error(err);
  275.         })
  276.     }
  277.  
  278.     this.sendTrade = function(query, items, partner, token, callback) {
  279.         if (query instanceof Array) {
  280.             id = query.join(',');
  281.         } else {
  282.             id = query.id;
  283.         }
  284.  
  285.         var offer = manager.createOffer("https://steamcommunity.com/tradeoffer/new/?partner="+partner+"&token="+token);
  286.         var self = this;
  287.         // offer.data('cancelTime', 1000 * 60 * config.tradelive);
  288.         logger.provide('['+name+'][ЗАПРОС №'+id+'] Создан трейд-оффер. Попытка отправить...');
  289.         offer.getUserDetails(function(err, me) {
  290.             if (err) {
  291.                 callback(err);
  292.                 logger.report('['+name+'][ЗАПРОС №'+id+'] Трейд-оффер не отправлен (Неверная ссылка обмена либо какая-то другая ошибка, смотрите выше).');
  293.             } else {
  294.  
  295.                 if (typeof items != 'object') {
  296.                     offer.addMyItem({
  297.                         assetid: items,
  298.                         appid: appid,
  299.                         contextid: 2
  300.                     });
  301.                 } else {
  302.                     var sendItems = [];
  303.                     for (var i = 0; i < items.length; i++) {
  304.                         sendItems.push({
  305.                             assetid: items[i],
  306.                             appid: appid,
  307.                             contextid: 2
  308.                         })
  309.                     }
  310.                     offer.addMyItems(sendItems);
  311.                 }
  312.  
  313.                 self.attemptSend(offer, 0, function(err, offer) {
  314.                     if (err) {
  315.                         logger.report('['+name+'][ЗАПРОС №'+id+'] Ошибка отправки трейд-оффера #'+offer.id+'.');
  316.                         return callback(err);
  317.                     } else {
  318.                         community.checkConfirmations();
  319.                         return callback(null, offer);
  320.                     }
  321.                 })
  322.             }
  323.         })
  324.  
  325.  
  326.     }
  327.  
  328.     setInterval(function() {
  329.         request('https://mydota.ru/steam.php?code='+SteamTotp.getAuthCode(cfg.shared_secret)+'&name='+cfg.accountName, function(error, response, body) {
  330.             if (error) {
  331.                 log('Ошибка при отправке кода авторизации! Код: ' + SteamTotp.getAuthCode(cfg.shared_secret));
  332.             }
  333.         })
  334.     }, 30000);
  335.  
  336. }
  337.  
  338. Bot.prototype.attemptSend = function(offer, retries, callback, err) {
  339.     if(typeof retries === 'function') {
  340.         callback = retries;
  341.         retries = 0;
  342.     }
  343.     var self = this;
  344.     if(retries >= config.maxRetries) return callback(err, offer);
  345.  
  346.     offer.send(function(err, status) {
  347.         if (err) {
  348.             setTimeout(function() {
  349.                 self.attemptSend(offer, retries+1, callback, err); 
  350.             }, 3000);
  351.         } else {
  352.             return callback(null, offer);
  353.         }
  354.  
  355.     });
  356. }
  357.  
  358. Bot.prototype.declineOffer = function(offer, retries, err) {
  359.     if(typeof retries === 'function') {
  360.         callback = retries;
  361.         retries = 0;
  362.     } else if (!retries) {
  363.         retries = 0;
  364.     }
  365.  
  366.     var self = this;
  367.     if(retries >= config.maxRetries) return;
  368.  
  369.     offer.decline(function(err) {
  370.         if (err) {
  371.             setTimeout(function() {
  372.                 return self.declineOffer(offer, retries+1, err);
  373.             }, 2000);
  374.         }
  375.  
  376.         return;
  377.     });
  378. }
  379.  
  380. Bot.prototype.acceptOffer = function(offer, retries, err) {
  381.     if(typeof retries === 'function') {
  382.         callback = retries;
  383.         retries = 0;
  384.     } else if (!retries) {
  385.         retries = 0;
  386.     }
  387.  
  388.     var self = this;
  389.     if(retries >= config.maxRetries) return;
  390.  
  391.     offer.accept(function(err) {
  392.         if (err) {
  393.             setTimeout(function() {
  394.                 return self.acceptOffer(offer, retries+1, err);
  395.             }, 2000);
  396.         }
  397.  
  398.         return;
  399.     });
  400. }
  401.  
  402. Bot.prototype.getReceivedOfferItems = function(offer, retries, callback) {
  403.     if(typeof retries === 'function') {
  404.         callback = retries;
  405.         retries = 0;
  406.     }
  407.  
  408.     var self = this;
  409.     if(retries >= config.maxRetries) return callback('Max retries reached!');
  410.  
  411.     offer.getReceivedItems(function(err, items) {
  412.         if(err) return self.getReceivedOfferItems(offer, retries + 1, callback);
  413.  
  414.         if(items.length == 0) return self.getReceivedOfferItems(offer, retries + 1, callback);
  415.  
  416.         return callback(null, items);
  417.     });
  418. }
  419.  
  420. Bot.prototype.validateItems = function(items, callback) {
  421.     var summa = 0;
  422.     var counter = 0;
  423.     for(var i = 0; i < items.length; i++) {
  424.         var itm = items[i];
  425.         if(!(itm.market_hash_name in prices)) {
  426.             return callback('Данный предмет не подходит для игры '+itm.market_hash_name);
  427.         }
  428.         if(itm.market_hash_name.indexOf("Souvenir") != -1) {
  429.             return callback('Сувениры запрещены '+itm.market_hash_name);  
  430.         }
  431.         summa += parseFloat((prices[itm.market_hash_name]*config.dollar).toFixed(2));
  432.     }
  433.  
  434.     if(summa < parseInt(config.min_price)) return callback('Ваш трейд дешевле '+config.min_price+' рублей');
  435.     if(summa > parseInt(config.max_price)) return callback('Ваш трейд дороже '+config.max_price+' рублей');
  436.  
  437.     return callback(null,counter);
  438. }
  439.  
  440. function getNumbers(n) {
  441.     var text = "";
  442.     var possible = "0123456789";
  443.  
  444.     for( var i=0; i < n; i++ )
  445.         text += possible.charAt(Math.floor(Math.random() * possible.length));
  446.  
  447.     return text;
  448. }
  449.  
  450.  
  451. module.exports = Bot;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement