Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update #39

Merged
merged 15 commits into from
Jul 31, 2020
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# tf2autobot

A free and open source fully automated TF2 trading bot advertising on www.backpack.tf using prices from www.prices.tf.
**tf2autobot** is an improved version of the original **tf2-automatic** made by [Nicklason](https://github.com/Nicklason). You can find out more about the original repository [here](https://github.com/Nicklason/tf2-automatic).
**tf2autobot** is an improved and feature rich version of the original **tf2-automatic** made by [Nicklason](https://github.com/Nicklason). You can find out more about the original repository [here](https://github.com/Nicklason/tf2-automatic).

![GitHub package version](https://img.shields.io/github/package-json/v/idinium96/tf2autobot.svg)
[![Build Status](https://img.shields.io/github/workflow/status/idinium96/tf2autobot/CI/development)](https://github.com/idinium96/tf2autobot/actions)
Expand Down Expand Up @@ -75,7 +75,7 @@ The original tf2-automatic repository already have a lot of features, but some f
- automatically restart your bot on queue problem, and automatically relist if backpack.tf does not synchronized with your bot listings on Autokeys (sometimes it's set to automatically buy keys, but at backpack.tf, it's listed to sell.)
- use emojis on almost all messages
- list out every items on each offer review reasons
- New added commands: "!pure", "!time", "!delete", "!check", "!block", "!unblock", "!autokeys", "!craftweapon" and "!uncraftweapon" commands
- New added commands: "!pure", "!time", "!delete", "!check", "!block", "!unblock", "!autokeys", "!inventory", "!adjustrate", "!craftweapon" and "!uncraftweapon" commands
- and more to come!

## Added features
Expand Down Expand Up @@ -143,7 +143,7 @@ Some screenshots:

![autokeys3](https://user-images.githubusercontent.com/47635037/84581310-9c1cd100-ae12-11ea-80fa-085ad8bff73e.png)

You can see codes on how this feature works [here](https://github.com/idinium96/tf2autobot/blob/master/src/classes/MyHandler.ts#L1546-L2140).
You can see codes on how this feature works [here](https://github.com/idinium96/tf2autobot/blob/master/src/classes/MyHandler.ts#L1582-L2176).

### Emojis and more commands added

Expand Down Expand Up @@ -294,7 +294,7 @@ Time will be use in "!time" command and
- `DISCORD_WEBHOOK_TRADE_SUMMARY_SHOW_QUICK_LINKS`: [true|false] - Show trade partner quick links to their Steam profile, backpack.tf and SteamREP pages.
- `DISCORD_WEBHOOK_TRADE_SUMMARY_SHOW_KEY_RATE`: [true|false] - self explained.
- `DISCORD_WEBHOOK_TRADE_SUMMARY_SHOW_PURE_STOCK`: [true|false] - self explained.
- `DISCORD_WEBHOOK_TRADE_SUMMARY_SHOW_INVENTORY`: [true|false] - Show total current items in your bot inventory (I have tried to include `/max slot` but it's not working).
- `DISCORD_WEBHOOK_TRADE_SUMMARY_SHOW_INVENTORY`: [true|false] - Show total current items in your bot inventory.
- `DISCORD_WEBHOOK_TRADE_SUMMARY_ADDITIONAL_DESCRIPTION_NOTE` - Notes.
- `DISCORD_WEBHOOK_TRADE_SUMMARY_MENTION_OWNER` [true|false] - Set it to `true` if you want your bot to mention on every successful trades.
- `DISCORD_WEBHOOK_TRADE_SUMMARY_MENTION_OWNER_ONLY_ITEMS_SKU` [StringArray] - Support multiple items sku, let say you want to be mentioned on every unusual and australium trades, just do `[";5;u", ";11;australium"]`, or if you want to mention on specific item, just fill in the full item sku like `["725;6;uncraftable"]`, then to add more, just separate it with a comma between each sku string.
Expand All @@ -321,7 +321,7 @@ Time will be use in "!time" command and
### Manual Review settings
- `ENABLE_MANUAL_REVIEW`: [true|false] - Set to `true` if you want any INVALID_VALUE/INVALID_ITEMS/OVERSTOCKED/DUPED_ITEMS/DUPE_CHECK_FAILED trades to be reviewed by you.
- `DISABLE_SHOW_REVIEW_OFFER_SUMMARY`: [true|false] - set to `true` if you do not want your bot to show offer summary to trade partner, but it will only notify trade partner that their offer is being hold for a review.
- `DISABLE_REVIEW_OFFER_NOTE`: [true|false] - If set to `false`, it will show note on [each error](https://github.com/idinium96/tf2autobot/blob/master/src/classes/MyHandler.ts#L1340-L1471)
- `DISABLE_REVIEW_OFFER_NOTE`: [true|false] - If set to `false`, it will show note on [each error](https://github.com/idinium96/tf2autobot/blob/master/src/classes/MyHandler.ts#L1358-L1572)
- `DISABLE_SHOW_CURRENT_TIME`: [true|false] - If set to `false`, it will show owner time on offer review notification that trade partner will received.

- `DISABLE_ACCEPT_INVALID_ITEMS_OVERPAY`: [true|false] - Default: `false`. Set to `true` if you do not want your bot to accept a trade with INVALID_ITEMS but with their value more or equal to our value.
Expand Down
48 changes: 45 additions & 3 deletions src/classes/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const ADMIN_COMMANDS: string[] = [
'!withdraw <name=>&<amount=> - Used to withdraw items',
'!add - Add a pricelist entry ➕',
'!update - Update a pricelist entry',
'!adjustrate buy.metal=<buying price>&sell.metal=<selling price> - Manually adjust key rate (reset on restart, self-update when key rate changes)',
'!remove <sku=> OR <item=> - Remove a pricelist entry ➖',
'!get <sku=> OR <item=> - Get raw information about a pricelist entry',
'!pricecheck <sku=> OR <item=> - Requests an item to be priced by PricesTF',
Expand Down Expand Up @@ -126,6 +127,8 @@ export = class Commands {
this.uncraftweaponCommand(steamID);
} else if (command === 'rate') {
this.rateCommand(steamID);
} else if (command === 'adjustrate' && isAdmin) {
this.adjustKeyRateCommand(steamID, message);
} else if (command === 'message') {
this.messageCommand(steamID, message);
} else if (command === 'cart') {
Expand Down Expand Up @@ -422,7 +425,12 @@ export = class Commands {

private inventoryCommand(steamID: SteamID): void {
const currentItems = this.bot.inventoryManager.getInventory().getTotalItems();
this.bot.sendMessage(steamID, `🎒 My crrent items in my inventory: ${currentItems}`);
const backpackSlots = (this.bot.handler as MyHandler).getBackpackSlots();

this.bot.sendMessage(
steamID,
`🎒 My crrent items in my inventory: ${currentItems + (backpackSlots !== 0 ? '/' + backpackSlots : '')}`
);
}

private autoKeysCommand(steamID: SteamID): void {
Expand Down Expand Up @@ -493,11 +501,17 @@ export = class Commands {
? 'Banking' + (autokeys.scrapAdjustmentEnabled ? ' (default price)' : '')
: autokeys.isBuying
? 'Buying for ' +
Currencies.toRefined(keyPrices.buy.toValue() + autokeys.scrapAdjustmentValue).toString() +
Currencies.toRefined(
keyPrices.buy.toValue() +
(autokeys.scrapAdjustmentEnabled ? autokeys.scrapAdjustmentValue : 0)
) +
' ref' +
(autokeys.scrapAdjustmentEnabled ? ' (+' + autokeys.scrapAdjustmentValue + ' scrap)' : '')
: 'Selling for ' +
Currencies.toRefined(keyPrices.sell.toValue() - autokeys.scrapAdjustmentValue).toString() +
Currencies.toRefined(
keyPrices.sell.toValue() -
(autokeys.scrapAdjustmentEnabled ? autokeys.scrapAdjustmentValue : 0)
) +
' ref' +
(autokeys.scrapAdjustmentEnabled ? ' (-' + autokeys.scrapAdjustmentValue + ' scrap)' : '')
: 'Not active'
Expand Down Expand Up @@ -528,6 +542,34 @@ export = class Commands {
);
}

private adjustKeyRateCommand(steamID: SteamID, message: string): void {
const params = CommandParser.parseParams(CommandParser.removeCommand(message));

if (!params || (params.buy === undefined && params.sell === undefined)) {
this.bot.sendMessage(
steamID,
'❌ You must include both buy AND sell price, example - "!adjustkeyrate sell.metal=56.33&buy.metal=56.22"'
);
return;
}

if (+params.buy.metal > +params.sell.metal) {
this.bot.sendMessage(steamID, '❌ Sell price must be higher than buy price.');
return;
}

const buyKeys = +params.buy.keys || 0;
const buyMetal = +params.buy.metal || 0;
const sellKeys = +params.sell.keys || 0;
const sellMetal = +params.sell.metal || 0;
const buy = { keys: buyKeys, metal: buyMetal };
const sell = { keys: sellKeys, metal: sellMetal };

this.bot.pricelist.adjustKeyRate(buy, sell);

this.bot.sendMessage(steamID, '✅ Key rate adjusted to ' + new Currencies(buy) + '/' + new Currencies(sell));
}

private messageCommand(steamID: SteamID, message: string): void {
const isAdmin = this.bot.isAdmin(steamID);
const parts = message.split(' ');
Expand Down
24 changes: 17 additions & 7 deletions src/classes/DiscordWebhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export = class DiscordWebhook {
sendOfferReview(
offer: TradeOffer,
reason: string,
reasons: string,
pureStock: string[],
time: string,
tradeSummary: string,
Expand All @@ -177,12 +178,12 @@ export = class DiscordWebhook {
let noMentionOnInvalidValue = false;
if (process.env.DISCORD_WEBHOOK_REVIEW_OFFER_DISABLE_MENTION_INVALID_VALUE !== 'false') {
if (
reason.includes('🟥INVALID_VALUE') &&
reasons.includes('🟥INVALID_VALUE') &&
!(
reason.includes('🟨INVALID_ITEMS') ||
reason.includes('🟦OVERSTOCKED') ||
reason.includes('🟫DUPED_ITEMS') ||
reason.includes('🟪DUPE_CHECK_FAILED')
reasons.includes('🟨INVALID_ITEMS') ||
reasons.includes('🟦OVERSTOCKED') ||
reasons.includes('🟫DUPED_ITEMS') ||
reasons.includes('🟪DUPE_CHECK_FAILED')
)
) {
noMentionOnInvalidValue = true;
Expand Down Expand Up @@ -259,7 +260,13 @@ export = class DiscordWebhook {
},
title: '',
description:
`⚠️ An offer sent by ${partnerNameNoFormat} is waiting for review.\nReason: ${reason}\n\n__Offer Summary__:\n` +
`⚠️ An offer sent by ${partnerNameNoFormat} is waiting for review.\nReason: ${
reason === '⬜BACKPACKTF_DOWN'
? '⬜BACKPACKTF_DOWN - failed to check banned status'
: reason === '⬜STEAM_DOWN'
? '⬜STEAM_DOWN - failed to check escrow status'
: reasons
}\n\n__Offer Summary__:\n` +
tradeSummary.replace('Asked:', '**Asked:**').replace('Offered:', '**Offered:**') +
(value.diff > 0
? `\n📈 ***Profit from overpay:*** ${value.diffRef} ref` +
Expand Down Expand Up @@ -321,6 +328,7 @@ export = class DiscordWebhook {
tradeSummary: string,
pureStock: string[],
currentItems: number,
backpackSlots: number,
invalidItemsCombine: string[],
keyPrice: { buy: Currencies; sell: Currencies },
value: { diff: number; diffRef: number; diffKey: string },
Expand Down Expand Up @@ -483,7 +491,9 @@ export = class DiscordWebhook {
}`
: '') +
(isShowPureStock ? `\n💰 Pure stock: ${pureStock.join(', ').toString()}` : '') +
(isShowInventory ? `\n🎒 Total items: ${currentItems}` : '') +
(isShowInventory
? `\n🎒 Total items: ${currentItems + (backpackSlots !== 0 ? '/' + backpackSlots : '')}`
: '') +
(AdditionalNotes ? '\n' + AdditionalNotes : ''),
color: botEmbedColor
}
Expand Down
15 changes: 15 additions & 0 deletions src/classes/Listings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export = class Listings {

private autoRelistEnabled = false;

private autoRelistRetry = false;

private autoRelistRetryTimeout;

private autoRelistTimeout;

private templates: { buy: string; sell: string } = {
Expand Down Expand Up @@ -59,6 +63,7 @@ export = class Listings {

this.autoRelistEnabled = true;

clearTimeout(this.autoRelistRetryTimeout);
clearTimeout(this.autoRelistTimeout);

const doneWait = (): void => {
Expand Down Expand Up @@ -97,6 +102,9 @@ export = class Listings {
this.getAccountInfo().asCallback((err, info) => {
if (err) {
log.warn('Failed to get account info from backpack.tf: ', err);
clearTimeout(this.autoRelistTimeout);
clearTimeout(this.autoRelistRetryTimeout);
this.autoRelistRetry = true;
return;
}

Expand All @@ -108,6 +116,13 @@ export = class Listings {
'Enabling autorelist! - Consider paying for backpack.tf premium instead of forcefully bumping listings: https://backpack.tf/donate'
);
this.enableAutoRelist();
} else if (this.autoRelistEnabled && this.autoRelistRetry) {
this.autoRelistRetry = false;
clearTimeout(this.autoRelistRetryTimeout);
log.warn('backpack.tf down, will wait for 30 minutes before relist again...');
this.autoRelistRetryTimeout = setTimeout(() => {
this.enableAutoRelist();
}, 5 * 60 * 1000);
}
});
}
Expand Down
Loading