Guest User

Untitled

a guest
Apr 7th, 2017
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.18 KB | None | 0 0
  1. const config = require('./config.js');
  2. const fs = require('fs');
  3. const request = require('request');
  4. const cheerio = require('cheerio');
  5. const SteamTotp = require('steam-totp');
  6. const SteamCommunity = require('steamcommunity');
  7. const SteamUser = require('steam-user');
  8. const TradeOfferManager = require('steam-tradeoffer-manager');
  9. var knapsack = require('knapsack-js');
  10. var prompt = require('prompt');
  11. const notifier = require('node-notifier');
  12.  
  13. const community = new SteamCommunity();
  14. const client = new SteamUser();
  15. const manager = new TradeOfferManager({
  16. steam: client,
  17. domain: 'example.com',
  18. language: 'en'
  19. });
  20.  
  21.  
  22. // Variables
  23. var acceptThis = [] //Accept a tradeoffer if the offerID is on the list!
  24. var lastLoginAttempt = Date.now(); //Cooldown for refreshing the bot's session
  25.  
  26. var cookie; //Stores the website cookie
  27. var caseKeys = []; //Stores the user keys as objects properties are name, price and id
  28. var topLimit = 0; //Stores the top limit (max Key amount from the config * keyPrice)
  29.  
  30.  
  31. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  32. ////////// WITHDRAW BOT //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  33. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  34.  
  35. console.log("")
  36. console.log(" =====================================================================================================")
  37. console.log(" > Script starting...")
  38.  
  39. logInBot();
  40.  
  41. // The script is being run when the tradebot is logged in and returns the cookies for skinsJar
  42.  
  43.  
  44.  
  45.  
  46.  
  47. function loadOwnInv() {
  48. caseKeys = [];
  49. topLimit = 0;
  50.  
  51. console.log(" =====================================================================================================")
  52. console.log(" > Requesting player inventory!");
  53. var options = {
  54. headers: {
  55. 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
  56. 'Cookie': cookie
  57. },
  58. }
  59. request.get("https://skinsjar.com/loadInventory?refresh=1&v=1", options, function (error, response, body) {
  60. if (error) {
  61. console.log(' > Error loading our own inventory!');
  62. console.log("Retrying in 30 seconds!");
  63. console.log("");
  64. setTimeout(function(){ loadOwnInv(); }, 30000);
  65. }
  66. if (response.statusCode !== 200) {
  67. console.log(' > Error loading our own inventory (statuscode)!');
  68. console.log("Retrying in 30 seconds!");
  69. console.log("");
  70. setTimeout(function(){ loadOwnInv(); }, 30000);
  71.  
  72. }
  73. var myInv = JSON.parse(body);
  74.  
  75. for (var key in myInv) { //Pushes all keys into the caseKeys array
  76. if (myInv[key].category == "Key" && myInv[key].inTrade == false && isInArray(myInv[key].name, config.excludeKeys) == false && myInv[key].priceBuy > 2) { //2$ is just for security if the keys are values at 0.00$!
  77. for (i = 0; i < myInv[key].items.length; i++) {
  78. caseKeys.push({ "name": myInv[key].name, "price": myInv[key].priceBuy, "id": myInv[key].items[i] })
  79. }
  80. }
  81. }
  82. fs.writeFileSync('keyObject.json', JSON.stringify(caseKeys));
  83.  
  84.  
  85. if(caseKeys.length != 0 && caseKeys.length > config.stopAt){
  86. if(config.useKeys > caseKeys.length){ config.useKeys = caseKeys.length };
  87.  
  88. for (i = 0; i < config.useKeys; i++) { //take amount of keys to use from the config, add up the first x keys in the array to get the max withdraw limit
  89. //console.log(caseKeys[i]);
  90. topLimit += caseKeys[i].price;
  91. }
  92. console.log(" > User inventory loaded: " + caseKeys.length + " key(s)! Limit: " + topLimit.toFixed(2) + "$ | " + config.useKeys + " keys!");
  93. loadBotInv()
  94. } else {
  95.  
  96. if(config.slowMode){
  97. askInput();
  98. } else {
  99. console.log(" > Out of keys! Refreshing the inventory in 60 seconds!");
  100. console.log("")
  101. setTimeout(function(){ loadOwnInv(); }, 60000);
  102. }
  103. }
  104. });
  105. }
  106.  
  107.  
  108.  
  109. function loadBotInv() {
  110. var filteredInv = {}; //Holds the filtered inventory
  111. var options = {
  112. headers: {
  113. 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
  114. 'Cookie': cookie
  115. },
  116. }
  117. request.get("http://skinsjar.com/loadBots", options, function (error, response, body) {
  118. if (error) {
  119. console.log(' > Error loading our own inventory!');
  120. console.log("Retrying in 30 seconds!");
  121. console.log("")
  122. setTimeout(function(){ loadOwnInv(); }, 30000);
  123. }
  124. if (response.statusCode !== 200) {
  125. console.log(' > Error loading our own inventory (statuscode)!');
  126. console.log("Retrying in 30 seconds!");
  127. console.log("")
  128. setTimeout(function(){ loadOwnInv(); }, 30000);
  129. }
  130. var botInv = JSON.parse(body);
  131.  
  132. for (var key in botInv) { //Only take items below the limit, that dont have a phrase from the blacklist (config) in their name. Also only take items from the right category
  133. if (botInv[key].priceSell > config.minPrice && botInv[key].priceSell < config.maxPrice && notBlackListed(botInv[key].name) && config.takeCategory.indexOf(botInv[key].category) >= 0) {
  134.  
  135. for (i = 0; i < botInv[key].items.length; i++) {
  136. if(botInv[key].bot in filteredInv){
  137. var obj = {};
  138. obj[botInv[key].items[i]] = botInv[key].priceSell;
  139. filteredInv[botInv[key].bot].push(obj)
  140. } else {
  141. filteredInv[botInv[key].bot] = []
  142. var obj = {};
  143. obj[botInv[key].items[i]] = botInv[key].priceSell;
  144. filteredInv[botInv[key].bot].push(obj)
  145. }
  146.  
  147. }
  148. }
  149. }
  150.  
  151. prepareOffer(longest(filteredInv))
  152. });
  153. }
  154.  
  155. function longest(obj){
  156.  
  157. var longest = {"bot":0, "count":0}
  158. for(var key in obj){
  159. if(obj[key].length > longest.count){
  160. longest.bot = key
  161. longest.count = obj[key].length
  162. }
  163. }
  164. var longestBot = obj[longest.bot]
  165.  
  166.  
  167. var fullPrice = 0;
  168.  
  169. for (i = 0; i < obj[longest.bot].length; i++) {
  170.  
  171. for(var key in obj[longest.bot][i]) {
  172. fullPrice += obj[longest.bot][i][key]
  173. }
  174.  
  175. }
  176.  
  177. return {"items": obj[longest.bot], "botId": longest.bot, "fullPrice": parseFloat((fullPrice).toFixed(2))};
  178.  
  179. }
  180.  
  181. function prepareOffer(itemObject) {
  182. console.log(" > Bot inventory loaded and filtered! Biggest bot #" + itemObject.botId + " | " + itemObject.items.length + " item(s)!")
  183. console.log(" =====================================================================================================")
  184.  
  185. var calculatedObj = {};
  186.  
  187. for (i = 1; i < config.useKeys; i++) {
  188. var varName = i.toString()
  189. var keysNow = caseKeys.slice(0,i);
  190. var ourPrice = 0;
  191. var theirPrice = 0;
  192. var theirItems = []
  193. var ourItems = []
  194.  
  195. for(j = 0; j < keysNow.length; j++){
  196. ourPrice += keysNow[j].price
  197. ourItems.push(keysNow[j].id)
  198. }
  199.  
  200. var selectedItems = knapsack.resolve(ourPrice, itemObject.items);
  201.  
  202. for(j = 0; j < selectedItems.length; j++){
  203. for(var key in selectedItems[j]) {
  204. theirPrice += selectedItems[j][key]
  205. theirItems.push(key)
  206. }
  207. }
  208.  
  209. calculatedObj[varName] = {
  210. "ourPrice": parseFloat(ourPrice.toFixed(2)),
  211. "theirPrice": parseFloat(theirPrice.toFixed(2)),
  212. "botID": itemObject.botId,
  213. "items": theirItems,
  214. "keys": ourItems,
  215. "overpay": parseFloat((ourPrice - theirPrice).toFixed(2))
  216. }
  217. }
  218.  
  219. sendOffer(getLowestOverpay(calculatedObj))
  220. }
  221.  
  222.  
  223. function getLowestOverpay(calculatedObj){
  224.  
  225. var reversedObj = reverse(calculatedObj);
  226. var bestOffer = {"items": []}
  227.  
  228. for(var key in reversedObj){
  229.  
  230. if(reversedObj[key].overpay < config.overpayTolerance && reversedObj[key].items.length > bestOffer.items.length){
  231. bestOffer = reversedObj[key];
  232. }
  233.  
  234. }
  235.  
  236. if(bestOffer.items.length > 0){
  237. console.log(" > Best calculated offer: ")
  238. console.log(" - " + bestOffer.items.length + " items (" + bestOffer.theirPrice + "$)");
  239. console.log(" - " + bestOffer.keys.length + " keys (" + bestOffer.ourPrice + "$)")
  240. console.log(" - " + bestOffer.overpay + "$" + " overpay")
  241. console.log(" =====================================================================================================")
  242. } else {
  243. console.log(" > Not able to find an offer that matches our settings!")
  244. console.log(" - Try to set 'useKeys' to a higher value")
  245. console.log(" - Use a higher 'overpayTolerance'")
  246. console.log(" - Lower the number of 'sendIfMore'")
  247. console.log(" - Check the item filters")
  248. console.log(" =====================================================================================================")
  249. return false;
  250. }
  251. if(bestOffer.overpay < config.overpayTolerance && bestOffer.items.length > 0){
  252. return bestOffer;
  253. } else {
  254. return false;
  255. }
  256. }
  257.  
  258. function sendOffer(bestOffer) {
  259.  
  260. if(bestOffer && bestOffer.items.length > config.sendIfMore){
  261. console.log(" > Sending an offer!")
  262. var data = {"itemsFromMe": bestOffer.items, "bot": parseInt(bestOffer.botID), "itemsFromThem": bestOffer.keys};
  263. request.post({
  264. headers : {
  265. 'Origin': 'http://skinsjar.com',
  266. 'Accept-Encoding': 'gzip, deflate',
  267. 'Accept-Language': 'de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4',
  268. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
  269. 'Content-Type': 'application/json;charset=UTF-8',
  270. 'Accept': 'application/json, text/plain, */*',
  271. 'Referer': 'http://skinsjar.com/',
  272. 'X-Requested-With': 'XMLHttpRequest',
  273. 'Connection': 'keep-alive',
  274. 'Cookie': cookie
  275. },
  276. gzip: true,
  277. url: 'https://skinsjar.com/api/items/trade',
  278. body: JSON.stringify(data)
  279. }, function (error, response, body) {
  280. if (error) {
  281. console.log(' > Error requesting the offer!');
  282. console.log("Retrying in 30 seconds!");
  283. console.log("")
  284. setTimeout(function(){ loadOwnInv(); }, 30000);
  285. }
  286. if (response.statusCode !== 200) {
  287. console.log(' > Error requesting the offer! (statuscode)!');
  288. console.log("Retrying in 30 seconds!");
  289. console.log("")
  290. setTimeout(function(){ loadOwnInv(); }, 30000);
  291. }
  292. var responseBody = JSON.parse(response.body)
  293.  
  294. if (responseBody.status == "0") { // accessing body from response might be bad to do, not totally sure. :)
  295. console.log(" > Offer was successfully sent! (" + responseBody.tradeofferid + ")")
  296. console.log(" > Waiting " + config.waitTime + " second(s)!")
  297. console.log("")
  298. if(config.offerNotifications){notifier.notify({'title': 'Requested an offer!', 'message': "> " + bestOffer.items.length + " item(s) for " + bestOffer.keys.length + " key(s)!"})};
  299. acceptThis.push((responseBody.tradeofferid).toString());
  300. if(config.slowMode){
  301. askInput();
  302. } else {
  303. setTimeout(function(){ console.log(""); loadOwnInv(); }, config.waitTime * 1000)
  304. }
  305. } else {
  306. console.log(" > Problem: " + responseBody.error + " (Bot won't accept this trade!)");
  307. console.log(" > Waiting " + config.waitTime + " second(s)!")
  308. setTimeout(function(){ console.log(""); loadOwnInv(); }, config.waitTime * 1000)
  309. }
  310.  
  311. });
  312. } else {
  313. console.log(" > No good offers found! (Overpay too high, min. amount of items etc...)")
  314. console.log(" > Waiting " + config.waitTime + " second(s)!")
  315. console.log("")
  316. setTimeout(function(){ console.log(""); loadOwnInv(); }, config.waitTime * 1000)
  317. }
  318. }
  319.  
  320.  
  321.  
  322. function notBlackListed(word) { //Pass the itemName to this function. Returns TRUE if the name doesn't contain a blackListed word ("StatTrak", "Souvenir", "Battle-Scared" etc...)
  323. var contains = false;
  324. for (i = 0; i < (config.avoid).length; i++) {
  325. if (word.indexOf(config.avoid[i]) >= 0) {
  326. contains = true;
  327. }
  328. }
  329. return !contains;
  330. }
  331.  
  332. function askInput(){
  333.  
  334. console.log("")
  335. setTimeout(function(){ console.log("")}, 100);
  336. prompt.message = '>>> Enter "+" and hit return to check for items: ';
  337.  
  338. prompt.get(['userInput'], function (err, result) {
  339.  
  340. if(result.userInput == "+"){
  341. loadOwnInv();
  342. } else {
  343. askInput();
  344. }
  345. });
  346. }
  347.  
  348.  
  349.  
  350.  
  351. function reverse(items, func){
  352. var reversed = Array();
  353. for( var key in items ){
  354. reversed.unshift(items[key]);
  355. }
  356. if( func ){
  357. for( var key in reversed ){
  358. func(key, reversed[key]);
  359. }
  360. }
  361. return reversed;
  362. }
  363.  
  364. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  365. ////////// TRADEBOT //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  366. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  367.  
  368.  
  369. /*
  370. Polling Steam and Logging On
  371. */
  372.  
  373. function logInBot() {
  374. if(config.useSecrets){
  375. client.logOn({
  376. accountName: config.username,
  377. password: config.password,
  378. twoFactorCode: SteamTotp.generateAuthCode(config.sharedsecret)
  379. });
  380. } else {
  381. console.log(" > 'useSecrets' is set to false - Please enter an auth-code!")
  382. client.logOn({
  383. accountName: config.username,
  384. password: config.password,
  385. twoFactorCode: ""
  386. });
  387. }
  388. }
  389.  
  390.  
  391. function isInArray(value, array) {
  392. return array.indexOf(value) > -1;
  393. }
  394.  
  395. function acceptOffer(offer) {
  396. offer.accept((err) => {
  397. if(config.useSecrets){
  398. community.acceptConfirmationForObject(config.identitysecret, offer.id, function(){
  399. });
  400. } else {
  401.  
  402. console.log(" > Please confirm this offer!");
  403. }
  404. if (err) console.log(` > Unable to accept offer: ${err.message}`);
  405. });
  406. }
  407.  
  408. function declineOffer(offer) {
  409. console.log(" > Declining offer!")
  410. offer.decline((err) => {
  411. if (err) return console.log(` > Unable to decline offer: ${err.message}`);
  412. });
  413. }
  414.  
  415.  
  416. manager.on('newOffer', function (offer) {
  417. const partnerid = offer.partner.getSteamID64();
  418. offer.getUserDetails((err, me, them) => {
  419. if (err) return console.log(err);
  420. if (them.escrowDays > 0) {
  421. console.log(' > Trade is in escrow. Declining.');
  422. declineOffer(offer);
  423. }
  424. });
  425. if (!offer.itemsToGive.length && config.acceptDonations) {
  426. acceptOffer(offer);
  427. console.log(" ============ Received a new offer ===================================================================");
  428. console.log(" > ID: " + offer.id + " | Give: " + offer.itemsToGive.length + " | Receive: " + offer.itemsToReceive.length)
  429. console.log(" > Donation! Accepting!");
  430. console.log(" =====================================================================================================");
  431. console.log("");
  432. } else if (acceptThis.indexOf(offer.id) >= 0) {
  433. console.log(" ============ Received a new offer ===================================================================");
  434. console.log(" > ID: " + offer.id + " | Give: " + offer.itemsToGive.length + " | Receive: " + offer.itemsToReceive.length)
  435. if(config.autoAccept){
  436. console.log(" > Offer was sent from this bot! Accepting!");
  437. console.log(" =====================================================================================================");
  438. console.log("");
  439. acceptOffer(offer);
  440. } else {
  441. console.log(" > Offer was sent from this bot, but autoAccept is set to 'false' in the config!");
  442. console.log(" =====================================================================================================");
  443. console.log("");
  444. }
  445. }
  446. });
  447.  
  448.  
  449.  
  450. //Refresh polldata.json
  451. manager.on('pollData', function (pollData) {
  452. fs.writeFile('polldata.json', JSON.stringify(pollData));
  453. });
  454.  
  455. if (fs.existsSync('polldata.json')) {
  456. try {
  457. console.log(" > Loaded polldata!")
  458. manager.pollData = JSON.parse(fs.readFileSync('polldata.json'));
  459. } catch (Exception) {
  460. console.log(" > polldata.json is corrupted! Restoring!");
  461. manager.pollData = {};
  462. }
  463. }
  464.  
  465. client.on('loggedOn', function (details) {
  466. console.log(` > Logged into Steam as ${client.steamID}!`);
  467. client.setPersona(SteamUser.Steam.EPersonaState.Online);
  468. });
  469.  
  470. client.on('webSession', function (sessionID, cookies) {
  471. manager.setCookies(cookies, function (err) {
  472. if (err) return console.log(err);
  473. console.log(" > Steamcookies are set!");
  474. logIntoWebsite()
  475. });
  476. community.setCookies(cookies);
  477. });
  478.  
  479. client.on("sessionExpired", function (err) {
  480. if (Date.now() - lastLoginAttempt > 30000) {
  481. lastLoginAttempt = Date.now();
  482. console.log(" > Session Expired, relogging.");
  483. client.webLogOn();
  484. } else {
  485. console.log(" > Session Expired, waiting a while before attempting to relogin.");
  486. }
  487. });
  488.  
  489. function logIntoWebsite() {
  490. console.log(" > Logging into website!")
  491. community.httpRequestGet('http://skinsjar.com/login', (err, response, body) => {
  492. if (err) {
  493. console.log(" > Error authenticating with website: " + err);
  494. process.exit(); // add exit code error
  495. }
  496. var $ = cheerio.load(body);
  497. var data = $('#openidForm').serializeArray();
  498. var formData = {};
  499. data.forEach((obj) => {
  500. formData[obj.name] = obj.value;
  501. });
  502. var options = {
  503. url: 'https://steamcommunity.com/openid/login',
  504. method: 'POST',
  505. formData: formData,
  506. followAllRedirects: true
  507. };
  508.  
  509. community.httpRequest(options, (error, response, body) => {
  510. if (error) {
  511. console.log(" > Error loading websiteCookies: " + err);
  512. process.exit();
  513. }
  514. cookie = response.request.headers.cookie;
  515. console.log(" > Received website cookies!");
  516. if(config.slowMode){
  517. askInput();
  518. } else {
  519. loadOwnInv();
  520. }
  521.  
  522. });
  523. });
  524. }
Add Comment
Please, Sign In to add comment