From b97c1ff323bf1cc8861980dd817f6cbdab0e5209 Mon Sep 17 00:00:00 2001 From: Jason Hunter Date: Wed, 15 Feb 2017 23:10:29 -0500 Subject: [PATCH 1/2] optimize sniping and bidding, potential BIN listing fix --- app/actions/bid.js | 39 +++++++++++++++++++------ app/actions/logic/index.js | 5 ---- app/components/Settings.js | 3 +- app/components/player/PlayerSettings.js | 3 +- app/containers/Account.js | 3 +- app/package.json | 2 +- package.json | 2 +- test/actions/bid.spec.js | 20 ++++++------- 8 files changed, 48 insertions(+), 29 deletions(-) diff --git a/app/actions/bid.js b/app/actions/bid.js index e5cc0f9..e3d5bd7 100644 --- a/app/actions/bid.js +++ b/app/actions/bid.js @@ -78,7 +78,7 @@ export function setBINStatus(won) { export function snipe(player, settings) { return async (dispatch, getState) => { let state = getState(); - const api = getApi(state.account.email); + let api = getApi(state.account.email); dispatch(addMessage('log', `Preparing to snipe ${player.name}...`)); // Snipe const binFilter = _.merge({}, filter, { @@ -93,6 +93,8 @@ export function snipe(player, settings) { binResponse = { auctionInfo: [] }; } dispatch(addMessage('log', `${binResponse.auctionInfo.length} BIN found for ${player.name}...`)); + // drop RPM for sniping + api = getApi(state.account.email, 60); for (const trade of binResponse.auctionInfo) { // refresh state every trade state = getState(); @@ -140,6 +142,7 @@ export function snipe(player, settings) { } } } + api = getApi(state.account.email, settings.rpm); }; } @@ -147,7 +150,7 @@ export function placeBid(player, settings) { return async (dispatch, getState) => { if (!settings.snipeOnly) { let state = getState(); - const api = getApi(state.account.email); + let api = getApi(state.account.email); dispatch(addMessage('log', `Getting ready to search auctions for ${player.name}...`)); const bidFilter = _.merge({}, filter, { definitionId: player.id, @@ -189,12 +192,22 @@ export function placeBid(player, settings) { // The card has at least one contract && trade.itemData.contract > 0 ) { + // Get the latest status of this trade + api = getApi(state.account.email, 0); + let latestTrade; + try { + const status = await api.getStatus([trade.tradeId]); + dispatch(setCredits(status.credits)); + latestTrade = _.get(status, 'auctionInfo[0]', trade); + } catch (e) { + latestTrade = trade; + } // Set our bid let bid; - if (trade.currentBid) { - bid = Fut.calculateNextHigherPrice(trade.currentBid); + if (latestTrade.currentBid) { + bid = Fut.calculateNextHigherPrice(latestTrade.currentBid); } else { - bid = trade.startingBid; + bid = latestTrade.startingBid; } // If the next step up is our max, go ahead and bid max @@ -204,16 +217,19 @@ export function placeBid(player, settings) { } // Make sure we aren't trying to spend more than we want to - if (bid <= player.price.buy && bid <= state.account.credits) { + if (latestTrade.expires > 0 && bid <= player.price.buy && bid <= state.account.credits) { // Bid! let tradeResult = {}; try { - const placeBidResponse = await api.placeBid(trade.tradeId, bid); + const placeBidResponse = await api.placeBid(latestTrade.tradeId, bid); dispatch(setCredits(placeBidResponse.credits)); tradeResult = _.get(placeBidResponse, 'auctionInfo[0]', {}); } catch (e) { dispatch(addMessage('error', `Error placing bid on ${player.name}`, e)); } + + // Reset RPM for this stuff + api = getApi(state.account.email, settings.rpm); // tradeResult = { // bidState: 'highest', // tradeId: trade.tradeId, @@ -239,7 +255,12 @@ export function placeBid(player, settings) { dispatch(addMessage('warn', `Something happened when trying to bid on ${player.name}`)); } } else { - dispatch(addMessage('log', `Required bid (${bid}) is more than we are willing to pay for ${player.name} (${player.price.buy})`)); + if (latestTrade.expires === -1 && latestTrade.currentBid < player.price.bid) { + dispatch(addMessage('warn', `TOO SLOW: Trade has expired for ${player.name} (sold for ${latestTrade.currentBid})`)); + } else { + dispatch(addMessage('log', `Required bid (${bid}) is more than we are willing to pay for ${player.name} (${player.price.buy})`)); + } + api = getApi(state.account.email, settings.rpm); } } } @@ -378,7 +399,7 @@ export function continueTracking(settings) { return async (dispatch, getState) => { let state = getState(); const api = getApi(state.account.email); - const tradeIds = Object.keys(state.bid.trades); + const tradeIds = Object.keys(state.bid.trades).filter(id => id > 0); if (!settings.snipeOnly && tradeIds.length) { dispatch(addMessage('log', `Updating status on ${tradeIds.length} active trades...`)); let statuses; diff --git a/app/actions/logic/index.js b/app/actions/logic/index.js index 5420967..44d73b8 100644 --- a/app/actions/logic/index.js +++ b/app/actions/logic/index.js @@ -80,9 +80,6 @@ export function bidCycle() { await dispatch(bidActions.placeBid(player, settings)); } - // Update items always when bidding - // await dispatch(bidActions.updateItems(player, settings)); - state = getState(); if (state.bid.bidding) { if (!settings.snipeOnly) { @@ -96,8 +93,6 @@ export function bidCycle() { } // buy now goes directly to unassigned now - state = getState(); - dispatch(bidActions.setBINStatus(!!state.bid.unassigned.length)); await dispatch(bidActions.binNowToUnassigned()); // Log sold items diff --git a/app/components/Settings.js b/app/components/Settings.js index 561314e..9c553b8 100644 --- a/app/components/Settings.js +++ b/app/components/Settings.js @@ -260,7 +260,8 @@ Settings.propTypes = { sell: PropTypes.string, bin: PropTypes.string, relistAll: PropTypes.bool - }) + }), + errors: PropTypes.shape({}) }; Settings.contextTypes = { diff --git a/app/components/player/PlayerSettings.js b/app/components/player/PlayerSettings.js index 788b681..4eefc98 100644 --- a/app/components/player/PlayerSettings.js +++ b/app/components/player/PlayerSettings.js @@ -222,7 +222,8 @@ PlayerSettings.propTypes = { player: PropTypes.shape({ list: PropTypes.shape({}) }), - settings: PropTypes.shape({}) + settings: PropTypes.shape({}), + errors: PropTypes.shape({}) }; PlayerSettings.contextTypes = { diff --git a/app/containers/Account.js b/app/containers/Account.js index 63bf82f..8532133 100644 --- a/app/containers/Account.js +++ b/app/containers/Account.js @@ -232,7 +232,8 @@ Account.propTypes = { platform: PropTypes.string, code: PropTypes.string, }), - next: PropTypes.func // only used for tests + next: PropTypes.func, // only used for tests + errors: PropTypes.shape({}) }; Account.contextTypes = { diff --git a/app/package.json b/app/package.json index 3e25908..a23c418 100644 --- a/app/package.json +++ b/app/package.json @@ -1,7 +1,7 @@ { "name": "fifa-autobuyer", "productName": "FIFA Autobuyer", - "version": "0.4.2", + "version": "0.4.3", "description": "Autobuyer for FIFA 17 Ultimate Team", "main": "./main.js", "author": { diff --git a/package.json b/package.json index 33f5433..973beda 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "fifa-autobuyer", "productName": "FIFA Autobuyer", - "version": "0.4.2", + "version": "0.4.3", "description": "Autobuyer for FIFA 17 Ultimate Team", "main": "main.js", "scripts": { diff --git a/test/actions/bid.spec.js b/test/actions/bid.spec.js index 1a94d03..975bfbc 100644 --- a/test/actions/bid.spec.js +++ b/test/actions/bid.spec.js @@ -167,7 +167,7 @@ describe('actions', () => { const settings = { minCredits: 1000, maxCard: 5 }; const store = mockStore(initialState); await store.dispatch(actions.snipe(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(searchStub.calledOnce).to.eql(true); const cleanActions = _.filter(store.getActions(), a => a.type !== types.ADD_MESSAGE); expect(cleanActions.length).to.eql(0); @@ -191,7 +191,7 @@ describe('actions', () => { const settings = { minCredits: 1000, maxCard: 5 }; const store = mockStore(initialState); await store.dispatch(actions.snipe(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(searchStub.calledOnce).to.eql(true); const cleanActions = _.filter(store.getActions(), a => a.type !== types.ADD_MESSAGE); expect(cleanActions.length).to.eql(0); @@ -223,7 +223,7 @@ describe('actions', () => { const settings = { minCredits: 10000, maxCard: 5 }; const store = mockStore(initialState); await store.dispatch(actions.snipe(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(searchStub.calledOnce).to.eql(true); expect(bidStub.called).to.eql(false); const cleanActions = _.filter(store.getActions(), a => a.type !== types.ADD_MESSAGE); @@ -256,7 +256,7 @@ describe('actions', () => { const settings = { minCredits: 1000, maxCard: 5 }; const store = mockStore(initialState); await store.dispatch(actions.snipe(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(searchStub.calledOnce).to.eql(true); expect(bidStub.called).to.eql(false); const cleanActions = _.filter(store.getActions(), a => a.type !== types.ADD_MESSAGE); @@ -300,7 +300,7 @@ describe('actions', () => { const settings = { minCredits: 1000, maxCard: 5 }; const store = mockStore(initialState); await store.dispatch(actions.snipe(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(searchStub.calledOnce).to.eql(true); expect(bidStub.calledOnce).to.eql(true); /* @@ -354,7 +354,7 @@ describe('actions', () => { const settings = { minCredits: 1000, maxCard: 5 }; const store = mockStore(initialState); await store.dispatch(actions.snipe(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(searchStub.calledOnce).to.eql(true); expect(bidStub.calledOnce).to.eql(true); /* @@ -397,7 +397,7 @@ describe('actions', () => { const settings = { minCredits: 1000, maxCard: 5 }; const store = mockStore(initialState); await store.dispatch(actions.snipe(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(searchStub.calledOnce).to.eql(true); expect(bidStub.calledOnce).to.eql(true); const cleanActions = _.filter(store.getActions(), a => a.type !== types.ADD_MESSAGE); @@ -518,7 +518,7 @@ describe('actions', () => { const settings = { minCredits: 10000, maxCard: 5, snipeOnly: false }; const store = mockStore(initialState); await store.dispatch(actions.placeBid(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(highestPriceStub.calledTwice).to.eql(true); const cleanActions = _.filter(store.getActions(), a => a.type !== types.ADD_MESSAGE); expect(cleanActions).to.be.eql( @@ -586,7 +586,7 @@ describe('actions', () => { const settings = { minCredits: 10000, maxCard: 5, snipeOnly: false }; const store = mockStore(initialState); await store.dispatch(actions.placeBid(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(highestPriceStub.calledOnce).to.eql(true); const cleanActions = _.filter(store.getActions(), a => a.type !== types.ADD_MESSAGE); expect(cleanActions).to.be.eql( @@ -642,7 +642,7 @@ describe('actions', () => { const settings = { minCredits: 10000, maxCard: 5, snipeOnly: false }; const store = mockStore(initialState); await store.dispatch(actions.placeBid(player, settings)); - expect(apiStub.calledOnce).to.eql(true); + expect(apiStub.callCount).to.eql(3); expect(searchStub.calledOnce).to.eql(true); expect(highestPriceStub.calledTwice).to.eql(true); expect(bidStub.calledOnce).to.eql(true); From 0730a7fc69599af6cb80294e17d5372768ac68cd Mon Sep 17 00:00:00 2001 From: Jason Hunter Date: Thu, 16 Feb 2017 00:00:38 -0500 Subject: [PATCH 2/2] fix RPM issue with placeBid --- app/actions/bid.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/app/actions/bid.js b/app/actions/bid.js index e3d5bd7..85d93cb 100644 --- a/app/actions/bid.js +++ b/app/actions/bid.js @@ -193,7 +193,6 @@ export function placeBid(player, settings) { && trade.itemData.contract > 0 ) { // Get the latest status of this trade - api = getApi(state.account.email, 0); let latestTrade; try { const status = await api.getStatus([trade.tradeId]); @@ -220,15 +219,15 @@ export function placeBid(player, settings) { if (latestTrade.expires > 0 && bid <= player.price.buy && bid <= state.account.credits) { // Bid! let tradeResult = {}; + api = getApi(state.account.email, 0); try { + // No delay between status and bid const placeBidResponse = await api.placeBid(latestTrade.tradeId, bid); dispatch(setCredits(placeBidResponse.credits)); tradeResult = _.get(placeBidResponse, 'auctionInfo[0]', {}); } catch (e) { dispatch(addMessage('error', `Error placing bid on ${player.name}`, e)); } - - // Reset RPM for this stuff api = getApi(state.account.email, settings.rpm); // tradeResult = { // bidState: 'highest', @@ -254,13 +253,10 @@ export function placeBid(player, settings) { // TODO: do something about this dispatch(addMessage('warn', `Something happened when trying to bid on ${player.name}`)); } + } else if (latestTrade.expires === -1 && latestTrade.currentBid < player.price.bid) { + dispatch(addMessage('warn', `TOO SLOW: Trade has expired for ${player.name} (sold for ${latestTrade.currentBid})`)); } else { - if (latestTrade.expires === -1 && latestTrade.currentBid < player.price.bid) { - dispatch(addMessage('warn', `TOO SLOW: Trade has expired for ${player.name} (sold for ${latestTrade.currentBid})`)); - } else { - dispatch(addMessage('log', `Required bid (${bid}) is more than we are willing to pay for ${player.name} (${player.price.buy})`)); - } - api = getApi(state.account.email, settings.rpm); + dispatch(addMessage('log', `Required bid (${bid}) is more than we are willing to pay for ${player.name} (${player.price.buy})`)); } } }