Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var config = require('./config');
- var SteamTotp = require("steam-totp");
- var TradeOfferManager = require("steam-tradeoffer-manager");
- var SteamCommunity = require("steamcommunity");
- var SteamUser = require("steam-user");
- var fs = require("fs");
- var request = require("request");
- var client = new SteamUser();
- var community = new SteamCommunity();
- var manager = new TradeOfferManager({
- "steam": client,
- "language": "en",
- "pollInterval": 2000 // Poll offers every 2 seconds (2000 ms).
- });
- client.setOption("promptSteamGuardCode", false);
- console.log("Selling CS:GO keys for " + rateAsText(false) + " or " + convertRateToKeysAndMetal(getRate(false)) + ", buying CS:GO keys for " + rateAsText(true) + " or " + convertRateToKeysAndMetal(getRate(true)));
- login();
- function login() {
- SteamTotp.getTimeOffset(function(err, offset) {
- if (err) {
- console.log("An error occurred getting the time offset, retrying in 10 seconds...");
- return setTimeout(login, 1000 * 10); // Wait 1 minut
- }
- var logOnDetails = getLoginDetails(offset);
- client.logOn(logOnDetails);
- });
- }
- client.on("loggedOn", loggedOn);
- client.on('webSession', function(sessionID, cookies) {
- manager.setCookies(cookies, function(err) {
- if (err) {
- console.log("An error occurred setting the cookies, retrying...");
- return client.webLogOn();
- }
- });
- community.setCookies(cookies);
- community.profileSettings({
- profile: 3,
- comments: 3,
- inventory: 3
- }, function(err, response) {
- if (err) {
- console.log("An error occurred while trying to update the privacy settings...");
- }
- });
- /*
- community.editProfile({
- name: config.name,
- }, function(err) {
- if (err) return console.log("An error occurred while trying to edit the profile...");
- });
- */
- });
- community.on("sessionExpired", function(err) {
- console.log("The session expired, logging in again...");
- client.webLogOn();
- });
- client.on('friendRelationship', function(steamID, relationship) {
- // If the user send us a friend request, we will continue.
- if (relationship == SteamUser.Steam.EFriendRelationship.RequestRecipient) {
- addFriend(steamID);
- }
- });
- client.on("friendsList", function() {
- for (var steamID in client.myFriends) {
- var relationship = client.myFriends[steamID];
- if (relationship == SteamUser.Steam.EFriendRelationship.RequestRecipient) {
- addFriend(steamID);
- }
- }
- });
- function addFriend(steamID) {
- client.addFriend(steamID, function(err, name) {
- if (err) return console.log("An error occurred while trying to add a friend...");
- console.log("I am now friends with " + name);
- });
- }
- community.on('confKeyNeeded', function(tag, callback) {
- var time = Math.floor(Date.now() / 1000);
- callback(null, time, SteamTotp.getConfirmationKey(config.identity_secret, time, tag));
- });
- manager.on("newOffer", handleOffer);
- manager.on("receivedOfferChanged", offerStateChanged);
- function loggedOn() {
- client.setPersona(SteamUser.EPersonaState.Online);
- console.log("Logged onto Steam");
- client.gamesPlayed(["CS:GO & TF2 KEYS EXCHANGE ♦SEND A TRADE OFFER ♦24/7 ACCEPT"]);
- if (config.notify && config.admin) client.chatMessage(config.admin, "Selling CS:GO keys for " + rateAsText(false) + " or " + convertRateToKeysAndMetal(getRate(false)) + ", buying CS:GO keys for " + rateAsText(true) + " or " + convertRateToKeysAndMetal(getRate(true)));
- }
- function handleOffer(offer) {
- console.log("Incoming offer from " + offer.partner.getSteamID64());
- if (offer.isGlitched()) {
- console.log("The offer appears to be glitched, declining...");
- return declineOffer(offer);
- }
- if (offer.partner.getSteamID64() == config.admin) {
- console.log("The offer is from an admin (" + config.admin + "), accepting...");
- return acceptOffer(offer);
- }
- if (offer.itemsToGive.length == 0) {
- console.log("The offer is a donation (we are not offering any items), accepting...");
- return acceptOffer(offer);
- }
- if (offer.itemsToReceive.length == 0) {
- console.log("The user is only taking items (they are not offering any items), declining...");
- return declineOffer(offer);
- }
- isEscrow(offer, function(err, escrow) {
- if (err) {
- console.log("An error occurred while checking for escrow, skipping the offer...");
- process.exit(0);
- return;
- }
- if (escrow) {
- console.log("Offer will be in escrow, declining...");
- return declineOffer(offer);
- }
- isScammer(offer.partner.getSteamID64(), function(err, isScammer) {
- if (err) console.log("An error occurred while checking if the user is a scammer: " + err);
- // If an error occurred, isScammer will be undefinded and this will return false. Keep it simple ;)
- if (isScammer) {
- console.log("The partner is marked as a scammer on SteamRep, declining...");
- return declineOffer(offer);
- }
- var accept = verifyOffer(offer.itemsToGive, offer.itemsToReceive);
- if (accept) {
- acceptOffer(offer);
- } else {
- declineOffer(offer)
- }
- });
- });
- }
- function verifyOffer(ourItems, theirItems) {
- var ourAppID = null;
- // This is offered together, or it is not a valid offer.
- var csgoKeys = 0;
- var change = 0;
- // Same as above, just with these values.
- var tf2Keys = 0;
- var metal = 0;
- // The bot buy csgo keys at a rate of 8 csgo for 9 tf2 + 4.22 refined.
- // The bot does not have 4.22 refined, but it has 5 refined.
- // We offer the bot 8 csgo keys and 0.77 refined for 9 tf2 keys and 5 refined
- // That's the same as 8 csgo keys for 9 tf2 keys and 4.22 refined
- // Also accept metal as tf2 / csgo keys.
- /*
- Nicklason: I offer the bot 10 csgo keys and metal for x tf2 keys
- Nicklason: Use the metal as change
- Nicklason: And only in that situation
- dont use metal as tf2 keys as the bot will get full quickly.
- */
- // Loop our items.
- for (var i = 0; i < ourItems.length; i++) {
- var item = ourItems[i];
- // If we are offering an item which is from csgo (item.appid is 730), and that is appid as the other items we hace checked, or the appid is null.
- if (item.appid == "730" && (ourAppID == item.appid || ourAppID == null)) {
- // We will then check if the item is a "valid" key, which i just a way to say that we accept this item as a csgo key.
- if (isValidKey(item.market_name)) {
- if (ourAppID == null) ourAppID = item.appid; // Set our appid if it has not been set yet.
- csgoKeys++;
- } else {
- return false; // Return false as the offer is not valid and it should be declined.
- }
- } else if (item.appid == "440" && (ourAppID == item.appid || ourAppID == null)) {
- if (item.market_name === "Mann Co. Supply Crate Key") {
- if (ourAppID == null) ourAppID = item.appid; // Set our appid if it has not been set yet.
- tf2Keys++;
- } else {
- // If the item is not a key, we will check if it is metal.
- var _isMetal = isMetal(item.market_name);
- // isMetal will return false if it is not metal, and it will return the amount in scrap if it is.
- if (_isMetal) {
- metal += _isMetal;
- } else {
- return false;
- }
- }
- // If the appid of the currently looped item is 440, and our appid is 730, we will take this as change (but only if it is metal).
- } else if (item.appid == "440" && (ourAppID == "730")) {
- var _isMetal = isMetal(item.market_name);
- if (_isMetal) {
- change += _isMetal;
- } else {
- return false;
- }
- } else {
- return false; // Return false if it is not the appid of tf2 or csgo, and if we offer items from different appids.
- }
- }
- for (var i = 0; i < theirItems.length; i++) {
- var item = theirItems[i];
- // Same as before, just the other way around. I am not checking if ourAppID is null because it should always have a value here.
- // The bot will always decline offers where the user is not offering anything, and accept if the bot is not offering anything,
- // it will therefore always contain items on both sides.
- if (item.appid == "730" && (ourAppID != item.appid)) {
- if (isValidKey(item.market_name)) {
- csgoKeys++;
- } else {
- return false;
- }
- } else if (item.appid == "440" && (ourAppID != item.appid)) {
- if (item.market_name === "Mann Co. Supply Crate Key") {
- tf2Keys++;
- } else {
- var _isMetal = isMetal(item.market_name);
- if (_isMetal) {
- metal += _isMetal;
- } else {
- return false;
- }
- }
- // If they offer an item from tf2, but we are not offering items from csgo (we are offering tf2), we will take this as change.
- } else if (item.appid == "440" && ourAppID != "730") {
- var _isMetal = isMetal(item.market_name);
- if (_isMetal) {
- change += _isMetal;
- } else {
- return false;
- }
- }
- }
- if (change > 8) {
- console.log("offering more change than allowed");
- return false; // Since one refined is 9 scrap, we will decline offers with more change than 8 scrap worth of metal.
- }
- metal = metal - change;
- if (metal < 0) {
- console.log("Metal is less than 0, declining...");
- return false;
- }
- if (metal >= refinedToScrap(config.rate.keyPrice)) {
- console.log("The user offers more or the same amount as the value of a key, declining...");
- return false; // We will not accept metal as keys.
- }
- var actualRate = getRate(ourAppID == "440");
- var offeredRate = calculateRate(csgoKeys, tf2Keys, metal);
- console.log(actualRate, offeredRate);
- if (offeredRate <= actualRate && ourAppID == "440") {
- console.log("We are offering tf2 items, user is offering csgo. Price is right, accepting.");
- return true;
- } else if (offeredRate >= actualRate && ourAppID == "730") {
- console.log("We are offering csgo items, user is offering tf2. Price is right, accepting.");
- return true;
- } else {
- console.log("The offer is not valid, declining...");
- return false;
- }
- /*
- if (offeredRate <= actualRate) {
- console.log("The user is offering me a rate of " + offeredRate + ", the actual rate is " + actualRate + ", accepting...");
- return true;
- } else {
- console.log("The offer is not valid, declining...");
- return false;
- }
- */
- }
- function isEscrow(offer, callback) {
- offer.getUserDetails(function(err, me, them) {
- if (err) {
- client.webLogOn();
- return callback(err);
- }
- if (them.escrowDays > 0) return callback(null, true);
- if (me.escrowDays > 0) return callback(null, true);
- return callback(null, false);
- });
- }
- function scrapToRefined(scrap) {
- var refined = parseFloat((scrap / 9).toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]);
- return refined;
- }
- function refinedToScrap(refined) {
- var scrap = parseInt(Math.round(refined * 9));
- return scrap;
- }
- function keysAndMetalAsText(keys, refined) {
- var text = "0 keys & 0 refined";
- if (keys != 0) {
- text = keys + " " + (keys > 1 ? "keys" : "key");
- }
- if (refined != 0) {
- if (text == "0 keys & 0 refined") {
- text = refined + ' refined';
- } else {
- text += ' & ' + refined + ' refined';
- }
- }
- return text.toUpperCase();
- }
- function rateAsText(weBuyCSGO) {
- var intent = weBuyCSGO ? "buy" : "sell";
- var tf2Price = config.rate[intent].metal == 0 ? config.rate[intent].tf2 : config.rate[intent].tf2 + "+" + config.rate[intent].metal + " refined";
- return config.rate[intent].csgo + ":" + tf2Price;
- }
- /*
- function summary() {
- var sellRate = getRate(false);
- var buyRate = getRate(true);
- return "[h1][b]★Buy [u]My CS:GO Keys[/u] ➨ " + rateAsText(false) + " Or " + convertRateToKeysAndMetal(sellRate) + "\n★Sell [u]Your CS:GO Keys[/u] ➨ " + rateAsText(true) + " Or " + convertRateToKeysAndMetal(buyRate) + "[/b][/h1]\n[b][url=" + config.tradeoffer_url + "][h1][b]:crate:TRADE OFFER LINK[/b][/h1][/url][/b][b][url=https://steamcommunity.com/id/junglibunny/][h1][b]:spycon:Owner[/b][/h1][/url][/b] [b][url=http://steamcommunity.com/groups/Bunnykeyswap][h1][b]:csgoglobe:Steam Group[/b][/h1][/url][/b]";
- }
- */
- function calculateRate(csgoKeys, tf2Keys, metal) {
- var metalInKeys = metal / refinedToScrap(config.rate.keyPrice);
- var rate = (tf2Keys + metalInKeys) / csgoKeys;
- return rate.toString().match(/^-?\d+(?:\.\d{0,3})?/)[0];
- }
- function convertRateToKeysAndMetal(rate) {
- var keys = Math.floor(rate);
- var metal = scrapToRefined(refinedToScrap((rate - keys) * config.rate.keyPrice));
- return keysAndMetalAsText(keys, metal);
- }
- function getRate(weBuyCSGO) {
- if (weBuyCSGO) {
- return ((config.rate.buy.tf2 + (refinedToScrap(config.rate.buy.metal) / refinedToScrap(config.rate.keyPrice))) / config.rate.buy.csgo).toString().match(/^-?\d+(?:\.\d{0,3})?/)[0];
- } else {
- return ((config.rate.sell.tf2 + (refinedToScrap(config.rate.sell.metal) / refinedToScrap(config.rate.keyPrice))) / config.rate.sell.csgo).toString().match(/^-?\d+(?:\.\d{0,3})?/)[0];
- }
- }
- function isValidKey(name) {
- // If the name is in the acceptedKeys array, this will return true. If not, false ofc.
- return config.acceptedKeys.some(function(key) {
- if (key == name) return true;
- });
- }
- function isMetal(name) {
- // Return the value of the metal in scrap if it is metal. It will return false if not.
- if (name == "Refined Metal") return 9;
- if (name == "Reclaimed Metal") return 3;
- if (name == "Scrap Metal") return 1;
- return false;
- }
- function declineOffer(offer) {
- offer.decline(function (err) {
- if (err) {
- client.webLogOn();
- console.log("An error occurred when trying to decline offer #" + offer.id);
- }
- });
- }
- function acceptOffer(offer) {
- offer.accept(function(err, status) {
- if (err) {
- //client.webLogOn();
- console.log("Unable to accept offer #" + offer.id + ": " + err);
- process.exit(0);
- return;
- }
- // If the offer status is pending, that means that we have to accept a mobile confirmation for the offer.
- if (status == "pending") {
- community.acceptConfirmationForObject(config.identity_secret, offer.id, function(err) {
- if (err) return console.log("An error occurred while trying to accept the mobile confirmation for offer #" + offer.id);
- });
- }
- });
- }
- function offerStateChanged(offer, oldState) {
- console.log("Offer #" + offer.id + " changed: " + TradeOfferManager.ETradeOfferState[oldState] + " (" + oldState + ") -> " + TradeOfferManager.ETradeOfferState[offer.state] + " (" + offer.state + ")");
- if (config.notify && config.admin) {
- if (offer.state == TradeOfferManager.ETradeOfferState.Accepted) {
- inviteToGroup(offer.partner);
- return client.chatMessage(config.admin, "I've accepted a trade from " + offer.partner.getSteamID64());
- }
- if (offer.state == TradeOfferManager.ETradeOfferState.Declined) {
- return client.chatMessage(config.admin, "I've declined a trade from " + offer.partner.getSteamID64());
- }
- }
- }
- function inviteToGroup(steamID) {
- try {
- client.inviteToGroup(steamID, config.groupId);
- } catch (err) {
- console.log("An error occurred while trying to invite a user to our group: " + err.message);
- }
- }
- /*
- function inviteToGroup(steamID) {
- console.log(steamID);
- community.getSteamUser(steamID, function(err, cmt) {
- if (err) {
- console.log(err);
- } else {
- cmt.inviteToGroup(config.groupId);
- }
- });
- }
- */
- function getSteamRepSummary(steamid64, callback) {
- request({
- "method": "GET",
- "url": "http://steamrep.com/api/beta4/reputation/" + steamid64 + "?json=1"
- }, function(err, response, body) {
- if (err) return callback(err);
- if (!response.statusCode.toString().startsWith("2")) return callback("Statuscode: " + response.statusCode);
- if (!(response.headers['content-type'].indexOf("application/json") > -1)) return callback("Not a JSON response");
- var data = JSON.parse(body);
- return callback(null, data);
- });
- }
- function isScammer(steamid64, callback) {
- getSteamRepSummary(steamid64, function(err, steamrep) {
- if (err) return callback(err);
- return callback(null, steamrep.steamrep.reputation.summary.toLowerCase().indexOf("scammer") > -1); // Returns true if their summary contains scammer.
- });
- }
- function getLoginDetails(offset) {
- var logOnDetails = {
- "accountName": config.username,
- "password": config.password,
- "twoFactorCode": SteamTotp.getAuthCode(config.shared_secret, offset)
- };
- return logOnDetails;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement