diff --git a/src/classes/MyHandler/offer/accepted/updateListings.ts b/src/classes/MyHandler/offer/accepted/updateListings.ts index e24e74b91..e2b88db0c 100644 --- a/src/classes/MyHandler/offer/accepted/updateListings.ts +++ b/src/classes/MyHandler/offer/accepted/updateListings.ts @@ -30,20 +30,25 @@ export default function updateListings( const inventory = bot.inventoryManager.getInventory; const hv = highValue.items; const normalizePainted = opt.normalize.painted; + const dwEnabled = opt.discordWebhook.sendAlert.enable && opt.discordWebhook.sendAlert.url !== ''; for (const sku in diff) { if (!Object.prototype.hasOwnProperty.call(diff, sku)) { continue; } - const name = bot.schema.getName(SKU.fromString(sku), false); + const item = SKU.fromString(sku); + const name = bot.schema.getName(item, false); const isNotPureOrWeapons = !(weapons.includes(sku) || ['5000;6', '5001;6', '5002;6'].includes(sku)); const inPrice = bot.pricelist.getPrice(sku, false); const existInPricelist = inPrice !== null; const isDisabledHV = highValue.isDisableSKU.includes(sku); const isAdmin = bot.isAdmin(offer.partner); - const isNotSkinsOrWarPaint = SKU.fromString(sku).wear === null; + const isNotSkinsOrWarPaint = item.wear === null; + // if item is unusual and autoAddInvalidUnusual is set to true then we allow addInvalidUnusual. + // If the item is not an unusual sku, we "allow" still (no-op) + const addInvalidUnusual = item.quality === 5 ? opt.pricelist.autoAddInvalidUnusual : true; const isAutoaddPainted = normalizePainted.our === false && // must meet this setting @@ -62,17 +67,26 @@ export default function updateListings( isNotPureOrWeapons && sku !== '5021;6' && // not Mann Co. Supply Crate Key isNotSkinsOrWarPaint && // exclude War Paint (could be skins) + addInvalidUnusual && !isDisabledHV && !isAdmin && opt.pricelist.autoAddInvalidItems.enable; - const receivedNotInPricelist = + const receivedHighValueNotInPricelist = !existInPricelist && isNotPureOrWeapons && isNotSkinsOrWarPaint && // exclude War Paint (could be skins) isDisabledHV && // This is the only difference !isAdmin; + const receivedUnusualNotInPricelist = + !existInPricelist && + isNotPureOrWeapons && + isNotSkinsOrWarPaint && + item.quality === 5 && + opt.pricelist.autoAddInvalidUnusual === false && + !isAdmin; + const isAutoDisableHighValueItems = existInPricelist && isDisabledHV && @@ -168,7 +182,7 @@ export default function updateListings( log.debug(msg); if (opt.sendAlert.enable && opt.sendAlert.autoAddPaintedItems) { - if (opt.discordWebhook.sendAlert.enable && opt.discordWebhook.sendAlert.url !== '') { + if (dwEnabled) { sendAlert('autoAddPaintedItems', bot, msg.replace(/"/g, '`')); } else { bot.messageAdmins(msg, []); @@ -183,7 +197,7 @@ export default function updateListings( log.debug(msg); if (opt.sendAlert.enable && opt.sendAlert.autoAddPaintedItems) { - if (opt.discordWebhook.sendAlert.enable && opt.discordWebhook.sendAlert.url !== '') { + if (dwEnabled) { sendAlert('autoAddPaintedItemsFailed', bot, msg.replace(/"/g, '`')); } else { bot.messageAdmins(msg, []); @@ -211,7 +225,7 @@ export default function updateListings( log.warn(`❌ Failed to add ${name} (${sku}) sell automatically: ${(err as Error).message}`) ); // - } else if (receivedNotInPricelist) { + } else if (receivedHighValueNotInPricelist) { // if the item sku is not in pricelist, not craftweapons or pure or skins AND it's a highValue items, and not // from ADMINS, then notify admin. let msg = @@ -226,12 +240,26 @@ export default function updateListings( } if (opt.sendAlert.enable && opt.sendAlert.highValue.receivedNotInPricelist) { - if (opt.discordWebhook.sendAlert.enable && opt.discordWebhook.sendAlert.url !== '') { + if (dwEnabled) { sendAlert('highValuedInvalidItems', bot, msg.replace(/"/g, '`')); } else { bot.messageAdmins(msg, []); } } + } else if (receivedUnusualNotInPricelist) { + // if the item sku is not in pricelist, not craftweapons or pure or skins AND it's a Unusual (bought with Generic Unusual), and not + // from ADMINS, and opt.pricelist.autoAddInvalidUnusual is false, then notify admin. + const msg = + 'I have received an Unusual bought with Generic Unusual feature\n\nItem info: ' + + (dwEnabled ? `[${name}](https://www.prices.tf/items/${sku}) (${sku})` : `${name} (${sku})`); + + if (opt.sendAlert.enable && opt.sendAlert.receivedUnusualNotInPricelist) { + if (dwEnabled) { + sendAlert('unusualInvalidItems', bot, msg.replace(/"/g, '`')); + } else { + bot.messageAdmins(msg, []); + } + } } else if (isAutoDisableHighValueItems) { // If item received is high value, temporarily disable that item so it will not be sellable. const entry: EntryData = { @@ -275,7 +303,7 @@ export default function updateListings( } if (opt.sendAlert.enable && opt.sendAlert.highValue.gotDisabled) { - if (opt.discordWebhook.sendAlert.enable && opt.discordWebhook.sendAlert.url !== '') { + if (dwEnabled) { sendAlert('highValuedDisabled', bot, msg.replace(/"/g, '`')); } else { bot.messageAdmins(msg, []); @@ -297,7 +325,7 @@ export default function updateListings( log.warn(msg); if (opt.sendAlert.enable && opt.sendAlert.autoRemoveIntentSellFailed) { - if (opt.discordWebhook.sendAlert.enable && opt.discordWebhook.sendAlert.url !== '') { + if (dwEnabled) { sendAlert('autoRemoveIntentSellFailed', bot, msg); } else { bot.messageAdmins(msg, []); @@ -336,7 +364,7 @@ export default function updateListings( log.debug(msg); if (opt.sendAlert.enable && opt.sendAlert.partialPrice.onSuccessUpdatePartialPriced) { - if (opt.discordWebhook.sendAlert.enable && opt.discordWebhook.sendAlert.url !== '') { + if (dwEnabled) { sendAlert('autoUpdatePartialPriceSuccess', bot, msg); } else { bot.messageAdmins('✅ Automatically update partially priced item - ' + msg, []); @@ -348,7 +376,7 @@ export default function updateListings( log.warn(msg); if (opt.sendAlert.enable && opt.sendAlert.partialPrice.onFailedUpdatePartialPriced) { - if (opt.discordWebhook.sendAlert.enable && opt.discordWebhook.sendAlert.url !== '') { + if (dwEnabled) { sendAlert('autoUpdatePartialPriceFailed', bot, msg); } else { bot.messageAdmins(msg, []); diff --git a/src/classes/Options.ts b/src/classes/Options.ts index 7eee2273a..1921ac199 100644 --- a/src/classes/Options.ts +++ b/src/classes/Options.ts @@ -66,7 +66,8 @@ export const DEFAULTS = { onUpdate: true, onSuccessUpdatePartialPriced: true, onFailedUpdatePartialPriced: true - } + }, + receivedUnusualNotInPricelist: true }, pricelist: { @@ -83,6 +84,9 @@ export const DEFAULTS = { autoAddInvalidItems: { enable: true }, + autoAddInvalidUnusual: { + enable: false + }, autoAddPaintedItems: { enable: true }, @@ -1024,6 +1028,7 @@ interface SendAlert extends OnlyEnable { failedAccept?: boolean; unableToProcessOffer?: boolean; partialPrice?: PartialPrice; + receivedUnusualNotInPricelist?: boolean; } interface PartialPrice { @@ -1052,6 +1057,7 @@ interface Pricelist { filterCantAfford?: OnlyEnable; autoRemoveIntentSell?: OnlyEnable; autoAddInvalidItems?: OnlyEnable; + autoAddInvalidUnusual?: OnlyEnable; autoAddPaintedItems?: OnlyEnable; priceAge?: PriceAge; } diff --git a/src/lib/DiscordWebhook/sendAlert.ts b/src/lib/DiscordWebhook/sendAlert.ts index 88cb85296..5467d8bf1 100644 --- a/src/lib/DiscordWebhook/sendAlert.ts +++ b/src/lib/DiscordWebhook/sendAlert.ts @@ -36,7 +36,8 @@ type AlertType = | 'error-accept' | 'autoUpdatePartialPriceSuccess' | 'autoUpdatePartialPriceFailed' - | 'isPartialPriced'; + | 'isPartialPriced' + | 'unusualInvalidItems'; export default function sendAlert( type: AlertType, @@ -107,6 +108,10 @@ export default function sendAlert( title = 'Received High-value invalid item(s)'; description = msg; color = '8323327'; // purple + } else if (type === 'unusualInvalidItems') { + title = 'Received Unusual bought with Generic Unusual feature'; + description = msg; + color = '8323327'; // purple } else if (type === 'autoRemoveIntentSellFailed') { title = 'Failed to remove item(s) with intent sell'; description = msg; @@ -217,7 +222,8 @@ export default function sendAlert( 'queue-problem-not-restart-bptf-down', 'autoAddPaintedItemsFailed', 'failed-accept', - 'error-accept' + 'error-accept', + 'unusualInvalidItems' ].includes(type) && optDW.sendAlert.isMention ? `<@!${optDW.ownerID}>` : '') + (content ? ` - ${content}` : ''), diff --git a/src/schemas/options-json/options.ts b/src/schemas/options-json/options.ts index 56c2c04a9..d4d9c202c 100644 --- a/src/schemas/options-json/options.ts +++ b/src/schemas/options-json/options.ts @@ -482,6 +482,9 @@ export const optionsSchema: jsonschema.Schema = { }, required: ['onUpdate', 'onSuccessUpdatePartialPriced', 'onFailedUpdatePartialPriced'], additionalProperties: false + }, + receivedUnusualNotInPricelist: { + type: 'boolean' } }, required: [ @@ -493,7 +496,8 @@ export const optionsSchema: jsonschema.Schema = { 'autoAddPaintedItems', 'failedAccept', 'unableToProcessOffer', - 'partialPrice' + 'partialPrice', + 'receivedUnusualNotInPricelist' ], additionalProperties: false }, @@ -523,6 +527,9 @@ export const optionsSchema: jsonschema.Schema = { autoAddInvalidItems: { $ref: '#/definitions/only-enable' }, + autoAddInvalidUnusual: { + $ref: '#/definitions/only-enable' + }, autoAddPaintedItems: { $ref: '#/definitions/only-enable' }, @@ -543,6 +550,7 @@ export const optionsSchema: jsonschema.Schema = { 'filterCantAfford', 'autoRemoveIntentSell', 'autoAddInvalidItems', + 'autoAddInvalidUnusual', 'autoAddPaintedItems', 'priceAge' ],