· 10 years ago · Feb 20, 2016, 11:42 AM
1var fs = require('fs');
2var crypto = require('crypto');
3var console = process.console;
4var config = require('./config.js');
5var Steam = require('steam');
6var SteamWebLogOn = require('steam-weblogon');
7var getSteamAPIKey = require('steam-web-api-key');
8var SteamTradeOffers = require('steam-tradeoffers');
9var redisClient, requestify;
10var SteamTotp = require('steam-totp');
11var SteamcommunityMobileConfirmations = require('steamcommunity-mobile-confirmations');
12module.exports.init = function(redis, requestifyCore) {
13 redisClient = redis.createClient();
14 requestify = requestifyCore;
15}
16
17var logOnOptions = {
18 account_name: config.shopBot.username,
19 password: config.shopBot.password,
20 two_factor_code: SteamTotp.generateAuthCode(config.shopBot.shared_secret)
21};
22console.tag('SteamBotShop').log('Код авторизиции '+SteamTotp.generateAuthCode(config.shopBot.shared_secret));
23function gucode(){
24 console.tag('SteamBotShop').log('Код авторизиции '+SteamTotp.generateAuthCode(config.shopBot.shared_secret));
25 setTimeout(function(){ gucode() }, 30000)
26}
27gucode();
28//var authCode = 'TCG2W'; // code received by email
29
30//try {
31 // logOnOptions.sha_sentryfile = getSHA1(fs.readFileSync('sentry_shop'));
32//} catch (e) {
33 // if (authCode !== '') {
34 // logOnOptions.auth_code = authCode;
35 // }
36//}
37function getSHA1(bytes) {
38 var shasum = crypto.createHash('sha1');
39 shasum.end(bytes);
40 return shasum.read();
41}
42// if we've saved a server list, use it
43if (fs.existsSync('servers')) {
44 Steam.servers = JSON.parse(fs.readFileSync('servers'));
45}
46
47var steamClient = new Steam.SteamClient();
48var steamUser = new Steam.SteamUser(steamClient);
49var steamFriends = new Steam.SteamFriends(steamClient);
50var steamWebLogOn = new SteamWebLogOn(steamClient, steamUser);
51var offers = new SteamTradeOffers();
52
53var checkingOffers = [],
54 WebSession = false,
55 globalSession;
56
57const redisChannels = {
58 itemsToSale: 'items.to.sale',
59 itemsToGive: 'items.to.give',
60 offersToCheck: 'offers.to.check'
61}
62
63function steamBotLogger(log){
64 console.tag('SteamBotShop').log(log);
65}
66steamClient.connect();
67steamClient.on('debug', steamBotLogger);
68steamClient.on('connected', function() {
69 steamUser.logOn(logOnOptions);
70});
71//steamClient.on('loggedOff', function () {
72 // try to log back on
73//steamUser.logOn(logOnOptions);
74//});
75
76steamClient.on('logOnResponse', function(logonResp) {
77 if (logonResp.eresult === Steam.EResult.OK) {
78 steamBotLogger('Logged in!');
79 steamFriends.setPersonaState(Steam.EPersonaState.Online);
80
81 steamWebLogOn.webLogOn(function(sessionID, newCookie) {
82 function trademobile(){
83var hash = require('crypto').createHash('sha1');
84hash.update(Math.random().toString());
85hash = hash.digest('hex');
86device_id = 'android:' + hash;
87var steamcommunityMobileConfirmations = new SteamcommunityMobileConfirmations(
88{
89 steamid: config.shopBot.steamid,
90identity_secret: config.shopBot.identity_secret,
91device_id: this.device_id,
92 webCookie: newCookie,
93});
94steamcommunityMobileConfirmations.FetchConfirmations((function (err, confirmations)
95{
96 if (err)
97 {
98 console.tag('SteamBot').error(err);
99 return;
100 }
101 console.tag('ESCROW').log('Трейдов: ' + confirmations.length + '');
102 if ( ! confirmations.length)
103 {
104 return;
105 }
106 steamcommunityMobileConfirmations.AcceptConfirmation(confirmations[0], (function (err, result)
107 {
108 if (err)
109 {
110 console.tag('SteamBot').console.error(err);
111 return;
112 }
113 console.tag('ESCROW').log('Результат: ' + result);
114 }).bind(this));
115}).bind(this));
116 setTimeout(function(){ trademobile()}, 1000)
117}
118trademobile();
119 getSteamAPIKey({
120 sessionID: sessionID,
121 webCookie: newCookie
122 }, function(err, APIKey) {
123 offers.setup({
124 sessionID: sessionID,
125 webCookie: newCookie,
126 APIKey: APIKey
127 }, function(err){
128 WebSession = true;
129 globalSession = sessionID;
130 redisClient.lrange(redisChannels.tradeoffersList, 0, -1, function(err, offers){
131 offers.forEach(function(offer) {
132 checkingOffers.push(offer);
133 });
134 handleOffers();
135 });
136 steamBotLogger('Setup Offers!');
137 });
138
139 });
140 });
141 }
142});
143
144steamClient.on('servers', function(servers) {
145 fs.writeFile('servers', JSON.stringify(servers));
146});
147
148steamUser.on('updateMachineAuth', function(sentry, callback) {
149 fs.writeFileSync('sentry_shop', sentry.bytes);
150 callback({ sha_file: getSHA1(sentry.bytes) });
151});
152
153function handleOffers() {
154 offers.getOffers({
155 get_received_offers: 1,
156 active_only: 1
157 }, function(error, body) {
158 if (
159 body
160 && body.response
161 && body.response.trade_offers_received
162 ) {
163 body.response.trade_offers_received.forEach(function(offer) {
164 if (offer.trade_offer_state == 2) {
165 if(config.admins.indexOf(offer.steamid_other) != -1){
166 offers.acceptOffer({
167 tradeOfferId: offer.tradeofferid
168 }, function(error, traderesponse) {
169 if(!error) {
170 if ('undefined' != typeof traderesponse.tradeid) {
171 offers.getItems({
172 tradeId: traderesponse.tradeid
173 }, function (error, recieved_items) {
174 if (!error) {
175 var itemsForParse = [], itemsForSale = [], i = 0;
176 recieved_items.forEach(function(item){
177 itemsForParse[i++] = item.id;
178 })
179 offers.loadMyInventory({appId: 730, contextId: 2, language: 'russian'}, function(error, botItems){
180 if(!error){
181 i = 0;
182 botItems.forEach(function(item){
183 if(itemsForParse.indexOf(item.id) != -1){
184 var rarity = '', type = '';
185 var arr = item.type.split(',');
186 if (arr.length == 2) rarity = arr[1].trim();
187 if (arr.length == 3) rarity = arr[2].trim();
188 if (arr.length && arr[0] == 'Ðож') rarity = 'Тайное';
189 if (arr.length) type = arr[0];
190 var quality = item.market_name.match(/\(([^()]*)\)/);
191 if(quality != null && quality.length == 2) quality = quality[1];
192 itemsForSale[i++] = {
193 inventoryId: item.id,
194 classid: item.classid,
195 name: item.name,
196 market_hash_name: item.market_hash_name,
197 rarity: rarity,
198 quality: quality,
199 type: type
200 }
201 }
202 });
203 }
204 redisClient.rpush(redisChannels.itemsToSale, JSON.stringify(itemsForSale));
205 return;
206 });
207 }
208 return;
209 });
210 }
211 }
212 return;
213 });
214 }else{
215 offers.declineOffer({tradeOfferId: offer.tradeofferid});
216 }
217 return;
218 }
219 });
220 }
221 });
222}
223
224steamUser.on('tradeOffers', function(number) {
225 console.log('Offers: ' + number);
226 if (number > 0) {
227 handleOffers();
228 }
229});
230
231var sendTradeOffer = function(offerJson){
232 var offer = JSON.parse(offerJson);
233 try {
234 offers.loadMyInventory({
235 appId: 730,
236 contextId: 2
237 }, function (err, items) {
238 var itemsFromMe = [];
239
240 items.forEach(function(item){
241 if(item.id == offer.itemId){
242 itemsFromMe[0] = {
243 appid: 730,
244 contextid: 2,
245 amount: item.amount,
246 assetid: item.id
247 };
248 }
249 });
250
251
252
253
254function getErrorCode(err, callback){
255 var errCode = 0;
256 var match = err.match(/\(([^()]*)\)/);
257 if(match != null && match.length == 2) errCode = match[1];
258 callback(errCode);
259}
260
261 if (itemsFromMe.length > 0) {
262 offers.makeOffer({
263 partnerSteamId: offer.partnerSteamId,
264 accessToken: offer.accessToken,
265 itemsFromMe: itemsFromMe,
266 itemsFromThem: [],
267 message: 'Your purchase on the site '+config.domain+''
268 }, function (err, response) {
269 if (err) {
270 //console.tag('SteamBotShop', 'SendItem').error('Error to send offer. Error: ' + err);
271
272 getErrorCode(err.message, function(errCode){
273if(errCode == 15 || errCode == 25 || err.message.indexOf('an error sending your trade offer. Please try again later.')) {
274 redisClient.lrem(redisChannels.itemsToGive, 0, offerJson, function (err, data) {
275 setItemStatus(offer.id, 4);
276 sendProcceed = false;
277 });
278
279 sendProcceed = false;
280 }
281 sendProcceed = false;
282 });
283 sendProcceed = false;
284 }else if(response){
285 redisClient.lrem(redisChannels.itemsToGive, 0, offerJson, function(err, data){
286 sendProcceed = false;
287 setItemStatus(offer.id, 3);
288 console.tag('SteamBotShop', 'SendItem').log('TradeOffer #' + response.tradeofferid +' send!');
289 redisClient.rpush(redisChannels.offersToCheck, response.tradeofferid);
290 });}
291 });
292 }else{
293 console.tag('SteamBotShop', 'SendItem').log('Items not found!');
294 setItemStatus(offer.id, 2);
295 redisClient.lrem(redisChannels.itemsToGive, 0, offerJson, function(err, data){
296 sendProcceed = false;
297 });
298 }
299 });
300
301 }catch(ex){
302 console.tag('SteamBotShop').error('Error to send the item');
303 sendProcceed = false;
304 }
305};
306
307var setItemStatus = function(item, status){
308 requestify.post('http://'+config.domain+'/api/shop/setItemStatus', {
309 secretKey: config.secretKey,
310 id: item,
311 status: status
312 })
313 .then(function(response) {
314 },function(response){
315 console.tag('SteamBotShop').error('Something wrong with setItemStatus. Retry...');
316 setTimeout(function(){setItemStatus()}, 1000);
317 });
318}
319
320var addNewItems = function(){
321 requestify.get('http://'+config.domain+'/api/shop/newItems', {
322 secretKey: config.secretKey
323 })
324 .then(function(response) {
325 var answer = JSON.parse(response.body);
326 if(answer.success){
327 itemsToSaleProcced = false;
328 }
329 },function(response){
330 console.tag('SteamBotShop').error('Something wrong with newItems. Retry...');
331 setTimeout(function(){addNewItems()}, 1000);
332 });
333}
334
335var checkOfferForExpired = function(offer){
336 offers.getOffer({tradeOfferId: offer}, function (err, body){
337 if(body.response.offer){
338 var offerCheck = body.response.offer;
339 if(offerCheck.trade_offer_state == 2) {
340 var timeCheck = Math.floor(Date.now() / 1000) - offerCheck.time_created;
341 console.log(timeCheck);
342 if(timeCheck >= config.shopBot.timeForCancelOffer){
343 offers.cancelOffer({tradeOfferId: offer}, function(err, response){
344 if(!err){
345 redisClient.lrem(redisChannels.offersToCheck, 0, offer, function(err, data){
346 steamBotLogger('Offer #' + offer + ' was expired!')
347 checkProcceed = false;
348 });
349 }else{
350 checkProcceed = false;
351 }
352 });
353 }else{
354 checkProcceed = false;
355 }
356 return;
357 }else if(offerCheck.trade_offer_state == 3 || offerCheck.trade_offer_state == 7){
358 redisClient.lrem(redisChannels.offersToCheck, 0, offer, function(err, data){
359 checkProcceed = false;
360 });
361 }else{
362 checkProcceed = false;
363 }
364 }else{
365 checkProcceed = false;
366 }
367 })
368}
369
370var queueProceed = function(){
371 redisClient.llen(redisChannels.itemsToSale, function(err, length) {
372 if (length > 0 && !itemsToSaleProcced) {
373 console.tag('SteamBotShop','Queues').info('New items to sale:' + length);
374 itemsToSaleProcced = true;
375 addNewItems();
376 }
377 });
378 redisClient.llen(redisChannels.itemsToGive, function(err, length) {
379 if (length > 0 && !sendProcceed && WebSession) {
380 console.tag('SteamBotShop','Queues').info('Send items:' + length);
381 sendProcceed = true;
382 redisClient.lindex(redisChannels.itemsToGive, 0,function (err, offerJson) {
383 sendTradeOffer(offerJson);
384 });
385 }
386 });
387 redisClient.llen(redisChannels.offersToCheck, function(err, length) {
388 if (length > 0 && !checkProcceed && WebSession) {
389 console.tag('SteamBotShop','Queues').info('Check Offers:' + length);
390 checkProcceed = true;
391 redisClient.lindex(redisChannels.offersToCheck, 0,function (err, offer) {
392 setTimeout(function(){
393 checkOfferForExpired(offer)
394 }, 1000 * config.shopBot.timeForCancelOffer);
395 });
396 }
397 });
398}
399var itemsToSaleProcced = false;
400var sendProcceed = false;
401var checkProcceed = false;
402setInterval(queueProceed, 1500);