def arbitrage(obj): obj.current_strategy = 'Arbitrage' temp_settings = obj.strategy_settings['arbitrage'] min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] min_profit = temp_settings['min_profit'] min_percentage_of_price = temp_settings['min_percentage_of_price'] players = temp_settings['players'] remove_keys = [ 'min_price', 'max_price', 'min_profit', 'min_percentage_of_price', 'players' ] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Conducting Arbitrage...', level='title') players_to_arbitrage = [] # Go through player lists for player in players: futbin = info.get_price(player, obj, False, False, 'futbin') futhead = info.get_price(player, obj, False, False, 'futhead') if futbin != 0 and futhead != 0: potential = int(round((futbin * 0.95) - futhead)) percent = abs(int(round((potential / futbin) * 100))) if potential > min_profit and percent > min_percentage_of_price: players_to_arbitrage.append( (player, futhead, futbin, potential)) sleep(0.25) if len(players_to_arbitrage) == 0: multi_log(obj, 'No players to arbitrage') return None for player in players_to_arbitrage: search_price = player[2] tier = info.get_tier(search_price) search_price = info.round_down(search_price, Global.rounding_tiers[tier]) sell_price = info.round_down(player[2] - (0.2 * player[3]), Global.rounding_tiers[tier]) if search_price > 0: if obj.get_credits( ) > search_price and min_price <= search_price <= max_price: snipe_criteria = { 'search_type': 'Players', 'player': player[0], 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } common_snipe(obj, name=info.get_player_info( snipe_criteria['player'], False)['name'], snipe_criteria=snipe_criteria, price=search_price, sell_price=sell_price, strategy='arbitrage', **settings)
def common_wait_to_expire(obj, strategy, remaining_players=None, acquired=None, sell_price=None, sell_acquired_if_full=True): max_expire = 0 obj.go_to('transfer_targets') bids = obj.__get_items__(p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Active Bids')]", gp_type='xpath', get_price=False) for bid in bids: if bid['time_left'] > max_expire: max_expire = bid['time_left'] multi_log(obj, 'Waiting on last bid to expire...') if max_expire > 60: multi_log( obj, 'Will check every 30 seconds to see if we\'re outbid on everything.' ) while True: active_bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Active Bids')]", gp_type='xpath', get_price=False) winning = 0 for bid in active_bids: if bid['bid_status'] == 'outbid': try: bid['element'].click() side_panel = obj.__get_class__('DetailView', as_list=False) side_panel.find_element_by_class_name('watch').click() obj.keep_alive(Global.micro_min) except (StaleElementReferenceException, WebDriverException): pass else: if bid['time_left'] > max_expire: max_expire = bid['time_left'] winning += 1 if winning == 0: break remaining_players, acquired = common_process_transfer_targets( obj, strategy, remaining_players, acquired, sell_price, sell_acquired_if_full) obj.keep_alive(30) if obj.location != 'home': obj.go_to('home') if obj.location != 'transfer_targets': obj.go_to('transfer_targets') remaining_players, acquired = common_process_transfer_targets( obj, strategy, remaining_players, acquired, sell_price, sell_acquired_if_full) return remaining_players, acquired
def snipe(obj): obj.current_strategy = 'Snipe' temp_settings = obj.strategy_settings['snipe'] min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] players = temp_settings['players'] rotate = temp_settings['rotate'] remove_keys = ['min_price', 'max_price', 'players', 'rotate'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Sniping...', level='title') # Go through player lists if not rotate: for player in players: futbin_price = info.get_price(player, obj=obj) if futbin_price > 0: if obj.get_credits() > futbin_price and min_price <= futbin_price <= max_price: snipe_criteria = { 'search_type': 'Players', 'player': player, 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } common_snipe(obj, name=info.get_player_info(snipe_criteria['player'], False)['name'], snipe_criteria=snipe_criteria, strategy='snipe', **settings) else: rotations_remaining = settings['max_tries'] temp_settings = settings remove_keys = ['max_tries'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} while rotations_remaining > 0: for player in players: futbin_price = info.get_price(player, obj=obj) if futbin_price > 0: if obj.get_credits() > futbin_price and min_price <= futbin_price <= max_price: snipe_criteria = { 'search_type': 'Players', 'player': player, 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } common_snipe(obj, name=info.get_player_info(snipe_criteria['player'], False)['name'], snipe_criteria=snipe_criteria, strategy='snipe', max_tries=1, **settings) rotations_remaining -= 1
def common_fight(obj, strategy, use_buy_percent=None, min_profit=100): def get_bids(price_to_get): bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Active Bids')]", gp_type='xpath', get_price=price_to_get) to_fight = [] for b in bids: if not b['expired'] and b['time_left'] > 5: to_fight.append(b) return to_fight multi_log(obj, 'Fighting for bids...', level='header') obj.go_to('transfer_targets') fight_bids = get_bids(True) prices = {} for bid in fight_bids: prices[bid['resource_id']] = info.get_price(bid['resource_id'], obj, False) min_expire = 9999999 while len(fight_bids) > 0: fight_bids = get_bids(False) for bid in fight_bids[:]: if bid['time_left'] < min_expire: min_expire = bid['time_left'] if not bid['expired'] and bid[ 'bid_status'] == 'outbid' and 3 < bid['time_left'] <= 60: tier = info.get_tier(bid['current_bid']) profit_buy_percent = obj.bin_settings[tier]['buy_percent'] max_bin = prices[bid['resource_id']] if strategy != 'acquire': if not use_buy_percent: max_buy = info.round_down( (max_bin * 0.95 * dynamic_profit(obj) - min_profit * obj.bin_settings[tier]['sell_percent']), Global.rounding_tiers[tier]) else: max_buy = info.round_down( (max_bin * profit_buy_percent * dynamic_profit(obj)), Global.rounding_tiers[tier]) else: max_buy = max_bin my_bid = bid['current_bid'] + Global.rounding_tiers[tier] if my_bid <= max_buy: obj.bid(item=bid, amount=my_bid) common_process_transfer_targets(obj, strategy) obj.keep_alive(5) multi_log(obj, 'There are 0 remaining bids to fight for. Processing...') common_process_transfer_targets(obj, strategy)
def check_transfer_targets(return_data): if obj.location != 'transfer_targets': obj.go_to('transfer_targets') multi_log(obj, 'Waiting on last bid to expire') while True: max_expire = 0 watched_items = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Watched Items')]", gp_type='xpath', get_price=False) if len(watched_items) == 0: break for item in watched_items: if item['time_left'] > max_expire: max_expire = item['time_left'] obj.keep_alive(max_expire + 5) expired_bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Expired Items')]", gp_type='xpath', get_price=False) expired = {} for expired_bid in expired_bids: if expired_bid['asset_id'] in settings['players']: if expired_bid['asset_id'] not in list(expired.keys()): expired[expired_bid['asset_id']] = { 'bid_amounts': 0, 'num_results': 0 } expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[ 'current_bid'] expired[expired_bid['asset_id']]['num_results'] += 1 for asset, data in expired.items(): return_data[asset]['average_bid'] = info.round_down( data['bid_amounts'] / data['num_results'], rounding) for return_asset, return_info in return_data.items(): name = info.get_player_info(return_asset, False)['name'] multi_log( obj, '{}\'s Average Bid: {}'.format(name, return_info['average_bid'])) database.save_market_data(obj, name, return_info['asset_id'], return_info['average_bid'], return_info['minimum_bin']) obj.clear_expired() return {}, 0
def check_sleep(obj): sleep_interval = obj.settings['sleep_after_running_for_x_minutes'] * 60 now = datetime.now() if (now - obj.last_sleep).seconds >= sleep_interval: sleep_average = obj.settings['sleep_average'] sleep_spread = obj.settings['sleep_spread'] sleep_time = rand(sleep_average - sleep_spread, sleep_average + sleep_spread) * 60 multi_log(obj, 'Exceeded maximum active time.') obj.keep_alive(sleep_time) obj.clear_sold() obj.relist_all() obj.last_sleep = datetime.now() else: night_mode(obj)
def housekeeping(obj): multi_log(obj, 'Housekeeping...', level='header') obj.check_unassigned() if obj.location != 'transfers': obj.go_to('transfers') obj.clear_sold() obj.relist_all() obj.clear_expired() obj.sell_transfer_targets_at_market() hour, day = database.get_profit(obj) multi_log( obj, 'Profit in last hour: {} | Profit in last 24 hours: {} | Credits: {}' .format(hour, day, obj.credits)) # TODO: Remove once GUI is implemented
def futbin_cheapest_sbc(obj): obj.current_strategy = 'Futbin Cheapest SBC' temp_settings = obj.strategy_settings['futbin_cheapest_sbc'] total_bids = 0 def buy_and_search(target_player): player_info = info.get_player_info(target_player, include_futbin_price=True) player_name = player_info['name'] bids = 0 if obj.credits > player_info['futbin_price']: hunt_criteria = { 'search_type': 'Players', 'player': target_player, 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } bids = common_hunt(obj=obj, name=player_name, hunt_criteria=hunt_criteria, strategy='futbin_cheapest_sbc', **settings) return bids multi_log(obj, 'Hunting for Cheapest SBC on Futbin...', level='title') min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] remove_keys = ['min_price', 'max_price'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} players = info.get_futbin_cheapest_sbc(obj, min_price, max_price) for player in players: num_bids = buy_and_search(player) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='futbin_cheapest_sbc') else: total_bids += num_bids if total_bids > 0: common_wait_to_expire(obj=obj, strategy='futbin_cheapest_sbc')
def process_items(items): for item in items: if item['item_type'] == 'player': price = item['futbin_price'] tier = info.get_tier(price) bin_price = max(250, info.round_down(price * obj.bin_settings[tier]['sell_percent'], Global.rounding_tiers[tier])) if bin_price > 350: start_price = bin_price - obj.bin_settings[tier]['spread'] actions.sell(obj, item, start_price, bin_price) else: actions.send_to_club(obj, item, strategy='bpm') elif item['item_type'] == 'fitness' and 'squad' in item['item_name'].lower(): if settings['keep_squad_fitness']: actions.send_to_club(obj, item, strategy='bpm') else: actions.sell(obj, item, 500, 800) elif item['item_type'] == 'healing': if any(s in item['item_name'].lower() for s in ['all', 'upper', 'foot', 'leg', 'knee', 'arm']): if 'all' in item['item_name'].lower(): actions.sell(obj, item, 250, 500) else: actions.sell(obj, item, 150, 200) else: actions.send_to_club(obj, item, strategy='bpm') elif min_sell_types and item['item_type'] in min_sell_types: actions.sell(obj, item, 150, 200) elif club_types and item['item_type'] in club_types: if item['item_type'] == 'fitness' and 'squad' in item['item_name'].lower(): actions.sell(obj, item, 300, 500) elif item['quality'] != 'bronze' and item['item_type'] != 'staff': actions.sell(obj, item, 150, 200) else: actions.send_to_club(obj, item, strategy='bpm') elif quick_sell_types and item['item_type'] in quick_sell_types: if item['item_type'] == 'training' and 'all' in item['item_name'].lower(): actions.sell(obj, item, 200, 400) else: multi_log(obj, 'Will quick sell {} at the end'.format(item['item_name'])) elif item['item_type'].lower != 'coins' : item['element'].click() obj.driver.find_element_by_xpath(".//*[contains(text(), 'Redeem')]").click() else: multi_log(obj, 'NEW ITEM IN BPM: {}'.format(item), level='warn', notify=True, icon_url=item['image']) obj.keep_alive(Global.micro_max) try: obj.keep_alive(Global.small_max) obj.driver.find_element_by_xpath(".//*[contains(text(), 'Quick Sell') and (contains(text(), 'Item'))]").click() multi_log(obj, 'Quick selling remaining items') obj.keep_alive(Global.small_max) modal = obj.__get_class__('ui-dialog-type-message', as_list=False) modal.find_element_by_xpath(".//*[contains(text(), 'Ok')]").click() obj.location = 'store' except Exception as e: multi_log(obj, e, level='error') obj.keep_alive(Global.small_max)
def consumable_amass(obj): obj.current_strategy = 'Consumable Amass' temp_settings = obj.strategy_settings['consumable_amass'] filters = temp_settings['filters'] sell_price = {} for f in filters: sell_price[f['item']] = f['sell_price'] remove_keys = ['filters', 'sell_price'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Filter amassing consumables...', level='title') total_bids = 0 # Search and bid for f in filters: try: hunt_criteria = { 'search_type': 'Consumables', 'item': f['item'], 'quality': f.get('quality', None), 'position': f.get('position', None), 'chem_style': f.get('chem_style', None), 'nation': f.get('nation', None), 'league': f.get('league', None), 'club': f.get('club', None), 'max_buy': f['max_buy'] } except ValueError: continue name = '/'.join( [str(x) for x in list(hunt_criteria.values()) if x is not None]) num_bids = common_hunt(obj=obj, name=name, hunt_criteria=hunt_criteria, strategy='consumable_amass', **settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='consumable_amass', sell_price=sell_price) else: total_bids += num_bids if total_bids > 0: common_wait_to_expire(obj=obj, strategy='consumable_amass', sell_price=sell_price)
def continual_relist(obj, ignore_tradepile=False): current_location = obj.location previous_length = 0 while True or ignore_tradepile: obj.current_strategy = 'Continual Relist' multi_log(obj, 'Reached maximum tradepile capacity. Entering relist-only mode...') obj.clear_sold() obj.relist_all() items = obj.__get_items__(get_price=False) min_expire = 60 * 60 for item in items: if item['time_left'] < min_expire: min_expire = item['time_left'] if len(items) < previous_length and not ignore_tradepile: break else: previous_length = len(items) obj.keep_alive(rand(min_expire, min_expire + (15 * 60))) obj.go_to(current_location)
def check_unlock(obj): while True: obj.go_to('transfers') if len(obj.driver.find_elements_by_class_name( 'tileDisabledMessage')) == 0: multi_log(obj, 'MARKET UNLOCKED', notify=True, level='title', title='MARKET UNLOCKED') return True else: multi_log(obj, 'Market still locked', notify=True, level='info', title='Still locked') wait = rand(60 * 60, 60 * 120) obj.keep_alive(wait)
def common_deal_with_full_transfer_list(obj, strategy=None): current_location = obj.location multi_log(obj, 'Clearing out transfer list to make room for more transfers...') obj.clear_sold() while True: if strategy == 'acquire': break min_expire = 99999 active_transfers = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Active Transfers')]", gp_type='xpath', get_price=False) if len(active_transfers) == 0: break for transfer in active_transfers: if transfer['time_left'] < min_expire: min_expire = transfer['time_left'] multi_log(obj, 'Waiting on next transfer to expire...') obj.keep_alive(min_expire + 15) obj.clear_sold() obj.go_to('home') multi_log(obj, 'Transfer list is clear. Attempting to resume...') obj.go_to(current_location)
def hunt(obj): obj.current_strategy = 'Hunt' temp_settings = obj.strategy_settings['hunt'] min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] players = temp_settings['players'] remove_keys = ['min_price', 'max_price', 'players'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Hunting...', level='title') total_bids = 0 # Search and bid for player in players: futbin_price = info.get_price(player, obj=obj) if futbin_price > 0: if obj.get_credits() > futbin_price and min_price <= futbin_price <= max_price: hunt_criteria = { 'search_type': 'Players', 'player': player, 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } num_bids = common_hunt(obj=obj, name=info.get_player_info(hunt_criteria['player'], False)['name'], hunt_criteria=hunt_criteria, strategy='hunt', **settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='hunt') else: total_bids += num_bids if total_bids > 0: if not settings['use_max_buy']: common_fight(obj=obj, strategy='hunt', settings=settings) else: common_wait_to_expire(obj=obj, strategy='hunt')
def amass(obj): obj.current_strategy = 'Amass' temp_settings = obj.strategy_settings['amass'] players = temp_settings['players'] remove_keys = ['players'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Amassing players...', level='title') total_bids = 0 # Search and bid for player in players: player_name = info.get_player_info(player, include_futbin_price=False)['name'] hunt_criteria = { 'search_type': 'Players', 'player': player, 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } num_bids = common_hunt(obj=obj, name=player_name, hunt_criteria=hunt_criteria, strategy='amass', **settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='amass') else: total_bids += num_bids if total_bids > 0: common_wait_to_expire(obj=obj, strategy='amass') total_bids = 0
def night_mode(obj): from ruamel.yaml import YAML yaml = YAML() yaml.explicit_start = True yaml.indent(mapping=4) yaml.preserve_quotes = True settings = obj.settings['night_mode'] now = datetime.now() if settings['enabled'] and (now - settings['last_sleep']).seconds * 60 * 60 > 12: start = datetime(now.year, now.month, now.day, settings['start_hour'], 0, 0, 0) if now.hour >= settings['end_hour']: try: end = datetime(now.year, now.month, now.day + 1, settings['end_hour'], 0, 0, 0) except ValueError: end = datetime(now.year, now.month + 1, 1, settings['end_hour'], 0, 0, 0) else: end = datetime(now.year, now.month, now.day, settings['end_hour'], 0, 0, 0) if start <= now < end: with open(obj.config_file) as config: new_config = yaml.load(config) new_config['settings']['night_mode'][ 'last_sleep'] = datetime.now() new_config['settings']['night_mode']['need_relist'] = True with open(obj.config_file, 'w') as update: yaml.dump(new_config, update) relist = settings['relist_for'] active_transfers = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Active Transfers')]", gp_type='xpath', get_price=False) if len(active_transfers) > 0: longest_time_left = active_transfers[-1]['time_left'] + 10 multi_log( obj, '[Night Mode] Waiting until current transfers expire') obj.keep_alive( longest_time_left) # Ensure all transfers are expired multi_log( obj, '[Night Mode] Relisting all transfers for {}'.format(relist)) obj.relist_individually(at_market=False, duration=relist) sleep_time = (end - datetime.now()).seconds multi_log( obj, '[Night Mode] Sleeping until'.format(settings['end_hour'])) obj.keep_alive(sleep_time) if settings['wait_for_enter']: obj.wait_for_enter()
def coin_transfer_list(obj, lose_coins, players): # List player for 80-90% of max with a bid random few steps below and for 1 day run_transfer_finish = False for i, player in enumerate(players): name = info.get_player_info(player)['name'] tier = info.get_tier(38000) step = Global.rounding_tiers[tier] start_price = info.round_down(int(38000 + (rand(-10, 10) * step)), Global.rounding_tiers[tier]) bin_price = info.round_down(start_price + (rand(6, 10) * step), Global.rounding_tiers[tier]) result = find_player(obj, player) if len(result) == 1: run_transfer_finish = True obj.sell(result[0], start_price, bin_price, duration='1 Day') # Record min bid and bin and time to expire expires = datetime.now() + timedelta(days=1) with open(obj.config_file) as config: new_config = yaml.load(config) new_player = { 'asset_id': player, 'start_price': start_price, 'bin_price': bin_price, 'expires': expires, 'lose_coins': lose_coins } try: new_config['coin_transfer']['players'].append(new_player) except AttributeError: new_config['coin_transfer']['players'] = [] new_config['coin_transfer']['players'].append(new_player) with open(obj.config_file, 'w') as update: yaml.dump(new_config, update) else: multi_log(obj, 'Error finding player {} for coin transfer'.format(name), level='error', notify=True, title='Coin Transfer Error') if run_transfer_finish: # Start buy script that runs in background coin_transfer_finish_prep.prep(obj.bot_number, lose_coins) multi_log(obj, 'Waiting for coin transfer to finish in the background.') obj.location = 'home' else: multi_log(obj, 'Something went wrong with coin transferring and there were no players to list.', level='error', notify=True, title='Coin Transfer Error')
def dynamic_profit(obj): global step1_notified global step2_notified global normal_notified adjustment = 1 if obj.bin_settings['dynamic_profit']: if obj.bin_settings[ 'dynamic_profit_after1'] <= obj.current_tradepile_size < obj.bin_settings[ 'dynamic_profit_after2']: adjustment -= obj.bin_settings['dynamic_profit_steps'] * 2 normal_notified = False if not step2_notified: multi_log( obj, 'Dynamic profit enabled. Profit buy_percent increased by {}%' .format(int(obj.bin_settings['dynamic_profit_steps'] * 200)), level='header') step2_notified = True elif obj.current_tradepile_size > obj.bin_settings[ 'dynamic_profit_after2']: adjustment -= obj.bin_settings['dynamic_profit_steps'] normal_notified = False if not step1_notified: multi_log( obj, 'Dynamic profit enabled. Profit buy_percent increased by {}%' .format(int(obj.bin_settings['dynamic_profit_steps'] * 100)), level='header') step1_notified = True else: if step1_notified or step2_notified: if normal_notified: multi_log(obj, 'Profit buy_percent returned to normal', level='header') step1_notified = False step2_notified = False return adjustment
def silver_flip(obj): def check_transfer_targets(): if obj.location != 'transfer_targets': obj.go_to('transfer_targets') multi_log(obj, 'Waiting on last bid to expire') while True: max_expire = 0 watched_items = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Watched Items')]", gp_type='xpath', get_price=False) if len(watched_items) == 0: break for item in watched_items: if item['time_left'] > max_expire: max_expire = item['time_left'] obj.keep_alive(max_expire + 5) expired_bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Expired Items')]", gp_type='xpath', get_price=False) expired = {} for expired_bid in expired_bids: if expired_bid['asset_id'] not in list(expired.keys()): expired[expired_bid['asset_id']] = { 'bid_amounts': 0, 'num_results': 0 } expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[ 'current_bid'] expired[expired_bid['asset_id']]['num_results'] += 1 return_players = [] for asset, data in expired.items(): futbin_price = info.get_price(asset) tier = info.get_tier(futbin_price) rounding = Global.rounding_tiers[tier] average_bid = info.round_down( data['bid_amounts'] / data['num_results'], rounding) coins_from_sale = futbin_price * 0.95 potential_profit = coins_from_sale - average_bid if settings[ 'use_buy_percent'] and potential_profit >= coins_from_sale - ( futbin_price * obj.bin_settings['buy_percent']): return_players.append({ 'asset_id': asset, 'name': info.get_player_info(asset, False)['name'], 'bid': average_bid, 'futbin': futbin_price }) elif potential_profit >= settings['min_profit']: return_players.append({ 'asset_id': asset, 'name': info.get_player_info(asset, False)['name'], 'bid': average_bid, 'futbin': futbin_price }) for player_data in return_players: name = info.get_player_info(player_data['asset_id'], False)['name'] multi_log( obj, '{}\'s Average Bid: {} | Futbin price: {}'.format( name, player_data['bid'], player_data['futbin'])) obj.clear_expired() return return_players obj.current_strategy = 'Silver Flip' temp_settings = obj.strategy_settings['silver_flip'] min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] max_results = temp_settings['max_results'] market_monitor = temp_settings['market_monitor'] players = temp_settings['players'] remove_keys = [ 'max_iterations', 'min_price', 'max_price', 'market_monitor', 'players', 'max_results' ] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Silver Flipping...', level='title') # Get market information bid_players = [] if len(players) == 0 or market_monitor['refresh']: obj.strategy_settings['silver_flip']['players'] = [] for league in market_monitor['leagues']: iterations = 0 multi_log(obj, 'Getting market data for {}.'.format(league)) while iterations < market_monitor['iterations']: full = False bid_results = obj.search(search_type='Players', quality='Silver', league=league, min_buy=min_price, max_buy=max_price) iterations += 1 for bid_result in bid_results: if bid_result['time_left'] <= market_monitor[ 'max_time_left'] and bid_result[ 'current_bid'] != bid_result['start_price']: bid_result['element'].click() obj.keep_alive(Global.micro_min) err = obj.__check_for_errors__() if err == 'limit': full = True break side_panel = obj.__get_class__('DetailView', as_list=False) try: side_panel.find_element_by_class_name( 'watch').click() err = obj.__check_for_errors__() if err == 'limit': full = True break except (ElementNotVisibleException, TimeoutException, NoSuchElementException): pass while not full: try: nav_bar = obj.__get_class__('pagingContainer', as_list=False) except (ElementNotVisibleException, NoSuchElementException, TimeoutException): nav_bar = obj.__get_class__('mainHeader', as_list=False) try: next_btn = nav_bar.find_element_by_class_name('next') obj.__click_element__(next_btn) bid_results = obj.__get_items__() least_time_left = 99999999 for bid_result in bid_results: if bid_result['time_left'] <= market_monitor[ 'max_time_left'] and bid_result[ 'current_bid'] != bid_result[ 'start_price']: bid_result['element'].click() obj.keep_alive(Global.micro_max) err = obj.__check_for_errors__() if err == 'limit': full = True break side_panel = obj.__get_class__('DetailView', as_list=False) try: side_panel.find_element_by_class_name( 'watch').click() err = obj.__check_for_errors__() if err == 'limit': full = True break except (ElementNotVisibleException, TimeoutException, NoSuchElementException): pass if bid_result['time_left'] < least_time_left: least_time_left = bid_result['time_left'] except (ElementNotVisibleException, NoSuchElementException, TimeoutException): break if full or least_time_left > market_monitor[ 'max_time_left']: break temp_players = check_transfer_targets() for temp_player in temp_players: if temp_players not in players: bid_players.append(temp_player) else: with open(obj.config_file) as config: old_config = yaml.load(config) bid_players = old_config['strategy_settings']['silver_flip'][ 'players'] # Get BIN info if futbin update is too late for bid_player in bid_players: max_bin, update = info.get_price(bid_player['asset_id'], obj, return_updated=True) tier = info.get_tier(max_bin) rounding = Global.rounding_tiers[tier] now = datetime.now() last_update = bid_player.get('last_update', None) if last_update: difference = (now - last_update).seconds else: difference = (now - now - timedelta(hours=99)).seconds if update > settings['max_futbin_update'] and update < difference: multi_log( obj, 'Price data for {} out of date. Getting current price...'. format(info.get_player_info(bid_player['asset_id'])['name'])) num_results = 0 total_bins = 0 bin_with_results = [] while num_results < 3: bin_results = obj.search(search_type='Players', player=bid_player['asset_id'], max_bin=max_bin) if len(bin_results) > max_results: if total_bins == 0: min_bin = 999999 for bin_result in bin_results: if bin_result['buy_now_price'] < min_bin: min_bin = bin_result[ 'buy_now_price'] - Global.rounding_tiers[ tier] max_bin = min_bin continue else: for bin_result in bin_results: if bin_result[ 'buy_now_price'] not in bin_with_results: total_bins += bin_result['buy_now_price'] num_results += 1 if len(bin_results) > 0: bin_with_results.append(max_bin) elif len(bin_results) == 0: max_bin += rounding * 2 else: for bin_result in bin_results: if bin_result['buy_now_price'] not in bin_with_results: total_bins += bin_result['buy_now_price'] num_results += 1 max_bin += rounding if len(bin_results) > 0: bin_with_results.append(max_bin) minimum_bin = info.round_down(total_bins / num_results, rounding) bid_player['minimum_bin'] = minimum_bin bid_player['last_update'] = datetime.now() else: bid_player['minimum_bin'] = max_bin coins_from_sale = bid_player['minimum_bin'] * 0.95 potential_profit = coins_from_sale - bid_player['bid'] current_players = [] if bid_player['asset_id'] not in current_players: current_players.append(bid_player['asset_id']) if settings['use_buy_percent']: if potential_profit >= coins_from_sale - ( bid_player['minimum_bin'] * obj.bin_settings['buy_percent']): players.append(bid_player) else: if potential_profit >= settings['min_profit']: players.append(bid_player) with open(obj.config_file) as config: new_config = yaml.load(config) new_config['strategy_settings']['silver_flip']['players'] = players with open(obj.config_file, 'w') as update: yaml.dump(new_config, update) total_bids = 0 # Search and bid for player in players: futbin_price = player['minimum_bin'] if futbin_price > 0: if obj.get_credits( ) > futbin_price and min_price <= futbin_price <= max_price: hunt_criteria = { 'search_type': 'Players', 'player': player['asset_id'], 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } num_bids = common_hunt(obj=obj, name=info.get_player_info( hunt_criteria['player'], False)['name'], price=futbin_price, hunt_criteria=hunt_criteria, strategy='silver_flip', **settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='hunt') else: total_bids += num_bids if total_bids > 0: if not settings['use_max_buy']: common_fight(obj=obj, strategy='silver_flip', settings=settings) else: common_wait_to_expire(obj=obj, strategy='silver_flip')
def acquire(obj, player_list, futbin_multiplier, increase_each_round=False, max_increases=5, sell_acquired_if_full=True, special_only=False): obj.current_strategy = 'Acquire' snipe_settings = obj.strategy_settings['acquire']['snipe'] hunt_settings = obj.strategy_settings['acquire']['hunt'] if type(player_list) is not list: new = [player_list] player_list = new if special_only: quality = 'Special' else: quality = None multi_log(obj, 'Acquiring Players...', level='title') # Go through player lists remaining_players = player_list acquired = [] iteration = 1 while len(remaining_players) > 0: bids = 0 search_list = [] if iteration > 1: snipe_settings['max_results'] = 9999999 print('{:<30} {:<20} {:<20}'.format('Name', 'Futbin Price', 'Asset ID')) for player in remaining_players: player_info = info.get_player_info(player, include_futbin_price=True) print('{:<30} {:<20} {:<20}'.format(player_info['name'], player_info['futbin_price'], player)) search_list.append(player_info) for player in search_list: name = player['name'] futbin_price = player['futbin_price'] tier = info.get_tier(futbin_price) max_bin = max(200, info.round_down(futbin_price * futbin_multiplier, Global.rounding_tiers[tier])) if increase_each_round: max_bin += Global.rounding_tiers[tier] * iteration include = [] if quality and quality.lower() == 'special' and int(player['asset_id']) <= 300000: special_ids = info.get_special_ids(player['asset_id']) for s in list(special_ids.values()): if int(s) >= 300000: include.append(s) include.append(info.get_base_id(player['asset_id'])) include.append(player.get('asset_id', None)) elif int(player['asset_id']) > 300000: include.append(player['asset_id']) include.append(info.get_base_id(player['asset_id'])) snipe_criteria = { 'search_type': 'Players', 'player': player['asset_id'], 'quality': quality, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': include, 'exclude': None, } snipe_result = common_snipe(obj=obj, snipe_criteria=snipe_criteria, name=name, strategy='acquire', price=max_bin, max_item_buys=1, sell_acquired_if_full=sell_acquired_if_full, **snipe_settings) if snipe_result == 'too many': multi_log(obj, 'Lots of results returned. Trying to get this cheaper by bidding...') max_bin -= Global.rounding_tiers[tier] elif snipe_result > 0: acquired.append((name, max_bin)) for i, player_id in enumerate(remaining_players): if str(player_id) == str(player['asset_id'] or str(player_id) in include): remaining_players.pop(i) break continue if obj.get_credits() > player['futbin_price']: num_bids = common_hunt(obj=obj, name=name, hunt_criteria=snipe_criteria, price=max_bin, strategy='acquire', max_item_bids=1, **hunt_settings) if num_bids == 'limit': common_wait_to_expire(obj, 'acquire', remaining_players, acquired, sell_acquired_if_full=sell_acquired_if_full) break elif num_bids == 'owned' or num_bids == 'sniped': acquired.append((name, max_bin)) for i, player_id in enumerate(remaining_players): if str(player_id) == str(player['asset_id']) or str(player_id) in include: remaining_players.pop(i) break else: bids += num_bids if bids > 0: remaining_players, acquired = common_wait_to_expire(obj, 'acquire', remaining_players, acquired, sell_acquired_if_full=sell_acquired_if_full) if increase_each_round and iteration <= max_increases: iteration += 1 if len(remaining_players) > 0: multi_log(obj, message='Increasing search price by {} step(s)'.format(min(iteration, max_increases))) multi_log(obj, message='Got all players!', level='green', notify=True, title='DONE') print('Acquired:') print('-' * 50) print('{:<30} {:<6}'.format('Name', 'Price')) for player in acquired: print('{:<30} {:<6}'.format(player[0], player[1])) return 'done'
def price_fix(obj): obj.current_strategy = 'Price Fix' settings = obj.strategy_settings['price_fix'] snipe_settings = settings['snipe'] hunt_settings = settings['hunt'] players = settings['players'] multi_log(obj, 'Price-fixing Players...', level='title') bids = 0 for num, player in players.items(): name = info.get_player_info(player['asset_id'], False)['name'] futbin_price = info.get_price(player['asset_id'], obj, False) if futbin_price > player['sell_price']: multi_log( obj, '{} price of {} is too low. Their Futbin price is {}'.format( name, player['sell_price'], futbin_price), level='warn') continue max_bin = player['sell_price'] tier = info.get_tier(max_bin) if settings['use_buy_percent']: max_bin = min( futbin_price, info.round_down( max_bin * obj.bin_settings[tier]['buy_percent'], Global.rounding_tiers[tier])) else: max_bin = info.round_down( (player['sell_price'] * 0.95) - settings['min_profit'], Global.rounding_tiers[tier]) sell_price = player['sell_price'] snipe_criteria = { 'search_type': 'Players', 'player': player['asset_id'], 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, } common_snipe(obj=obj, snipe_criteria=snipe_criteria, name=name, strategy='price_fix', price=max_bin, sell_price=sell_price, **snipe_settings) if obj.get_credits() > max_bin: num_bids = common_hunt(obj=obj, name=name, hunt_criteria=snipe_criteria, strategy='price_fix', price=max_bin, **hunt_settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='price_fix', sell_price=sell_price) else: bids += num_bids if bids > 0: common_wait_to_expire(obj=obj, strategy='price_fix', sell_price=sell_price) bids = 0
def find_player(obj, player_to_search): obj.go_to('players') search_button = obj.__get_class__('searchAction', as_list=False) obj.__click_element__(search_button) rating = None quality = 'Special' search_panel = obj.__get_class__('searchContainer', as_list=False) sleep(Global.micro_min / 2) name_list = [] if type(player_to_search) is int or (type(player_to_search) is str and any(n in player_to_search for n in '1234567890')): have_id = True try: db_player = Global.fifa_players[player_to_search] except KeyError: multi_log(obj, 'No player with id {} in fifa_players.json'.format(player_to_search), level='error') try: player_to_search = info.get_base_id(player_to_search) db_player = Global.fifa_players[player_to_search] except KeyError: return 'no_name' name_list = [db_player['first_name'], db_player['last_name'], db_player['surname']] temp_names = [] for name in name_list: if name: temp_names.append(name) name_list = temp_names if len(name_list) == 3: name_list = [name_list[2], name_list[0] + ' ' + name_list[1], name_list[0] + ' ' + name_list[2], name_list[1] + ' ' + name_list[2], name_list[1] + ' ' + name_list[0], name_list[1], name_list[2] + ' ' + name_list[0], name_list[2] + ' ' + name_list[1], name_list[0]] elif len(name_list) == 2: name_list = [name_list[0] + ' ' + name_list[1], name_list[1] + ' ' + name_list[0], name_list[1], name_list[0]] if not rating and int(player_to_search) < 300000: try: rating = Global.fifa_players[player_to_search]['rating'] except KeyError: pass else: have_id = False name = player_to_search.title() name_list.append(name) name_found = False while not name_found: if not name_list: multi_log(obj, message='Unable to find {}.'.format(player_to_search)) return [] name = name_list[0] name_box = search_panel.find_element_by_class_name('textInput') obj.__type_element__(name_box, name) name_parent = name_box.find_element_by_xpath('..') sleep(Global.micro_max) result_list = name_parent.find_element_by_tag_name('ul') results = result_list.find_elements_by_class_name('btn-text') if not results: if len(name_list) <= 1: multi_log(obj, 'Unable to find results for {}'.format(player_to_search), level='warn', notify=True, title='Search Error') return [] else: og_name = name new_name = name_list[1] multi_log(obj, '\"{}\" not found. Trying \"{}\"'.format(og_name, new_name), level='debug') search_panel = obj.__get_class__('ClubSearchFilters', as_list=False) name_list = name_list[1:] else: for r in results: if have_id: if rating and len(results) > 1: result_parent = r.find_element_by_xpath('..') result_rating = result_parent.find_element_by_class_name('btn-subtext').text if str(rating) == str(result_rating): obj.__click_element__(r) name_found = True break else: try: obj.__click_element__(r) name_found = True break except StaleElementReferenceException: return [] else: if name.lower() in parse.remove_accents(r.text).lower(): if rating and len(results) > 1: result_parent = r.find_element_by_xpath('..') result_rating = result_parent.find_element_by_class_name('btn-subtext').text if str(rating) == str(result_rating): obj.__click_element__(r) name_found = True break else: obj.__click_element__(r) name_found = True break if not name_found: name_list = name_list[1:] quality = quality.title() quality_dropdown = search_panel.find_element_by_xpath(".//*[contains(text(), 'Quality')]") obj.__click_element__(quality_dropdown) sleep(5) quality_parent = quality_dropdown.find_element_by_xpath('..') obj.__check_for_errors__() quality_parent.find_element_by_xpath(".//*[contains(text(), '{}')]".format(quality)).click() obj.__click_element__(search_panel.find_element_by_xpath(".//*[contains(text(), 'Search')]")) sleep(Global.small_min) results = obj.__get_items__(get_price=False) return results
def futbin_market(obj): obj.current_strategy = 'Futbin Market' temp_settings = obj.strategy_settings['futbin_market'] down_markets = temp_settings['down_markets'] up_markets = temp_settings['up_markets'] min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] remove_keys = ['down_markets', 'up_markets', 'min_price', 'max_price'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} total_bids = 0 def buy_and_search(target_player, group, total_b): bids = 0 futbin_price = info.get_price(target_player['asset_id'], obj) if target_player['change'] >= 10 and futbin_price > 0: if (group == 'down' and obj.credits > target_player['futbin_price'] and target_player['futbin_price'] * 1.2 >= futbin_price) \ or (group == 'up' and obj.credits > target_player['futbin_price']): hunt_criteria = { 'search_type': 'Players', 'player': target_player['asset_id'], 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } if group == 'down': max_bin = futbin_price * (1 - (target_player['change'] / 200)) else: max_bin = futbin_price * (1 - (target_player['change'] / 300)) bids += common_hunt(obj, hunt_criteria=hunt_criteria, name=info.get_player_info( hunt_criteria['player'], False)['name'], strategy='futbin_market_{}'.format(group), price=max_bin, **settings) return bids multi_log(obj, 'Futbin Market...', level='title') # Go through player lists have_markets = [] # Snipe down players and sell just below previous BIN for down_market in down_markets: multi_log(obj, 'Getting information for {} market...'.format(down_market)) market_data = info.get_futbin_market(obj, down_market, min_price, max_price) have_markets.append({'name': down_market, 'market_data': market_data}) if obj.url not in obj.driver.current_url: obj.driver.get(obj.url) obj.location = 'home' obj.rate_limit() obj.__get_xpath__('//*[@id="user-coin"]/div/span[2]', timeout=Global.large_max) if 40 < market_data['momentum'] <= 60: for player in market_data['down_players']: total_bids += buy_and_search(player, 'down', total_bids) if total_bids > 0: common_wait_to_expire(obj=obj, strategy='futbin_market_down') else: multi_log( obj, message= '{} market momentum of {} is too poor for down-hunting. Skipping...' .format(down_market, market_data['momentum'])) # Snipe up players below previous BIN and sell just below current BIN have_market_names = [] for have_market in have_markets: have_market_names.append(have_market['name']) for up_market in up_markets: if up_market in have_market_names: for have_market in have_markets: if have_market['name'] == up_market: market_data = have_market['market_data'] break else: market_data = info.get_futbin_market(obj, up_market, min_price, max_price) if obj.url not in obj.driver.current_url: obj.driver.get(obj.url) obj.location = 'home' obj.rate_limit() obj.__get_xpath__('//*[@id="user-coin"]/div/span[2]', timeout=Global.large_max) if 40 < market_data['momentum'] <= 75: for player in market_data['up_players']: num_bids = buy_and_search(player, 'up', total_bids) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='futbin_market_up') else: total_bids += num_bids if total_bids > 0: common_wait_to_expire(obj=obj, strategy='futbin_market_up') else: multi_log( obj, message= '{} market momentum of {} is too poor for up-hunting. Skipping...' .format(up_market, market_data['momentum']))
def sbc_hunt(obj): obj.current_strategy = 'SBC Hunt' temp_settings = obj.strategy_settings['sbc_hunt'] max_iterations = temp_settings['max_iterations'] min_price = temp_settings['min_price'] max_price = temp_settings['max_price'] only_new = temp_settings['only_new'] solutions_per_challenge = temp_settings['solutions_per_challenge'] refresh_players = temp_settings['refresh_players'] max_players = temp_settings['max_players'] remove_keys = [ 'max_iterations', 'min_price', 'max_price', 'only_new', 'refresh_players', 'players', 'solutions_per_challenge', 'max_players' ] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'SBC Hunting...', level='title') if refresh_players: all_players = [] def remove_cookie_warning(): sleep(Global.micro_max) script = "var elements=document.getElementsByClassName('cc_container');while(elements.length>0){elements[0].parentNode.removeChild(elements[0]);};" obj.driver.execute_script(script) def get_players(): player_cards = obj.__get_class__('cardetails') sbc_solution_players = [] for card in player_cards: try: sbc_icon = card.find_element_by_class_name( 'sbc-alternatives') if 'display: none' in sbc_icon.get_attribute('style'): card_details = card.find_element_by_class_name( 'pcdisplay') sbc_player_id = card_details.get_attribute( 'data-resource-id') if platform == 'ps': sbc_player_price = card_details.get_attribute( 'data-price-ps3') elif platform == 'pc': sbc_player_price = card_details.get_attribute( 'data-price-pc') else: sbc_player_price = card_details.get_attribute( 'data-price-xbl') sbc_player_price = parse.price_parse(sbc_player_price) if type(sbc_player_price) is not int: sbc_player_price = 0 sbc_solution_players.append({ 'asset_id': sbc_player_id, 'price': sbc_player_price }) except NoSuchElementException: pass return sbc_solution_players if 'pc' in obj.platform: platform = 'pc' elif 'xbox' in obj.platform: platform = 'xbox' else: platform = 'ps' futbin_url = 'https://www.futbin.com/squad-building-challenges' multi_log(obj, 'Getting players from SBC challenges...') obj.driver.get(futbin_url) obj.location = 'futbin' remove_cookie_warning() if only_new: try: sets = obj.__get_class__('round-star-label') except TimeoutException: multi_log(obj, message='No new sets found') obj.__login__() return else: sets = obj.__get_class__('set_name') set_links = [] for sbc in sets: gp = sbc.find_element_by_xpath('../..') set_name = gp.find_element_by_class_name('set_name').text.lower() if 'loan' not in set_name: set_column = gp.find_element_by_xpath('../../..') set_link = set_column.find_element_by_tag_name( 'a').get_attribute('href') set_links.append(set_link) for s_link in set_links: if len(all_players) >= max_players: break obj.new_tab(s_link) chal_links = [] chal_names = obj.__get_class__('chal_name') for chal in chal_names: if len(all_players) >= max_players: break chal_column = chal.find_element_by_xpath('../..') chal_link = chal_column.find_element_by_xpath( ".//*[contains(text(), 'Completed Challenges')]" ).get_attribute('href') chal_links.append(chal_link) for c_link in chal_links: if len(all_players) >= max_players: break obj.new_tab(c_link) remove_cookie_warning() # Get cheapest solution solutions = [] relevant_price = '{}_price'.format(platform) remove_cookie_warning() table = obj.__get_class__('chal_table', as_list=False) for row in table.find_elements_by_xpath('.//tr'): if 'thead_des' != row.get_attribute('class'): data = row.find_elements_by_xpath('.//td') if data: try: solution = { 'ps_price': parse.price_parse(data[5].text), 'xbox_price': parse.price_parse(data[6].text), 'pc_price': parse.price_parse(data[7].text) } if solution[ relevant_price] <= max_price * 11 * 3: solutions.append([ solution, row, data[1].text, int(data[9].text), int(data[10].text) ]) except IndexError: continue if len(solutions) == 0: multi_log(obj, 'No good solutions found. Skipping...', level='warn') else: sorted_solutions = sorted( solutions, key=lambda s: s[0][relevant_price]) for cheap in sorted_solutions[0:solutions_per_challenge + 1]: try: cheap_url = cheap[1].find_element_by_class_name( 'squad_url').get_attribute('href') obj.new_tab(cheap_url) except WebDriverException: break solution_players = get_players() for player in solution_players: if min_price <= player[ 'price'] <= max_price and player[ 'asset_id'] not in all_players and len( all_players) < max_players: all_players.append(player['asset_id']) with open(obj.config_file) as config: new_config = yaml.load(config) new_config['strategy_settings']['sbc_hunt'][ 'players'] = all_players with open(obj.config_file, 'w') as update: yaml.dump(new_config, update) obj.close_tab() obj.close_tab() obj.close_tab() obj.__login__() else: with open(obj.config_file) as config: old_config = yaml.load(config) all_players = old_config['strategy_settings']['sbc_hunt'][ 'players'] multi_log(obj, 'Amassing SBC players...', level='header') total_bids = 0 # Search and bid i = 0 while i < max_iterations: for player in all_players: player_name = info.get_player_info( player, include_futbin_price=False)['name'] hunt_criteria = { 'search_type': 'Players', 'player': player, 'quality': None, 'position': None, 'chem_style': None, 'nation': None, 'league': None, 'club': None, 'min_bin': None, 'include': None, 'exclude': None, } num_bids = common_hunt(obj=obj, name=player_name, hunt_criteria=hunt_criteria, strategy='sbc_hunt', **settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='sbc_hunt') else: total_bids += num_bids i += 1 if total_bids > 0: common_wait_to_expire(obj=obj, strategy='sbc_hunt')
def filter_snipe(obj): obj.current_strategy = 'Filter Snipe' temp_settings = obj.strategy_settings['filter_snipe'] filters = temp_settings['filters'] max_price = temp_settings['max_price'] remove_keys = ['max_price', 'filters'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Filter Sniping...', level='title') for f in filters: multi_log(obj, 'Getting filter data...') futbin_url = create_futbin_url(obj, f) obj.new_tab(futbin_url) obj.location = 'futbin' # Grab all data from tables, hit next page until it can't any more, turn data into list of player dicts all_results = parse_futbin_tables(obj, futbin_url, True, False) multi_log(obj, 'Done getting filter data') obj.close_tab() obj.driver.switch_to.window(obj.driver.window_handles[0]) obj.location = 'home' include = [] max_bin = 999999999999 for result in all_results: if result['price'] != 0 and result['resource_id'] not in f.get( 'exclude', []): include.append(result['resource_id']) if result['price'] < max_bin: max_bin = result['price'] tier = info.get_tier(max_bin) if not settings['use_buy_percent']: search_price = info.round_down( (max_bin * 0.95 * dynamic_profit(obj) * obj.bin_settings[tier]['sell_percent']) - settings['min_profit'], Global.rounding_tiers[tier]) else: search_price = info.round_down( (max_bin * obj.bin_settings[tier]['buy_percent'] * dynamic_profit(obj)), Global.rounding_tiers[tier]) if obj.get_credits( ) > max_bin and search_price <= max_bin <= max_price: try: snipe_criteria = { 'search_type': 'Players', 'player': None, 'quality': f.get('quality', None), 'position': f.get('position', None), 'chem_style': f.get('chem_style', None), 'nation': f.get('nation', None), 'league': f.get('league', None), 'club': f.get('club', None), 'include': include, 'exclude': f.get('exclude', None), } except ValueError: continue name = list(f.values()) common_snipe(obj, name=name, snipe_criteria=snipe_criteria, strategy='filter_snipe', price=max_bin, **settings)
def filter_finder(obj, starting_url, min_price=None, min_players=None, include_zeroes=None, max_multiplier=2, max_spread=3500): obj.current_strategy = 'Filter Finder' settings = obj.strategy_settings['filter_finder'] if not min_price: min_price = settings['min_price'] if not min_players: min_players = settings['min_players'] if not include_zeroes: include_zeroes = settings['include_zeroes'] multi_log(obj, 'Finding Filters...', level='title') def get_futbin_url(filters_list, og_link): def add_to_filter(ft, text): if ft == '- {': ft = ft + text else: ft = ft + ', ' + text return ft if 'pc' in obj.platform: platform = 'pc' elif 'xbox' in obj.platform: platform = 'xbox' else: platform = 'ps' if 'sort' not in og_link: base_url = og_link + '&sort={}_price&order=asc'.format(platform) else: base_url = og_link params = parse_qs(urlsplit(og_link).query) filter_text = '- {' for k, v in params.items(): if 'gold' in v[0].lower(): filter_text = add_to_filter(filter_text, 'quality: Gold') elif 'silver' in v[0].lower(): filter_text = add_to_filter(filter_text, 'quality: Silver') elif 'bronze' in v[0].lower(): filter_text = add_to_filter(filter_text, 'quality: Bronze') elif 'special' in v[0].lower(): filter_text = add_to_filter(filter_text, 'quality: Special') elif k.lower() == 'position': filter_text = add_to_filter( filter_text, 'position: {}'.format(v[0].upper())) elif k.lower() == 'nation': filter_text = add_to_filter( filter_text, 'nation: {}'.format(Global.fifa_nations[v[0]])) elif k.lower() == 'league' and 'club' not in og_link: filter_text = add_to_filter( filter_text, 'league: {}'.format(Global.fifa_leagues[v[0]])) elif k.lower() == 'club': filter_text = add_to_filter( filter_text, 'club: {}'.format(Global.fifa_clubs[v[0]])) for f in filters_list: if f[0] == 'quality' and f[ 1] in available_quality and 'version' not in base_url: base_url = base_url + '&version={}'.format(f[1].lower()) filter_text = add_to_filter(filter_text, 'quality: {}'.format(f[1])) elif f[0] == 'position' and f[ 1] in available_position and 'position' not in base_url: base_url = base_url + '&position={}'.format(f[1]) filter_text = add_to_filter(filter_text, 'position: {}'.format(f[1])) elif f[0] == 'nation' and f[ 1] in available_nation and 'nation' not in base_url: name = get_ea_name_from_id(ea_db='fifa_nations', thing_id=f[1]) base_url = base_url + '&nation={}'.format(f[1]) filter_text = add_to_filter(filter_text, 'nation: {}'.format(name)) elif f[0] == 'league' and f[ 1] in available_league and 'league' not in base_url and 'club' not in base_url: name = get_ea_name_from_id(ea_db='fifa_leagues', thing_id=f[1]) base_url = base_url + '&league={}'.format(f[1]) filter_text = add_to_filter(filter_text, 'league: {}'.format(name)) elif f[0] == 'club' and f[ 1] in available_club and 'club' not in base_url: name = get_ea_name_from_id(ea_db='fifa_clubs', thing_id=f[1]) base_url = base_url + '&club={}'.format(f[1]) filter_text = add_to_filter(filter_text, 'club: {}'.format(name)) filter_text = filter_text + '}' return base_url, filter_text def adjust_prices(price_list): try: return sorted([ p for p in price_list if p <= max_multiplier * min(i for i in price_list if i > 0) or p <= min(i for i in price_list if i > 0) + max_spread ]) except ValueError: return [] # Go to url multi_log(obj, 'Getting player data...') og_url = starting_url if 'sort' not in starting_url: starting_url = starting_url + '&sort=TotalIGS&order=asc' obj.location = 'futbin' # Grab all data from tables, hit next page until it can't any more, turn data into list of player dicts all_results = parse_futbin_tables(obj, starting_url, ignore_untradeable=True, fast=True) if len(all_results) >= min_players: multi_log(obj, 'Analyzing player data...') # Go though list of dicts, put all filters into available_x available_quality = [] available_position = [] available_nation = [] available_league = [] available_club = [] ignore_quality = ['SBC'] for result in all_results: if result.get('quality', None) and result.get( 'quality', None ) not in available_quality and 'version' not in og_url and result[ 'quality'] not in ignore_quality: available_quality.append(result['quality']) if result.get('position', None) and result.get( 'position', None ) not in available_position and 'position' not in og_url: available_position.append(result['position']) if result.get('nation', None) and result.get( 'nation', None) not in available_nation and 'nation' not in og_url: available_nation.append(str(result['nation'])) if result.get('league', None) and result.get( 'league', None ) not in available_league and 'league' not in og_url and 'club' not in og_url: if ( 'version' in og_url and result['league'] != '2118' ) or 'version=all_specials' in og_url or 'version' not in og_url: available_league.append(str(result['league'])) if result.get('club', None) and result.get( 'club', None ) not in available_club and 'club' not in og_url and result.get( 'club', None) != '112658': available_club.append(str(result['club'])) # Arrange into appropriate filter groups singles = [] doubles = [] triples = [] quads = [] # Compare Quality permutations try: for q in available_quality: for p in available_position: for n in available_nation: for l in available_league: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player['position'] == p and player['nation'] == n \ and player['league'] == l: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player['position'] == p and player['nation'] == n \ and player['league'] == l: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: quads.append( ([('quality', q), ('position', p), ('nation', n), ('league', l)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for c in available_club: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player['position'] == p and player['nation'] == n \ and player['club'] == c: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player['position'] == p and player['nation'] == n \ and player['club'] == c: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: quads.append( ([('quality', q), ('position', p), ('nation', n), ('club', c)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'position'] == p and player[ 'nation'] == n: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'position'] == p and player[ 'nation'] == n: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: triples.append( ([('quality', q), ('position', p), ('nation', n)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for l in available_league: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'position'] == p and player[ 'league'] == l: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'position'] == p and player[ 'league'] == l: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: triples.append( ([('quality', q), ('position', p), ('league', l)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for c in available_club: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'position'] == p and player[ 'club'] == c: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'position'] == p and player[ 'club'] == c: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: triples.append( ([('quality', q), ('position', p), ('club', c)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'position'] == p: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'position'] == p: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('quality', q), ('position', p)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for n in available_nation: for l in available_league: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'nation'] == n and player[ 'league'] == l: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'nation'] == n and player[ 'league'] == l: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: triples.append( ([('quality', q), ('nation', n), ('league', l)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for c in available_club: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'nation'] == n and player['club'] == c: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player[ 'nation'] == n and player['club'] == c: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: triples.append( ([('quality', q), ('nation', n), ('club', c)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player['nation'] == n: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player['nation'] == n: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('quality', q), ('nation', n)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for l in available_league: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player['league'] == l: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player['league'] == l: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('quality', q), ('league', l)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for c in available_club: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['quality'] == q and player['club'] == c: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['quality'] == q and player['club'] == c: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('quality', q), ('club', c)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) prices = [] for player in all_results: if player['price'] >= min_price or (include_zeroes and player['price'] == 0): if player['quality'] == q: prices.append(player['price']) elif player['price'] < min_price or (not include_zeroes and player['price'] == 0): if player['quality'] == q: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: singles.append( ([('quality', q)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) # Compare Position permutations for p in available_position: for n in available_nation: for l in available_league: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['position'] == p and player[ 'nation'] == n and player[ 'league'] == l: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['position'] == p and player[ 'nation'] == n and player[ 'league'] == l: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: quads.append( ([('position', p), ('nation', n), ('league', l)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for c in available_club: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['position'] == p and player[ 'nation'] == n and player['club'] == c: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['position'] == p and player[ 'nation'] == n and player['club'] == c: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float( np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: quads.append( ([('position', p), ('nation', n), ('club', c)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) prices = [] for player in all_results: if player['price'] >= min_price or (include_zeroes and player['price'] == 0): if player['position'] == p and player['nation'] == n: prices.append(player['price']) elif player['price'] < min_price or (not include_zeroes and player['price'] == 0): if player['position'] == p and player['nation'] == n: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('position', p), ('nation', n)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for l in available_league: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['position'] == p and player[ 'league'] == l: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['position'] == p and player[ 'league'] == l: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('position', p), ('league', l)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for c in available_club: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['position'] == p and player['club'] == c: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['position'] == p and player['club'] == c: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('position', p), ('club', c)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) prices = [] for player in all_results: if player['price'] >= min_price or (include_zeroes and player['price'] == 0): if player['position'] == p: prices.append(player['price']) elif player['price'] < min_price or (not include_zeroes and player['price'] == 0): if player['position'] == p: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: singles.append( ([('position', p)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) # Compare Nation permutations for n in available_nation: for l in available_league: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['nation'] == n and player['league'] == l: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['nation'] == n and player['league'] == l: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('nation', n), ('league', l)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) for c in available_club: prices = [] for player in all_results: if player['price'] >= min_price or ( include_zeroes and player['price'] == 0): if player['nation'] == n and player['club'] == c: prices.append(player['price']) elif player['price'] < min_price or ( not include_zeroes and player['price'] == 0): if player['nation'] == n and player['club'] == c: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: doubles.append( ([('nation', n), ('club', c)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) prices = [] for player in all_results: if player['price'] >= min_price or (include_zeroes and player['price'] == 0): if player['nation'] == n: prices.append(player['price']) elif player['price'] < min_price or (not include_zeroes and player['price'] == 0): if player['nation'] == n: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: singles.append( ([('nation', n)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) # Compare League for l in available_league: prices = [] for player in all_results: if player['price'] >= min_price or (include_zeroes and player['price'] == 0): if player['league'] == l: prices.append(player['price']) elif player['price'] < min_price or (not include_zeroes and player['price'] == 0): if player['league'] == l: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: singles.append( ([('league', l)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) # Compare Club for c in available_club: prices = [] for player in all_results: if player['price'] >= min_price or (include_zeroes and player['price'] == 0): if player['club'] == c: prices.append(player['price']) elif player['price'] < min_price or (not include_zeroes and player['price'] == 0): if player['club'] == c: prices = [] break prices = adjust_prices(prices) if len(prices) >= min_players: mean, std = int(round(float(np.mean(prices)))), int( round(float(np.std(prices)))) if std < mean: singles.append( ([('club', c)], len(prices), min(i for i in prices if i > 0), mean, std, sorted(prices))) multi_log( obj, 'Done finding filters', notify=True, icon_url= 'https://cdn3.iconfinder.com/data/icons/gray-toolbar-2/512/filter_stock_funnel_filters-128.png' ) print('-' * 100) except KeyError as e: print(e) print(player) # Sort lists by # players singles = sorted(singles, reverse=True, key=lambda x: x[1]) doubles = sorted(doubles, reverse=True, key=lambda x: x[1]) triples = sorted(triples, reverse=True, key=lambda x: x[1]) quads = sorted(quads, reverse=True, key=lambda x: x[1]) def print_filters(name, filters): filter_log = '' print('') print('-' * 100) time = 'TIMESTAMP: {}'.format(datetime.now()) print(time) print(og_url) header = '{}{} Filters{}'.format(Colors.bold, name.title(), Colors.reset) print(header) categories = '{}{!s:<100} {:<11} {:<11} {:<8} {:<8} {:<130} {!s:<100}{}'.format( Colors.bold, 'Filters', '# Players', 'Min Price', 'Avg', 'Std. Dev', 'Prices', 'Futbin Link', Colors.reset) print(categories) filter_log += '-' * 100 + linesep filter_log += time + linesep filter_log += og_url + linesep filter_log += header + linesep filter_log += categories + linesep for x in filters: link, f_text = get_futbin_url(x[0], og_url) output = '{!s:<100} {:<11} {:<11} {:<8} {:<8} {!s:<130} {!s:<100}'.format( f_text, x[1], x[2], x[3], x[4], x[5], link) print(output) filter_log += output + linesep print_filters('single', singles) print_filters('double', doubles) print_filters('triple', triples) print_filters('quadruple', quads) obj.close_tab()
def coin_transfer_prep(obj, amount): def add_player(player_to_search): rating = None quality = 'Special' search_panel = obj.__get_class__('ClubSearchFilters', as_list=False) sleep(Global.micro_min / 2) name_list = [] if type(player_to_search) is int or (type(player_to_search) is str and any(n in player_to_search for n in '1234567890')): have_id = True if int(player_to_search) >= 300000: quality = 'Special' try: db_player = Global.fifa_players[player_to_search] except KeyError: try: player_to_search = info.get_base_id(player_to_search) db_player = Global.fifa_players[player_to_search] except KeyError: multi_log( obj, 'No player with id {} in fifa_players.json, Unable to find player' .format(player_to_search), level='error') return 'no_name' name_list = [ db_player['first_name'], db_player['last_name'], db_player['surname'] ] temp_names = [] for name in name_list: if name: temp_names.append(name) name_list = temp_names if len(name_list) == 3: name_list = [ name_list[2], name_list[0] + ' ' + name_list[1], name_list[0] + ' ' + name_list[2], name_list[1] + ' ' + name_list[2], name_list[1] + ' ' + name_list[0], name_list[1], name_list[2] + ' ' + name_list[0], name_list[2] + ' ' + name_list[1], name_list[0] ] elif len(name_list) == 2: name_list = [ name_list[0] + ' ' + name_list[1], name_list[1] + ' ' + name_list[0], name_list[1], name_list[0] ] if not rating and int(player_to_search) < 300000: try: rating = Global.fifa_players[player_to_search]['rating'] except KeyError: pass else: have_id = False name = player_to_search.title() name_list.append(name) name_found = False while not name_found: if not name_list: multi_log( obj, message='Unable to find {}.'.format(player_to_search)) return [] name = name_list[0] name_box = search_panel.find_element_by_class_name('textInput') obj.__type_element__(name_box, name) name_parent = name_box.find_element_by_xpath('..') sleep(Global.micro_max) result_list = name_parent.find_element_by_tag_name('ul') results = result_list.find_elements_by_class_name('btn-text') if not results: if len(name_list) <= 1: multi_log(obj, 'Unable to find results for {}'.format( player_to_search), level='warn', notify=True, title='Search Error') return [] else: og_name = name new_name = name_list[1] multi_log(obj, '\"{}\" not found. Trying \"{}\"'.format( og_name, new_name), level='debug') search_panel = obj.__get_class__('ClubSearchFilters', as_list=False) name_list = name_list[1:] else: for r in results: if have_id: if rating and len(results) > 1: result_parent = r.find_element_by_xpath('..') result_rating = result_parent.find_element_by_class_name( 'btn-subtext').text if str(rating) == str(result_rating): obj.__click_element__(r) name_found = True break else: try: obj.__click_element__(r) name_found = True break except StaleElementReferenceException: return [] else: if name.lower() in parse.remove_accents( r.text).lower(): if rating and len(results) > 1: result_parent = r.find_element_by_xpath('..') result_rating = result_parent.find_element_by_class_name( 'btn-subtext').text if str(rating) == str(result_rating): obj.__click_element__(r) name_found = True break else: obj.__click_element__(r) name_found = True break if not name_found: name_list = name_list[1:] if quality is not None: quality = quality.title() quality_dropdown = search_panel.find_element_by_xpath( ".//*[contains(text(), 'Quality')]") obj.__click_element__(quality_dropdown) sleep(5) quality_parent = quality_dropdown.find_element_by_xpath('..') obj.__check_for_errors__() quality_parent.find_element_by_xpath( ".//*[contains(text(), '{}')]".format(quality)).click() else: try: obj.__click_element__( search_panel.find_element_by_xpath( './/div[3]/div[2]/div[3]/div/a') ) # Remove quality filter except ElementNotVisibleException: pass obj.__click_element__( search_panel.find_element_by_xpath( './/div[3]/div[2]/div[4]/div/a')) # Remove position filter obj.__click_element__( search_panel.find_element_by_xpath( ".//*[contains(text(), 'Search')]")) sleep(Global.small_min) results = obj.__get_class__('MyClubResults', as_list=False) if not results: multi_log( obj, 'Missing {} for SBC solution'.format( info.get_player_info(player_to_search, False)['name'])) return False try: results.find_element_by_class_name('has-action').click() obj.__click_xpath__(".//*[contains(text(), 'Swap Player')]") return True except (TimeoutException, ElementNotVisibleException, NoSuchElementException): pass multi_log( obj, 'Missing {} for coin transfer'.format( info.get_player_info(player_to_search, False)['name'])) return False multi_log(obj, 'Prepping for Coin Transfer...', level='title') # Get cheap gold IFs that aren't 0 multi_log(obj, 'Finding best players to purchase for coin transfer...') if 'pc' in obj.platform: platform = 'pc' elif 'xbox' in obj.platform: platform = 'xbox' else: platform = 'ps' futbin_url = 'https://www.futbin.com/18/players?page=1&version=if_gold&sort={}_price&order=asc'.format( platform) all_results = [] # Get enough players to reach amount players_needed = ceil(amount / 35000) obj.new_tab(futbin_url) obj.location = 'futbin' results = parse_futbin_players_table(obj, futbin_url, all_results)[0:players_needed - 1] obj.close_tab() obj.driver.switch_to.window(obj.driver.window_handles[0]) obj.location = 'home' multi_log(obj, 'Done finding players. Acquiring...') players_needed = [] for player in results: if int(player['asset_id']) < 300000: special_ids = list(get_special_ids(player['asset_id']).values()) good_ids = [int(i) for i in special_ids if int(i) > 300000] player['asset_id'] = str(min(good_ids)) players_needed.append(player['asset_id']) # Acquire players result = obj.acquire(players_needed, 1, False, special_only=True) if result == 'done': # Put players into a squad multi_log(obj, 'Putting players into squad...') obj.go_to('squads') obj.__click_xpath__("//*[contains(text(), 'Squad Management')]") obj.location = 'squad_management' squads = obj.__get_class__('listFUTSquad', as_list=True) squad_exists = False for squad in squads: if squad.find_element_by_tag_name( 'h1').text.lower() == 'ignore me': obj.__click_element__(squad) sleep(Global.micro_max) side_panel = obj.__get_class__('squadDetailView', as_list=False) side_panel.find_element_by_xpath( "//*[contains(text(), 'Open')]").click() squad_exists = True break if not squad_exists: obj.__click_xpath__("//*[contains(text(), 'Create New Squad')]") text_box = obj.__get_class__('textInput', as_list=False) obj.__type_element__(text_box, 'Ignore Me') obj.__click_xpath__("//*[contains(text(), 'Create')]") sleep(Global.micro_max) players_added = 0 ignore = [] while True and players_added < len(players_needed): all_full = True squad_pitch = obj.__get_class__('squadPitch', as_list=False) squad_slots = squad_pitch.find_elements_by_class_name('squadSlot') for slot in reversed(squad_slots): index = slot.get_attribute('index') try: if 'locked' not in slot.get_attribute( 'class' ) and 'empty' in slot.find_element_by_class_name( 'player').get_attribute( 'class') and index not in ignore: all_full = False slot.click() sleep(Global.micro_min) panel = obj.__get_class__('ui-layout-right', as_list=False) obj.__click_element__( panel.find_element_by_xpath( "//*[contains(text(), 'Add Player')]")) sleep(Global.micro_min) add_result = add_player(players_needed[players_added]) players_added += 1 if not add_result or add_result == 'no_name': ignore.append(index) break except NoSuchElementException: pass if all_full: break multi_log( obj, 'Done adding players to squad. Play a game with them before selling (less risky)' )
def add_player(player_to_search): rating = None quality = 'Special' search_panel = obj.__get_class__('ClubSearchFilters', as_list=False) sleep(Global.micro_min / 2) name_list = [] if type(player_to_search) is int or (type(player_to_search) is str and any(n in player_to_search for n in '1234567890')): have_id = True if int(player_to_search) >= 300000: quality = 'Special' try: db_player = Global.fifa_players[player_to_search] except KeyError: try: player_to_search = info.get_base_id(player_to_search) db_player = Global.fifa_players[player_to_search] except KeyError: multi_log( obj, 'No player with id {} in fifa_players.json, Unable to find player' .format(player_to_search), level='error') return 'no_name' name_list = [ db_player['first_name'], db_player['last_name'], db_player['surname'] ] temp_names = [] for name in name_list: if name: temp_names.append(name) name_list = temp_names if len(name_list) == 3: name_list = [ name_list[2], name_list[0] + ' ' + name_list[1], name_list[0] + ' ' + name_list[2], name_list[1] + ' ' + name_list[2], name_list[1] + ' ' + name_list[0], name_list[1], name_list[2] + ' ' + name_list[0], name_list[2] + ' ' + name_list[1], name_list[0] ] elif len(name_list) == 2: name_list = [ name_list[0] + ' ' + name_list[1], name_list[1] + ' ' + name_list[0], name_list[1], name_list[0] ] if not rating and int(player_to_search) < 300000: try: rating = Global.fifa_players[player_to_search]['rating'] except KeyError: pass else: have_id = False name = player_to_search.title() name_list.append(name) name_found = False while not name_found: if not name_list: multi_log( obj, message='Unable to find {}.'.format(player_to_search)) return [] name = name_list[0] name_box = search_panel.find_element_by_class_name('textInput') obj.__type_element__(name_box, name) name_parent = name_box.find_element_by_xpath('..') sleep(Global.micro_max) result_list = name_parent.find_element_by_tag_name('ul') results = result_list.find_elements_by_class_name('btn-text') if not results: if len(name_list) <= 1: multi_log(obj, 'Unable to find results for {}'.format( player_to_search), level='warn', notify=True, title='Search Error') return [] else: og_name = name new_name = name_list[1] multi_log(obj, '\"{}\" not found. Trying \"{}\"'.format( og_name, new_name), level='debug') search_panel = obj.__get_class__('ClubSearchFilters', as_list=False) name_list = name_list[1:] else: for r in results: if have_id: if rating and len(results) > 1: result_parent = r.find_element_by_xpath('..') result_rating = result_parent.find_element_by_class_name( 'btn-subtext').text if str(rating) == str(result_rating): obj.__click_element__(r) name_found = True break else: try: obj.__click_element__(r) name_found = True break except StaleElementReferenceException: return [] else: if name.lower() in parse.remove_accents( r.text).lower(): if rating and len(results) > 1: result_parent = r.find_element_by_xpath('..') result_rating = result_parent.find_element_by_class_name( 'btn-subtext').text if str(rating) == str(result_rating): obj.__click_element__(r) name_found = True break else: obj.__click_element__(r) name_found = True break if not name_found: name_list = name_list[1:] if quality is not None: quality = quality.title() quality_dropdown = search_panel.find_element_by_xpath( ".//*[contains(text(), 'Quality')]") obj.__click_element__(quality_dropdown) sleep(5) quality_parent = quality_dropdown.find_element_by_xpath('..') obj.__check_for_errors__() quality_parent.find_element_by_xpath( ".//*[contains(text(), '{}')]".format(quality)).click() else: try: obj.__click_element__( search_panel.find_element_by_xpath( './/div[3]/div[2]/div[3]/div/a') ) # Remove quality filter except ElementNotVisibleException: pass obj.__click_element__( search_panel.find_element_by_xpath( './/div[3]/div[2]/div[4]/div/a')) # Remove position filter obj.__click_element__( search_panel.find_element_by_xpath( ".//*[contains(text(), 'Search')]")) sleep(Global.small_min) results = obj.__get_class__('MyClubResults', as_list=False) if not results: multi_log( obj, 'Missing {} for SBC solution'.format( info.get_player_info(player_to_search, False)['name'])) return False try: results.find_element_by_class_name('has-action').click() obj.__click_xpath__(".//*[contains(text(), 'Swap Player')]") return True except (TimeoutException, ElementNotVisibleException, NoSuchElementException): pass multi_log( obj, 'Missing {} for coin transfer'.format( info.get_player_info(player_to_search, False)['name'])) return False
def filter_amass(obj): obj.current_strategy = 'Filter Amass' temp_settings = obj.strategy_settings['filter_amass'] filters = temp_settings['filters'] max_price = temp_settings['max_price'] remove_keys = ['filters', 'max_price'] settings = {k: v for k, v in temp_settings.items() if k not in remove_keys} multi_log(obj, 'Filter amassing players...', level='title') total_bids = 0 # Search and bid for f in filters: multi_log(obj, 'Getting filter data...') futbin_url = create_futbin_url(obj, f) obj.new_tab(futbin_url) obj.location = 'futbin' max_price = f.get('max_price', max_price) # Grab all data from tables, hit next page until it can't any more, turn data into list of player dicts all_results = parse_futbin_tables(obj, futbin_url, True, False) multi_log(obj, 'Done getting filter data') obj.close_tab() obj.driver.switch_to.window(obj.driver.window_handles[0]) obj.location = 'home' prices = [] include = [] for result in all_results: if result['price'] != 0 and result['resource_id'] not in f.get( 'exclude', []): include.append(result['resource_id']) prices.append(result['price']) filter_name = list(f.values()) if not prices: prices = [0] if max_price and max_price > 0: max_buy = min(max_price, max(prices)) else: max_buy = max(prices) try: hunt_criteria = { 'search_type': 'Players', 'player': None, 'quality': f.get('quality', None), 'position': f.get('position', None), 'chem_style': f.get('chem_style', None), 'nation': f.get('nation', None), 'league': f.get('league', None), 'club': f.get('club', None), 'max_buy': max_buy, 'include': include, 'exclude': f.get('exclude', None), } except ValueError: continue num_bids = common_hunt(obj=obj, name=filter_name, hunt_criteria=hunt_criteria, strategy='filter_amass', **settings) if num_bids == 'limit': common_wait_to_expire(obj=obj, strategy='filter_amass') else: total_bids += num_bids if total_bids > 0: common_wait_to_expire(obj=obj, strategy='filter_amass')
def check_transfer_targets(): if obj.location != 'transfer_targets': obj.go_to('transfer_targets') multi_log(obj, 'Waiting on last bid to expire') while True: max_expire = 0 watched_items = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Watched Items')]", gp_type='xpath', get_price=False) if len(watched_items) == 0: break for item in watched_items: if item['time_left'] > max_expire: max_expire = item['time_left'] obj.keep_alive(max_expire + 5) expired_bids = obj.__get_items__( p_element='../..', p_type='xpath', gp_element="//*[contains(text(), 'Expired Items')]", gp_type='xpath', get_price=False) expired = {} for expired_bid in expired_bids: if expired_bid['asset_id'] not in list(expired.keys()): expired[expired_bid['asset_id']] = { 'bid_amounts': 0, 'num_results': 0 } expired[expired_bid['asset_id']]['bid_amounts'] += expired_bid[ 'current_bid'] expired[expired_bid['asset_id']]['num_results'] += 1 return_players = [] for asset, data in expired.items(): futbin_price = info.get_price(asset) tier = info.get_tier(futbin_price) rounding = Global.rounding_tiers[tier] average_bid = info.round_down( data['bid_amounts'] / data['num_results'], rounding) coins_from_sale = futbin_price * 0.95 potential_profit = coins_from_sale - average_bid if settings[ 'use_buy_percent'] and potential_profit >= coins_from_sale - ( futbin_price * obj.bin_settings['buy_percent']): return_players.append({ 'asset_id': asset, 'name': info.get_player_info(asset, False)['name'], 'bid': average_bid, 'futbin': futbin_price }) elif potential_profit >= settings['min_profit']: return_players.append({ 'asset_id': asset, 'name': info.get_player_info(asset, False)['name'], 'bid': average_bid, 'futbin': futbin_price }) for player_data in return_players: name = info.get_player_info(player_data['asset_id'], False)['name'] multi_log( obj, '{}\'s Average Bid: {} | Futbin price: {}'.format( name, player_data['bid'], player_data['futbin'])) obj.clear_expired() return return_players