Jump to content


Photo
Question

How would you calculate the amount of metal to add to trade offers?

node.js node-steam-tradeoffer-manager

  • Please log in to reply
2 replies to this topic

#1 SnaBe

SnaBe

    Member

  • Member
  • PipPip
  • 16 posts
  • LocationDenmark

Posted 18 June 2018 - 01:12 PM

I've been working on TF2 trade bot over the past days and as I got close to a solution for a buy/sell command, I ran into an issue. How can I calculate the amount of metal to add to a trade offer?

 

I had a function that found the refined, reclaimed and scrap metal in a users inventory. The same way I find the keys in the bot's inventory. I had the bot calculate the key price in metal and split it up so it new what to add. However, the bot would only add specific items to do a successful trade. Meaning that if the key price was 32.22, it would add 32 ref and 2 scrap to the trade offer. But if the user dosen't have the exact amount of refined/scrap. Example, lets say they have 31 refined, 3 reclaimed and 2 scrap, (32.22 ref in total) it would cancel (return true). This function is not in the code below since I scrapped it.

 

So I'm looking for a way that the bot can find the users metal from their inventory with getUserInventoryContents and then add the right amount of metal to the trade offer, regardless of a specific item count. As long as the users total metal count meets the key buy price in metal.

 

If anyone can help me or come with suggetions on what I could do, I would be thankful!

 

Below is my buy command with the matching function:

//Command for buying keys
client.on('friendMessage', function(steamID, message) {
  //If the message meets the requirements.
  var buyKeysCmd;
  if(buyKeysCmd = message.match(/^!buy (\d+)/i)) {
    var keysToBuy = buyKeysCmd[1];
    if(keysToBuy > 0) {
      buyKeys(steamID, keysToBuy);
      client.chatMessage(steamID, 'Processing your request.');
    } else {
      client.chatMessage(steamID, 'You can\'t buy 0 keys.');
    }
  }
});
//Function used to buy keys with metal
function buyKeys(steamID, keysToBuy) {
  //No specific amount of keys to buy, cancel
  if(!keysToBuy) {
    return true;
  }
  //How many keys we've in our TF2 inventory
  var ourKeys = [];
  //How much the amount of keys will cost in metal.
  var priceInMetal = config.trading.buyKey * keysToBuy;
  //Display the request.
  console.log('User: ' + steamID + ' has requested to buy ' + keysToBuy + ' key(s) for ' + priceInMetal + ' metal.');
  //Load our TF2 inventory
  manager.getInventoryContents(config.bot.gameID, 2, true, function(err, inventory) {
    if(err) {
      console.log('Error getting our inventory: ' + err);
      client.chatMessage(steamID, 'I encountered an error getting my inventory, please try again later.');
    } else {
      //Go trough our inventory and search for accepted keys
      for(var n = 0; n < inventory.length; n++) {
        if(ourKeys.length < keysToBuy && config.acceptedKeys.indexOf(inventory[n].market_hash_name) >= 0) {
          ourKeys.push(inventory[n]);
        }
      }
      //We don't have any keys
      if(ourKeys.length === 0) {
        client.chatMessage(steamID, 'I don\'t have any keys. Please ask an admin to re-stock or wait for me to sell some keys.');
        return true;
        //The user has requested to buy more keys than our current stock.
      } else if(keysToBuy > ourKeys.length) {
        console.log('I don\'t have ' + keysToBuy + ' key(s).');
        client.chatMessage(steamID, 'I don\'t have ' + keysToBuy + ' key(s).');
        return true;
      }
      //If we've the requested amount of keys
      console.log('Adding ' + ourKeys.length + ' key(s) to the trade offer.');
      //Load their inventory
      manager.getUserInventoryContents(steamID, config.bot.gameID, 2, true, function(err, inventory) {
        if(err) {
          console.log('Error getting their inventory: ' + err);
          client.chatMessage(steamID, "An error occurred while loading your inventory. Please again try later.");
        } else {
          //This is where the users inventory is loaded
          //The bot should look trough the users tf2 inventory
          //Find the users refined metal, reclaimed metal and scrap metal
          //Add it all together and log it
          //If the user has enough metal to purchase the requested amount of keys, continue
          //The bot can now add the metal to the trade offer below.

          var offer = manager.createOffer(steamID);
          //Setup the trade details.
          offer.addMyItems(ourKeys);
          //offer.addTheirItems(their metal for buying x amount of keys);
          offer.setMessage('You\'re buying ' + ourKeys.length + ' key(s) for ' + priceInMetal);
          offer.send(function(err, status) {
            if(err) {
              console.log('Error sending the trade offer: ' + err);
              client.chatMessage(steamID, 'Something went wrong. There was an error sending you the trade offer, please contact support if this continues.');
            } else if(status == 'pending') {
              console.log(`Trade offer #${offer.id} is validated, but awaiting confirmation.`);
              client.chatMessage(steamID, 'The trade offer is validated, but awaiting confirmation.');
              community.acceptConfirmationForObject(config.account.identitySecret, offer.id, function(err) {
                if(err) {
                  console.log('Error confirming trade offer: ' + offer.id);
                  client.chatMessage(steamID, 'Error confirming trade offer, declining.');
                  offer.decline();
                } else {
                  console.log(`Trade offer #${offer.id} confirmed.`);
                  client.chatMessage(steamID, 'The trade offer was sent successfully. You can accept it here: http://steamcommunity.com/tradeoffer/' + offer.id);
                }
              });
            }
          });
        }
      });
    }
  });
}


#2 Dr. McKay

Dr. McKay

    Developer

  • Administrator
  • 1,817 posts

Posted 18 June 2018 - 02:14 PM

You would probably want to do something like this:

  1. Initialize a variable to 0 to count the user's owned metal
  2. Loop over the user's inventory, and add 9 to that variable for every refined, 3 for every reclaimed, and 1 for every scrap
  3. If that variable is < your key price in scrap * number of keys, they can't afford it
  4. If it's >=, then loop over their inventory again, starting with refined and add ref until they don't have any more or the amount you need < 9
  5. Keep going with rec and eventually scrap
  6. If, at the end, you're short a bit, add the smallest currency unit to go above your required price

  • TomYoki likes this

#3 SnaBe

SnaBe

    Member

  • Member
  • PipPip
  • 16 posts
  • LocationDenmark

Posted 18 June 2018 - 06:01 PM

Old issue: I had no trobule working through 1-3 and setup 4. But I'm having troubles with how I should check how much ref to add until they don't have any more or the amount I need < 9. I tried to setup up some refToAdd variable, but it didn't work as I intended , not with the current methods I know. The bot would either add to much or to little. I think that issue came from how I was adding the items to the array. However, if you could give an example on how you would do it for refined. I would be able to figure out the rest. I also realised that a user might only have ref and would need change, but I'll figure that out ones I get the basics. 

 

Update: It can now find the users metal and calculate the prices in scrap. However, it will only create a trade offer if they have the right amount of refined, reclaimed and scrap.

 

New issue: What I'm currently looking to get help with is how I can add a change system. So the user dosen't need the specfic amount of metal. Example, ther users has 32 ref and 3 rec, but the bot will only create a succesful trade if the user has 32 ref, 2 rec and 2 scrap. So here to bot should add the 32 ref and 3 rec and then add 1 scrap from its own inventory.

 

Below is the solution I'm currently using.

//Our custom function to let users buy keys.
function buyKeys(steamID, keysToBuy) {
  if(!keysToBuy) {
    return true;
  }
  //Our items for the trade offer (Must be arrays)
  var ourKeys = [];
  var ourRefined = [];
  var ourReclaimed = [];
  var ourScrap = [];
  //Our metal needed for change
  var ourMetalAdded = 0;
  var ourRefAdded = 0;
  var ourRecAdded = 0;
  var ourScrAdded = 0;
  //Their items for the trade offer
  var theirRefined = [];
  var theirReclaimed = [];
  var theirScrap = [];
  //Their metal to purchase keys
  var theirMetalAdded = 0;
  var theirMetal = 0;
  var theirRefAdded = 0;
  var theirRecAdded = 0;
  var theirScrAdded = 0;
  //Their metal count in their inventory
  var theirInventoryRef = 0;
  var theirInventoryRec = 0;
  var theirInventoryScrap = 0;
  //Bools
  var DoneAddingOurMetal = false;
  var DoneAddingTheirMetal = false;
  var userNeedsChange = false;
  //Price to buy x amount of keys
  var buyPriceInScrap = config.trading.buyKey * keysToBuy;
  //Lets get started
  console.log('User: ' + steamID + ' has requested to buy ' + keysToBuy + ' key(s) for ' + buyPriceInScrap + ' metal.');
  //Load the users inventory
  manager.getUserInventoryContents(steamID, 440, 2, true, function(err, inventory) {
    if(err) {
      console.log('Error getting their inventory: ' + err);
      client.chatMessage(steamID, "An error occurred while loading your inventory. Please again try later.");
    } else {
      //Loop through the users inventory to count metal
      for(var n = 0; n < inventory.length; n++) {
        if(inventory[n].name.indexOf('Refined Metal') >= 0) {
          theirInventoryRef += 1;
          theirMetal += 9;
        } else if(inventory[n].name.indexOf('Reclaimed Metal') >= 0) {
          theirInventoryRec += 1;
          theirMetal += 3;
        } else if(inventory[n].name.indexOf('Scrap Metal') >= 0) {
          theirInventoryScrap += 1;
          theirMetal += 1;
        }
      }
      //Log the users metal.
      console.log('User: ' + steamID + ' has ' + theirInventoryRef + ' refined, ' + theirInventoryRec + ' reclaimed & ' + theirInventoryScrap + ' scrap in their inventory.');
      console.log('User: ' + steamID + ' has ' + theirMetal + ' scrap metal in total.');
      //Check if the user has enough metal.
      if(theirMetal < buyPriceInScrap) {
        console.log('User: ' + steamID + ' dosen\'t have ' + buyPriceInScrap + ' scrap metal to buy ' + keysToBuy + ' key(s).');
        client.chatMessage(steamID, ' You don\'t have ' + buyPriceInScrap + ' scrap metal to buy ' + keysToBuy + ' key(s).');
        return true;
      } else if(theirMetal >= buyPriceInScrap) {
        console.log('User: ' + steamID + ' has enough scrap metal to buy ' + keysToBuy + ' key(s).');
        //Check their inventory again for a more detailed count.
        while(!DoneAddingTheirMetal) {
          if(theirInventoryRef > 0 && theirMetalAdded + 9 <= buyPriceInScrap) {
            theirMetalAdded += 9;
            theirRefAdded++;
            theirInventoryRef--;
          } else if(theirInventoryRec > 0 && theirMetalAdded + 3 <= buyPriceInScrap) {
            theirMetalAdded += 3;
            theirRecAdded++;
            theirInventoryRec--;
          } else if(theirInventoryScrap > 0 && theirMetalAdded + 1 <= buyPriceInScrap) {
            theirMetalAdded += 1;
            theirScrAdded++;
            theirInventoryScrap--;
          } else if(theirInventoryScrap == 0 && theirMetalAdded + 2 == buyPriceInScrap) {
            console.log('User: ' + steamID + ' is missing 2 scrap to complete the trade.');
            client.chatMessage(steamID, 'You\'re missing 2 scrap to complete this trade.');
            DoneAddingTheirMetal = true;
            return true;
          } else if(theirInventoryScrap == 0 && theirMetalAdded + 1 == buyPriceInScrap) {
            console.log('User: ' + steamID + ' is missing 1 scrap to complete the trade.');
            client.chatMessage(steamID, 'You\'re missing 1 scrap to complete this trade.');
            DoneAddingTheirMetal = true;
            return true;
          } else if(theirMetalAdded == buyPriceInScrap) {
            console.log('Done calculatiing user ' + steamID + '\'s metal.');
            client.chatMessage(steamID, 'You\'ve the right amount of refined, reclaimed & scrap for a succesful trade. I\'ll check if I\'ve ' + keysToBuy + ' key(s).');
            DoneAddingTheirMetal = true;
          }
        }
      }
      console.log('User: ' + steamID + ' will give us ' + theirRefAdded + ' refined, ' + theirRecAdded + ' reclaimed & ' + theirScrAdded + ' scrap from their inventory.');
      //Add their refined metal
      for(var n = 0; n < inventory.length; n++) {
        if(theirRefined.length < theirRefAdded && inventory[n].name.indexOf('Refined Metal') >= 0) {
          theirRefined.push(inventory[n]);
        }
      }
      console.log(theirRefined.length + ' refined has been added to the trade offer.');
      //Add their reclaimed
      for(var n = 0; n < inventory.length; n++) {
        if(theirReclaimed.length < theirRecAdded && inventory[n].name.indexOf('Reclaimed Metal') >= 0) {
          theirReclaimed.push(inventory[n]);
        }
      }
      console.log(theirReclaimed.length + ' reclaimed has been added to the trade offer.');
      //Add their scrap
      for(var n = 0; n < inventory.length; n++) {
        if(theirScrap.length < theirScrAdded && inventory[n].name.indexOf('Scrap Metal') >= 0) {
          theirScrap.push(inventory[n]);
        }
      }
      console.log(theirScrap.length + ' scrap has been added to the trade offer.');
    }
  });
}
 

 

You would probably want to do something like this:

  1. Initialize a variable to 0 to count the user's owned metal
  2. Loop over the user's inventory, and add 9 to that variable for every refined, 3 for every reclaimed, and 1 for every scrap
  3. If that variable is < your key price in scrap * number of keys, they can't afford it
  4. If it's >=, then loop over their inventory again, starting with refined and add ref until they don't have any more or the amount you need < 9
  5. Keep going with rec and eventually scrap
  6. If, at the end, you're short a bit, add the smallest currency unit to go above your required price

 


Edited by SnaBe, 19 June 2018 - 02:14 PM.






Also tagged with one or more of these keywords: Question, node.js, node-steam-tradeoffer-manager

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users