Jump to content
McKay Development
SnaBe

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

Recommended Posts

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);
                }
              });
            }
          });
        }
      });
    }
  });
}

Share this post


Link to post
Share on other sites

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
  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
  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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...