Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

features and improvements #12

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.idea
chrome-user-data-dir
*.pyc
*.DS_Store
__pycache__
245 changes: 156 additions & 89 deletions src/bot.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
from time import sleep
import platform
import atexit
import random
import enum

from selenium.common.exceptions import TimeoutException, WebDriverException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from src.config import URL
from src.config import create_driver, INCREASE_COUNT
from src.config import URL, USE_CHROME_PROFILE, START_MAXIMIZED, INCREASE_COUNT
from src.email_manager import get_access_code
from src.helpers import wait_for_shield_invisibility

from src.helpers import wait_for_shield_invisibility, create_driver

class Bot:
def __init__(self):
self.driver = create_driver()
self.system = platform.system()
self.driver = create_driver(self.system, URL, USE_CHROME_PROFILE, START_MAXIMIZED)
self.action = ActionChains(self.driver)
self.driver.get(URL)

atexit.register(self.cleanup)
print("Starting sniping bot...")

def cleanup(self):
print("Running cleanup...")
self.quit()

def quit(self):
#self.driver.quit()
pass

def go_to_login_page(self):
WebDriverWait(self.driver, 15).until(
EC.visibility_of_element_located((By.XPATH, '//*[@class="ut-login-content"]//button'))
Expand All @@ -43,7 +56,6 @@ def login(self, user):
).click()

access_code = get_access_code()

self.driver.find_element(By.ID, 'oneTimeCode').send_keys(access_code)
self.driver.find_element(By.ID, 'btnSubmit').click()

Expand All @@ -56,119 +68,174 @@ def login_manually(self):
self.go_to_login_page()

print("Enter your account credentials and click login button.")
print("Waiting 5 minutes...")
print("Waiting max. 5 minutes...")

WebDriverWait(self.driver, 300).until(
EC.element_to_be_clickable((By.ID, 'btnSendCode'))
).click()

print("Provide EA access code and click submit button.")
print("Waiting 5 minutes...")
print("Waiting max. 5 minutes...")

WebDriverWait(self.driver, 300).until(
EC.visibility_of_element_located((By.CLASS_NAME, 'icon-transfer'))
)
sleep(2)

def go_to_transfer_market(self):
def wait_for_login(self):
print("Waiting max. 5 minutes for Login...")
WebDriverWait(self.driver, 300).until(
EC.visibility_of_element_located((By.CLASS_NAME, 'icon-transfer'))
)
sleep(2)

def get_coins(self):
return int(
self.driver.find_element(By.CLASS_NAME, 'view-navbar-currency-coins').text
.replace(" ", "")
.replace(".", "")
.replace(",", "")
)

def go_to_transfer_market_search(self):
self.driver.find_element(By.CLASS_NAME, 'icon-transfer').click()

# wait until loaded - transfer market
WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located((By.CLASS_NAME, 'ut-tile-transfer-market'))
)
sleep(1)
sleep(random.randint(3, 9)/10)
self.driver.find_element(By.CLASS_NAME, 'ut-tile-transfer-market').click()

def search_player(self, player, max_price):
count = 1
success_count = 0
coins = self.driver.find_element(By.CLASS_NAME, 'view-navbar-currency-coins').text.replace(" ", "")
print("Number of coins: " + coins)

while int(coins) >= max_price and success_count < 5:
if count % INCREASE_COUNT == 0:
min_price_input = self.driver.find_element(By.XPATH, '(//input[contains(@class, "numericInput")])[3]')
min_price_input.click()
sleep(0.05)
min_price_input.send_keys(0)

self.driver.find_element(By.XPATH, '(//*[@class="button-container"]/button)[2]').click()
result = WebDriverWait(self.driver, 10).until(lambda d: d.find_elements(By.CLASS_NAME, 'no-results-icon') or
d.find_elements(By.CLASS_NAME, 'DetailView'))[0]

if "DetailView" in result.get_attribute("class"):
coins = self.driver.find_element(By.CLASS_NAME, 'view-navbar-currency-coins').text.replace(" ", "")

try:
self.driver.find_element(By.XPATH, '//button[contains(@class, "buyButton")]').click()
except WebDriverException:
wait_for_shield_invisibility(self.driver, 0.1)
self.driver.find_element(By.XPATH, '//button[contains(@class, "buyButton")]').click()

self.driver.find_element(By.XPATH, '//div[contains(@class,"view-modal-container")]//button').click()

sleep(0.5)

new_coins = self.driver.find_element(By.CLASS_NAME, 'view-navbar-currency-coins').text.replace(" ", "")

if int(coins) == int(new_coins):
print("Found something, but it was too late.")
else:
price = int(coins) - int(new_coins)
print("Success! You bought " + player + " for " + str(price) + " coins.")
coins = new_coins
success_count += 1

try:
self.driver.find_element(By.XPATH, '//button[contains(@class, "ut-navigation-button-control")]').click()
except WebDriverException:
wait_for_shield_invisibility(self.driver, 0.1)
self.driver.find_element(By.XPATH, '//button[contains(@class, "ut-navigation-button-control")]').click()
# wait until loaded - transfer market search
WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located((By.CLASS_NAME, 'ut-player-search-control'))
)
wait_for_shield_invisibility(self.driver)
sleep(random.randint(3, 9)/10)

inc_max_price_button = self.driver.find_element(By.XPATH, '(//div[@class="price-filter"]//button)[6]')
def fill_transfer_market_search(self, player, max_price):
# set player name
self.driver.find_element(By.XPATH, '//div[contains(@class, "ut-player-search-control")]//input').click()
sleep(random.randint(3, 9)/10)
self.driver.find_element(By.XPATH, '//div[contains(@class, "ut-player-search-control")]//input').send_keys(player)

WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '(//div[@class="price-filter"]//button)[6]'))
)
# select player in dropdown
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.XPATH, '//ul[contains(@class, "playerResultsList")]/button'))
)
sleep(random.randint(3, 9)/10)
self.driver.find_element(By.XPATH, '//ul[contains(@class, "playerResultsList")]/button').click()

# set max buy price
self.driver.find_element(By.XPATH, '(//input[@class="numericInput"])[4]').click()
sleep(random.randint(3, 9)/10)
self.driver.find_element(By.XPATH, '(//input[@class="numericInput"])[4]').send_keys(max_price)
sleep(random.randint(3, 9)/10)

def begin_transfer_market_search(self):
sleep(random.randint(3, 9)/10)
self.driver.find_element(By.XPATH, '(//*[@class="button-container"]/button)[2]').click()
#WebDriverWait(self.driver, 10).until(lambda d: d.find_elements(By.CLASS_NAME, 'no-results-icon') or
# d.find_elements(By.CLASS_NAME, 'DetailView'))[0]

def end_transfer_market_search(self):
sleep(random.randint(3, 9)/10)
try:
self.driver.find_element(By.XPATH, '//button[contains(@class, "ut-navigation-button-control")]').click()
except WebDriverException:
wait_for_shield_invisibility(self.driver, 0.1)
self.driver.find_element(By.XPATH, '//button[contains(@class, "ut-navigation-button-control")]').click()

wait_for_shield_invisibility(self.driver)
def increase_instant_buy_min_price(self):
sleep(random.randint(3, 9)/10)
WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '(//div[@class="price-filter"]//button)[6]'))
)
wait_for_shield_invisibility(self.driver)
sleep(random.randint(3, 9)/10)
self.driver.find_element(By.XPATH, '(//div[@class="price-filter"]//button)[6]').click()

inc_max_price_button.click()
def reset_instant_buy_min_price(self, count):
sleep(random.randint(3, 9)/10)
min_price_input = self.driver.find_element(By.XPATH, '(//input[contains(@class, "numericInput")])[3]')
min_price_input.click()
for x in range(4):
min_price_input.send_keys("\u0008")
self.driver.find_element(By.XPATH, '(//div[@class="price-filter"]//button)[6]').click()

count += 1
def buy_player(self, player):
coins = self.get_coins()

if success_count == 5:
print("You bought 5 players. Assign them and rerun the bot.")
try:
self.driver.find_element(By.XPATH, '//button[contains(@class, "buyButton")]').click()
except WebDriverException:
wait_for_shield_invisibility(self.driver, 0.1)
self.driver.find_element(By.XPATH, '//button[contains(@class, "buyButton")]').click()

self.driver.find_element(By.XPATH, '//div[contains(@class,"view-modal-container")]//button').click()
sleep(random.randint(1, 5))

new_coins = self.get_coins()
if coins == new_coins:
print("Found something, but it was too late.")
return 0
else:
print("You have no coins for more players.")
price = coins - new_coins
print("Success! You bought " + player + " for " + str(price) + " coins. Remaining coins: " + str(new_coins))
return price

def try_buy_player(self, player, expected_player_rating):
element = WebDriverWait(self.driver, 10).until(lambda d: d.find_elements(By.CLASS_NAME, 'no-results-icon') or
d.find_elements(By.CLASS_NAME, 'DetailView'))[0]
if "DetailView" in element.get_attribute("class"):
if expected_player_rating is None:
return self.buy_player(player)
else:
player_rating = int(self.driver.find_element(By.XPATH, "//div[contains(@class, 'tns-slide-active')]//div[@class='rating']").text)
if player_rating == expected_player_rating:
return self.buy_player(player)
else:
print("Found something, but rating (" + str(player_rating) + ") is not as expected (" + str(expected_player_rating) + ").")
return self.buy_player(player)
return 0

def buy_player(self, player, max_price):
def buy_players(self, player, player_rating, max_price, max_player_count):
try:
self.go_to_transfer_market()

WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located((By.CLASS_NAME, 'ut-player-search-control'))
)
wait_for_shield_invisibility(self.driver)

self.driver.find_element(By.XPATH, '//div[contains(@class, "ut-player-search-control")]//input').click()
sleep(0.1)
self.driver.find_element(By.XPATH, '//div[contains(@class, "ut-player-search-control")]//input').send_keys(player)

WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.XPATH, '//ul[contains(@class, "playerResultsList")]/button'))
)
sleep(1)

self.driver.find_element(By.XPATH, '//ul[contains(@class, "playerResultsList")]/button').click()
self.go_to_transfer_market_search()
sleep(random.randint(3, 9)/10)
self.fill_transfer_market_search(player, max_price)
sleep(random.randint(3, 9)/10)

# begin
count = 0
success_count = 0
coins = self.get_coins()
print("Number of available coins: " + str(coins))
print("Looking for " + player + " for max price " + str(max_price) + " coins...")

while coins >= max_price and success_count < max_player_count:
# Buy a player when result appears
self.begin_transfer_market_search()
price = self.try_buy_player(player, player_rating)
if price > 0:
coins = self.get_coins()
success_count += 1
self.end_transfer_market_search()

self.driver.find_element(By.XPATH, '(//input[@class="numericInput"])[4]').click()
sleep(0.1)
self.driver.find_element(By.XPATH, '(//input[@class="numericInput"])[4]').send_keys(max_price)
if count % INCREASE_COUNT == 0:
self.reset_instant_buy_min_price(count)
count = 0
else:
self.increase_instant_buy_min_price()

print("Looking for " + player + " with max price " + str(max_price) + "...")
count += 1
sleep(random.randint(3, 9)/10)

self.search_player(player, max_price)
if success_count >= max_player_count:
print("You bought " + str(success_count) + " players. Assign them and rerun the bot.")
elif coins < max_price:
print("You have not enought coins for more players.")

except TimeoutException:
print("Error, check the browser")
45 changes: 9 additions & 36 deletions src/config.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,24 @@
from selenium import webdriver
import platform
import os


def create_driver():
system = platform.system()

if system == 'Darwin':
path = 'chrome_mac/chromedriver'
elif system == 'Linux':
path = 'chrome_linux/chromedriver'
elif system == 'Windows':
path = os.getcwd() + '\chrome_windows\chromedriver.exe'
else:
raise OSError(f'Operating system {system} is not supported')

driver = webdriver.Chrome(
executable_path=path
)
driver.maximize_window()

return driver


URL = "https://www.ea.com/pl-pl/fifa/ultimate-team/web-app/"

EA_EMAIL = "EA@e.ea.com"

PLAYER = {
"name": "Kloster",
"rating": None,
"cost": 15000,
}
MAX_PLAYER = 15
INCREASE_COUNT = 5

INCREASE_COUNT = 20

# Credentials should be filled if LOGIN_MANUALLY is False
# and USE_CHROME_PROFILE is False
LOGIN_MANUALLY = True

# Credentials - fill in if LOGIN_MANUALLY is False

USE_CHROME_PROFILE = True
START_MAXIMIZED = False
USER = {
"email": "your_email@example.com",
"email": "your_email@gmail.com",
"password": "your_password",
}

EMAIL_CREDENTIALS = {
"email": "your_email@example.com",
"email": "your_email@gmail.com",
"password": "your_password",
}


Loading