MsRewards/V6.py

1035 lines
38 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/python3
import random
import subprocess
from modules.Classes.Config import Config
2024-02-27 15:05:19 +01:00
from modules.Classes.DiscordLogger import DiscordLogger
from modules.Classes.UserCredentials import UserCredentials
2024-04-26 14:00:33 +02:00
from modules.Tools.logger import critical, warning
2024-02-27 15:05:19 +01:00
from modules.cards import *
from modules.config import *
from modules.db import add_to_database
from modules.driver_tools import *
from modules.error import *
# create a webdriver
def create_driver(mobile=False):
2024-02-28 00:14:42 +01:00
pc_user_agent = (
"Mozilla/5.0 (X11; Linux x86_64)"
"AppleWebKit/537.36 (KHTML, like Gecko)"
"Chrome/122.0.0.0 Safari/537.36 Edg/122.0.2088.46"
)
2024-02-28 00:14:42 +01:00
mobile_user_agent = (
"Mozilla/5.0 (Linux; Android 7.0; Nexus 5 Build/MRA58N)"
"AppleWebKit/537.36 (KHTML, like Gecko)"
"Chrome/22 Mobile Safari/537.36"
)
chrome_profile_dir = init_profile(config.UserCredentials.get_mail(), mobile=mobile)
# Full list on https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md
arguments = [
"--no-first-run",
"--ash-no-nudges",
"--no-default-browser-check",
2024-04-08 16:51:43 +02:00
"--disable-features=PrivacySandboxSettings4,Translate",
"--disable-search-engine-choice-screen",
f"--user-data-dir={chrome_profile_dir}/"
]
if mobile:
arguments.append(f"--user-agent={mobile_user_agent}")
else:
arguments.append(f"--user-agent={pc_user_agent}")
# disabled as it may cause detection
2024-02-27 15:05:19 +01:00
if config.proxy.is_enabled():
arguments.append(f'--proxy-server={config.proxy.ip}:{config.proxy.port}')
chrome_options = webdriver.ChromeOptions()
for arg in arguments:
chrome_options.add_argument(arg)
driver = uc.Chrome(options=chrome_options)
return driver
# close the tab currently on and go back to the one first, or the one specified
def close_tab(tab, switch_to: int = 0) -> None:
driver = config.WebDriver.driver
driver.switch_to.window(tab)
driver.close()
driver.switch_to.window(driver.window_handles[switch_to])
# play_quiz[N]([int : override]) make the quiz with N choice each time. They usually have between 4 and 10 questions.
# override is the number of question, by default, it's the number of question in this specific quiz.
# Can be useful in some case, where the program crashes before finishing the quiz
def play_quiz2(override=10) -> None:
info("Starting to play quiz 2.")
driver = config.WebDriver.driver
debug(f"override: {override}")
for j in range(override):
custom_sleep(uniform(3, 5))
js_function = """
function get_correct_answer(){
2024-02-28 11:10:48 +01:00
function br(n) {
for (var r, t = 0, i = 0; i < n.length; i++)
t += n.charCodeAt(i);
return r = parseInt(_G.IG.substr(_G.IG.length - 2), 16), t += r, t.toString()
} // Ms check function
function namedRAValue() { //allow calls to getRAValue
return _w.getRAValue()
};
if (br(document.getElementById("rqAnswerOption0").attributes["data-option"].value) == namedRAValue()){
return(0);
}
else {
return(1);
}
};
return(get_correct_answer())
"""
correct_answer_value = driver.execute_script(js_function)
try:
answer_elem = driver.find_element(By.ID, f"rqAnswerOption{correct_answer_value}")
answer_elem.click()
except exceptions.ElementNotInteractableException:
answer_elem = driver.find_element(By.ID, f"rqAnswerOption{correct_answer_value}")
driver.execute_script("arguments[0].click();", answer_elem)
except Exception as e:
log_error(e)
break
info("Quiz 2 done.")
custom_sleep(3)
def play_quiz8():
driver = config.WebDriver.driver
info(f"Starting Quiz 8")
override = len(findall("<span id=\"rqQuestionState.\" class=\"emptyCircle\"></span>", driver.page_source)) + 1
debug(f"override : {override}")
correct_answers = ["Should", "be", "reset", "before", "you", "see", "this."] # supress warning
try:
for _ in range(override):
sleep(uniform(3, 5))
correct_answers = []
2024-02-28 00:14:42 +01:00
for i in range(8):
try:
2024-02-28 00:14:42 +01:00
element = driver.find_element(By.ID, f"rqAnswerOption{i}")
if 'iscorrectoption="True"' in element.get_attribute("outerHTML"):
2024-02-28 00:14:42 +01:00
correct_answers.append(f'rqAnswerOption{i}')
except Exception as e:
2024-02-28 00:14:42 +01:00
warning(f"can't find rqAnswerOption{i}. Probably already clicked" + str(e))
shuffle(correct_answers)
for answer_id in correct_answers:
wait_until_visible(By.ID, answer_id, timeout=20, browser=driver)
try:
answer_elem = driver.find_element(By.ID, answer_id)
answer_elem.click()
sleep(1)
except exceptions.NoSuchElementException:
driver.refresh()
sleep(10)
answer_elem = driver.find_element(By.ID, answer_id)
answer_elem.click()
except ElementClickInterceptedException:
2024-02-27 16:21:08 +01:00
rgpd_popup(config)
correct_answers.append(answer_id)
except Exception as e:
log_error(f"{format_error(e)} \n Good answers : {' '.join(correct_answers)}")
2024-02-27 16:21:08 +01:00
raise ValueError(format_error(e))
info("Quiz 8 done.")
custom_sleep(3)
def play_quiz4(override: int = None):
info(f"Starting Quiz 4")
driver = config.WebDriver.driver
if not override:
try: # fidelity quiz are much longer than usual ones
override = int(findall('rqQuestionState([\d]{1,2})"', driver.page_source)[-1])
2024-02-27 15:05:19 +01:00
except Exception as err:
debug(err)
override = 3
debug(f"Override : {override}")
try:
for i in range(override):
custom_sleep(uniform(3, 5))
txt = driver.page_source
answer_option = search('correctAnswer":"([^"]+)', txt)[1]
answer_option = answer_option.replace("\\u0027", "'") # replace Unicode weird symbols
answer_element = driver.find_element(By.CSS_SELECTOR, f'[data-option="{answer_option}"]')
try:
answer_element.click()
except exceptions.ElementNotInteractableException:
driver.execute_script("arguments[0].click();", answer_element)
except Exception as e:
log_error(e)
raise ValueError(e)
2024-03-01 17:29:15 +01:00
info("Quiz 4 done.")
custom_sleep(3)
# do_poll() answer a random thing to poll, on of daily activities
def do_poll():
info("Starting poll")
driver = config.WebDriver.driver
try:
answer_elem = driver.find_element(By.ID, f"btoption{choice([0, 1])}")
try:
answer_elem.click()
except exceptions.ElementNotInteractableException:
2024-02-28 18:22:15 +01:00
warning("element not clickable. Waiting a bit and retrying.")
custom_sleep(uniform(2, 2.5))
driver.execute_script("arguments[0].click();", answer_elem)
custom_sleep(uniform(2, 2.5))
except Exception as err:
log_error(err)
raise ValueError(err)
info("Poll done.")
custom_sleep(3)
# Find each playable card and tries to click on it to earn points
def all_cards():
driver = config.WebDriver.driver
2024-08-30 21:48:20 +02:00
def check_popups() -> bool:
"""
Check various annoying popups
"""
def check_welcome_tour() -> bool:
if "rewards.bing.com/welcometour" not in driver.current_url:
return False
2024-04-12 23:46:26 +02:00
2024-08-30 21:48:20 +02:00
info("Popup 'Explorer le programme' reçue")
wait_until_visible(By.ID, "welcome-tour", timeout=5, browser=driver)
custom_sleep(1.5)
2024-04-13 10:15:26 +02:00
2024-08-30 21:48:20 +02:00
welcome_tour = driver.find_element(By.ID, "welcome-tour")
interest_button_box = welcome_tour.find_element(By.CLASS_NAME, "interest-buttons")
interests = interest_button_box.find_elements(By.CLASS_NAME, "ng-binding")
debug("Got the following interests: " + str(interests))
random.choice(interests).click() # Choose interest
custom_sleep(1.5)
2024-04-13 10:57:32 +02:00
2024-08-30 21:48:20 +02:00
claim_button = welcome_tour.find_element(By.ID, "claim-button")
claim_button.click() # submit
custom_sleep(1.5)
return True
2024-04-13 10:57:32 +02:00
2024-08-30 21:48:20 +02:00
def check_streak_protection() -> bool:
"""
Ne perdez plus jamais votre série !
"""
try:
streak_protection_close = driver.find_element(By.ID, "streak-protection-popup-close-cross")
streak_protection_activate = driver.find_elements(By.CLASS_NAME, "earningPagePopUpPopUpSelectButton")
streak_protection_activate[0].click()
info("Popup 'Streak Protection' reçue")
custom_sleep(1.5)
return True
except (exceptions.NoSuchElementException, exceptions.ElementNotInteractableException, IndexError):
# les éléments sont présents dans le DOM même quand la popup n'est pas visible apparemment
return False
def check_streak_protection_expired() -> bool:
"""
Non, vous avez utilisé tous vos jours de protection contre les séries !
"""
try:
streak_protection_close = driver.find_element(By.ID, "streak-protection-popup-close-cross")
ok_sad_button = driver.find_elements(By.CLASS_NAME, "dashboardPopUpPopUpSelectButton")
ok_sad_button[0].click()
info("Popup 'Streak Protection fully used' reçue")
custom_sleep(1.5)
2024-04-12 23:46:26 +02:00
2024-08-30 21:48:20 +02:00
return True
except (exceptions.NoSuchElementException, exceptions.ElementNotInteractableException, IndexError):
return False
2024-05-12 17:55:56 +02:00
2024-08-30 21:48:20 +02:00
return (
check_welcome_tour()
or check_streak_protection()
or check_streak_protection_expired()
)
2024-05-16 17:52:12 +02:00
driver.get("https://rewards.bing.com")
wait_until_visible(By.CLASS_NAME, "c-card-content", 10, driver)
2024-02-28 00:14:42 +01:00
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
custom_sleep(2)
2024-02-28 00:14:42 +01:00
try:
promo()
except Exception as e:
2024-02-28 00:14:42 +01:00
debug(e)
info("no promo card")
2024-02-28 00:14:42 +01:00
if len(card_list) < 10: # most likely an error during loading
if "suspendu" in driver.page_source or "suspended" in driver.page_source:
raise Banned()
driver.refresh()
2024-02-28 00:14:42 +01:00
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
if len(card_list) < 10:
log_error("Less than 10 cards. Most likely an error with login.")
2024-02-28 00:14:42 +01:00
return "Not enough cards"
for i in range(len(card_list)):
2024-02-27 15:05:19 +01:00
debug(f"carte {i}")
2024-02-28 00:14:42 +01:00
checked = False
try:
2024-02-28 00:14:42 +01:00
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML")
except StaleElementReferenceException:
driver.refresh()
2024-02-28 00:14:42 +01:00
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
warning(f"staled, {len(card_list)}")
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML")
except IndexError:
driver.get("https://rewards.bing.com")
custom_sleep(10)
2024-02-28 00:14:42 +01:00
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
try:
2024-02-28 00:14:42 +01:00
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML")
except IndexError:
2024-02-28 00:14:42 +01:00
if i == len(card_list) and i > 15:
checked = False
2024-02-28 00:14:42 +01:00
2024-04-13 10:15:26 +02:00
if not checked:
continue
2024-04-26 13:55:20 +02:00
try:
activity = findall("data-bi-id=\"([^\"]+)\"", card_list[i].get_attribute("innerHTML"))[0]
2024-04-26 14:00:33 +02:00
except Exception as e:
warning("Can't find activity." + str(e))
2024-04-26 13:55:20 +02:00
activity = ""
2024-04-13 10:15:26 +02:00
custom_sleep(1.5)
2024-08-30 21:48:20 +02:00
check_popups()
2024-04-13 10:15:26 +02:00
driver.execute_script("arguments[0].scrollIntoView();", card_list[i])
custom_sleep(1.5)
card_list[i].click()
if len(driver.window_handles) > 1:
driver.switch_to.window(driver.window_handles[1])
2024-04-26 13:55:20 +02:00
try_play(driver.title, activity)
2024-04-13 10:15:26 +02:00
close_tab(driver.window_handles[1])
try:
driver.refresh()
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
2024-02-28 00:14:42 +01:00
2024-04-13 10:15:26 +02:00
if "mee-icon-AddMedium" not in card_list[i].get_attribute("innerHTML"):
continue
2024-02-28 00:14:42 +01:00
2024-08-30 21:48:20 +02:00
check_popups()
driver.execute_script("arguments[0].scrollIntoView();", card_list[i])
2024-04-13 10:15:26 +02:00
card_list[i].click()
driver.switch_to.window(driver.window_handles[1])
custom_sleep(10)
log_error(f"Card {i} Can't be completed. Why MS ?")
2024-02-28 00:14:42 +01:00
try:
2024-04-13 10:15:26 +02:00
try_play(driver.title) # go back to the main page
try:
close_tab(driver.window_handles[1])
except Exception as e:
debug(e)
except Exception as e:
debug(e)
driver.get("https://rewards.bing.com")
except Exception as err:
log_error(err)
custom_sleep(3)
def promo():
driver = config.WebDriver.driver
for i in range(5):
elm = driver.find_element(By.ID, "promo-item")
wait_until_visible(By.ID, "promo-item", 5, driver)
if not elm:
break
if i > 3:
2024-02-28 11:10:48 +01:00
log_error("There is more than 3 promo cards, most likely an unskippable one.")
try:
driver.find_element(By.CSS_SELECTOR,
'i[class="mee-icon pull-left icon mee-icon-Cancel ng-scope"]').click()
except Exception as e:
log_error(f"can't click to close : {e}")
return ()
try:
elm.click()
except Exception as e:
driver.execute_script("arguments[0].click();", elm)
2024-02-28 11:10:48 +01:00
warning(f"that shouldn't be there (promo), but the workaround seemed to work {e}")
custom_sleep(3)
if len(driver.window_handles) > 1:
driver.switch_to.window(driver.window_handles[len(driver.window_handles) - 1])
try_play(driver.title)
close_tab(driver.window_handles[1])
else:
try:
spotify(driver)
2024-02-28 11:10:48 +01:00
except Exception as e:
warning(f"no new windows {format_error(e)}")
driver.get("https://rewards.bing.com")
driver.refresh()
custom_sleep(3)
2024-04-26 13:55:20 +02:00
def explore_on_bing(activity: str, config: Config):
driver = config.WebDriver.driver
def search_bing(txt):
2024-04-26 14:00:33 +02:00
search_elm = driver.find_element(By.ID, "sb_form_q")
2024-04-26 13:55:20 +02:00
send_keys_wait(search_elm, txt)
send_keys_wait(search_elm, Keys.ENTER)
if "lyrics" in activity:
search_bing(
f"paroles de {['Gata', 'Pyramide', 'Dolce Camara', 'Position', 'Mami Wata'][randint(0, 4)]}") # merci bing copilot pour les titres
2024-04-26 13:55:20 +02:00
elif "flight" in activity:
search_bing(
f"vol {['Paris - New York', 'Londres Amsterdam', 'Bora-Bora Miami', 'Los Angeles Toulouse', 'Rome Dubai'][randint(0, 4)]}")
elif "shopping" in activity:
search_bing(f"idée cadeau {['Noel', 'Anniversaire'][randint(0, 1)]}")
elif "movie" in activity:
search_bing(
f"Distribution {['Code 8 part 2', 'The Hunger Games: The ballad of Songbirds & Snakes', 'Rebel Moon: Part Two', 'Dune II', 'Wonka'][randint(0, 4)]}")
2024-04-26 15:43:23 +02:00
elif "translator" in activity:
search_bing(f"traduction {config.wordlist.get_word()} en anglais")
elif "map" in activity:
search_bing(f"{['Paris', 'Nice', 'Marseille', 'Bordeaux', 'Lyon'][randint(0, 4)]} carte")
2024-05-15 09:52:39 +02:00
elif "restaurant" in activity:
search_bing(random.choice([
"restaurant à proximité",
"restaurant pas loin",
"manger dans le coin"
]))
elif "recipe" in activity:
2024-05-16 17:52:12 +02:00
search_bing("recette de " + random.choice([
2024-05-15 09:52:39 +02:00
"cake aux olives",
"tarte tatin",
"Kouign Amann",
"poulet au Curry",
"lasagnes aux épinards et ricotta",
"Boeuf Bourguignon",
"dessert",
"gateau au chocolat",
"crêpe sucrée"
2024-05-16 17:52:12 +02:00
])) # Merci llama pour les idées
2024-05-15 09:52:39 +02:00
elif "currency" in activity:
currencies = [
"euros",
"dollars canadiens",
"dollars",
"livres",
"francs suisses",
"roubles",
"pesos",
"bitcoin",
"anciens francs"
]
2024-05-15 10:03:01 +02:00
chosen = random.sample(currencies, k=2)
2024-05-15 09:52:39 +02:00
search_bing(f"convertir {random.randint(2, 120)} {chosen[0]} en {chosen[1]}")
2024-06-18 16:38:29 +02:00
elif "weather" in activity:
search_bing(f"météo {['Paris', 'Nice', 'Marseille', 'Bordeaux', 'Lyon'][randint(0, 4)]}")
2024-06-18 16:54:37 +02:00
elif "packagetracking" in activity:
driver.get("https://www.bing.com/?setmkt=en-US&setlang=en-US")
2024-09-14 22:57:40 +02:00
search_bing(f"{['fedex', 'UPS'][randint(0, 1)]} package tracking")
2024-07-05 13:45:26 +02:00
elif "hotel" in activity:
search_bing(f" {['Paris', 'Nice', 'Marseille', 'Bordeaux', 'Lyon'][randint(0, 4)]}")
elif "health" in activity:
2024-09-14 22:57:40 +02:00
search_bing(f"{['toux', 'douleur dos', 'nez qui coule', 'mal au genoux', 'otite'][randint(0, 4)]}")
2024-07-05 13:45:26 +02:00
elif "news" in activity:
search_bing(["actualités", "news"][randint(0, 1)])
elif "jobs" in activity:
search_bing("jobs")
elif "realestate" in activity:
2024-09-14 22:57:40 +02:00
search_bing(f"appartement à louer {['Paris', 'Nice', 'Marseille', 'Bordeaux', 'Lyon'][randint(0, 4)]}")
elif "financemarket" in activity:
search_bing(
f"cours action {['AIR LIQUIDE', 'Airbus', 'BNP Paribas', 'Michelin', 'Stellantis', 'Vinci'][randint(0, 5)]}")
2024-10-08 09:07:01 +02:00
elif "sports" in activity:
equipes = random.sample([
"Toulon", "toulouse",
"stade Rochelais", "castres",
"clermont", "perpignan",
"aviron bayonnais", "vannes"
], k=2)
search_bing(f"{['score', 'résultats'][randint(0, 1)]} rugby {equipes[0]} {equipes[1]}")
elif "videogames" in activity:
search_bing(random.choice([
"Minecraft", "GTA V",
"Tetris", "PUBG",
"Mario Kart 8",
"Red Dead Redemption II",
"Terraria",
"The Witcher",
"Animal Crossing",
"Pokémon rouge & bleu",
"Super Mario Bros",
"The legend of Zelda BOTW",
"Call of Duty Modern Warfare",
"The Witcher III"
]))
2024-10-15 11:51:55 +02:00
elif "dictionary" in activity:
search_bing(f"définition {config.wordlist.get_word()}")
2024-10-18 13:03:16 +02:00
elif "election" in activity or "timezonedates" in activity:
#! I don't understand the name of "timezonedates" but this seems to be the same activity
2024-10-15 11:51:55 +02:00
state = random.choice([
"Alaska", "Alabama", "Arkansas", "American Samoa", "Arizona", "California", "Colorado",
"Connecticut", "District ", "of Columbia", "Delaware", "Florida", "Georgia", "Guam",
"Hawaii", "Iowa", "Idaho", "Illinois", "Indiana", "Kansas", "Kentucky", "Louisiana",
"Massachusetts", "Maryland", "Maine", "Michigan", "Minnesota", "Missouri", "Mississippi",
"Montana", "North Carolina", "North Dakota", "Nebraska", "New Hampshire", "New Jersey",
"New Mexico", "Nevada", "New York", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
"Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Virginia", "Virgin Islands", "Vermont", "Washington", "Wisconsin",
"West Virginia", "Wyoming"
])
search_bing(f"governor candidates {state} 2024")
else:
log_error(f"Explore on bing: {activity} not found.")
2024-04-26 13:55:20 +02:00
# Find out which type of action to do
2024-04-26 13:55:20 +02:00
def try_play(nom="unknown", activity=""):
driver = config.WebDriver.driver
2024-02-27 16:21:08 +01:00
rgpd_popup(config)
def play(number):
if number in [8, 9]:
try:
debug(f"Quiz 8 detected on `{nom}`.")
play_quiz8()
except Exception as err:
error(f"fail of PlayQuiz 8. Aborted {err}")
elif number in [4, 5]:
try:
debug(f"Quiz 4 detected on `{nom}`")
play_quiz4()
except Exception as err:
error(f"Fail of PlayQuiz 4. Aborted {err}.")
elif number in [2, 3]:
try:
debug(f"\033[96mQuiz 2 detected on `{nom}`\033[0m")
play_quiz2()
except Exception as err:
error(f"fail of PlayQuiz 2. Aborted {err}")
else:
error("`rqAnswerOption` present in page but no action to do.")
custom_sleep(uniform(3, 5))
if "pas connecté à Microsoft Rewards" in driver.page_source:
custom_sleep(5)
driver.find_element(By.CSS_SELECTOR, '[onclick="setsrchusr()"]').click()
custom_sleep(5)
2024-02-27 16:21:08 +01:00
rgpd_popup(config)
custom_sleep(5)
debug("Detected and fixed connection popup")
if "bt_PollRadio" in driver.page_source:
debug("Poll detected")
do_poll()
elif search("([0-9]) de ([0-9]) finalisée", driver.page_source):
info("On fidelity page.")
fidelity()
2024-04-26 13:55:20 +02:00
elif wait_until_visible(By.ID, "rqStartQuiz", 5, driver, raise_error=False):
custom_sleep(3)
driver.find_element(By.ID, "rqStartQuiz").click() # start the quiz
answer_number = driver.page_source.count("rqAnswerOption")
play(answer_number)
2024-02-27 16:26:29 +01:00
elif "rqQuestionState" in driver.page_source:
number = driver.page_source.count("rqAnswerOption")
2024-02-28 11:10:48 +01:00
warning(f"recovery detected. quiz : {number}")
2024-02-27 16:26:29 +01:00
play(number - 1)
2024-04-26 13:55:20 +02:00
elif "exploreonbing" in activity:
info(f"Explore on bing: {activity}")
2024-04-26 13:55:20 +02:00
explore_on_bing(activity, config)
custom_sleep(uniform(3, 5))
elif "Optimisez votre sécurité avec Microsoft" in driver.page_source:
info("Still not paying Office 365 ?")
else:
info(f"Nothing obvious to do on page `{nom}`.")
custom_sleep(uniform(3, 5))
# Login with password or with cookies.
# The driver should be in the same state on both case
def login_part_1():
info("Starting part 1 of login")
driver = config.WebDriver.driver
2024-02-27 15:55:37 +01:00
driver.get("https://login.live.com")
2024-07-08 10:00:28 +02:00
try:
wait_until_visible(By.ID, "i0116", browser=driver)
send_wait_and_confirm(
driver.find_element(By.ID, "i0116"),
config.UserCredentials.get_mail()
)
except exceptions.NoSuchElementException:
info("Unable to find mail input for login, might be semi-logged-in")
wait_until_visible(By.ID, "i0118", browser=driver)
send_wait_and_confirm(
driver.find_element(By.ID, "i0118"),
config.UserCredentials.get_password()
)
# 2FA
try:
2024-04-10 12:14:41 +02:00
if not wait_until_visible(By.ID, "idTxtBx_SAOTCC_OTC", browser=driver, timeout=5, raise_error=False):
custom_sleep(2)
return
tfa = config.UserCredentials.get_tfa()
if tfa is None:
error("2FA needed but no code available for this account, sending error")
raise ValueError("2FA needed but no code available for this account")
else:
a2f_code = tfa.now()
info(f"Need 2FA, I have code: {a2f_code}")
send_wait_and_confirm(
driver.find_element(By.ID, "idTxtBx_SAOTCC_OTC"),
a2f_code
)
except Exception as err:
log_error(err)
# Accept all cookies question, and check if the account is locked
def login_part_2():
driver = config.WebDriver.driver
custom_sleep(5)
if 'Abuse' in driver.current_url:
raise Banned()
if 'identity' in driver.current_url:
raise Identity()
if 'notice' in driver.current_url:
driver.find_element(By.ID, "id__0").click()
if "proof" in driver.current_url:
driver.find_element(By.ID, "iLooksGood")
2024-02-27 16:13:01 +01:00
for elm_id in ["checkboxField", "KmsiCheckboxField", "acceptButton", "iNext", "id__0", "iLooksGood", "idSIButton9",
"iCancel"]:
if get_domain(driver) == "account.microsoft.com":
break
try:
driver.find_element(By.ID, elm_id).click()
except Exception as e:
debug(e)
wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 20, driver)
# login() tries to login to your Microsoft account.
# it uses global variable g._mail and g._password to login
def login():
def logged_in():
driver.get("https://login.live.com")
custom_sleep(10)
debug(get_domain(driver))
if get_domain(driver) == "account.microsoft.com":
return True
return False
info("Logging in...")
driver = config.WebDriver.driver
try:
if not logged_in():
login_part_1()
login_part_2()
driver.get("https://rewards.bing.com/")
except Banned:
raise Banned()
except Identity:
raise Banned()
2024-02-27 15:21:30 +01:00
except Exception as err:
critical("Error not caught during login." + format_error(err))
log_error(err)
driver.quit()
return False
# Makes 30 search as PC Edge
def bing_pc_search(override=randint(35, 40)):
driver = config.WebDriver.driver
driver.get(f"https://www.bing.com/search?q={config.wordlist.get_word().replace(' ', '+')}")
custom_sleep(uniform(1, 2))
2024-02-27 16:21:08 +01:00
rgpd_popup(config)
send_keys_wait(
driver.find_element(By.ID, "sb_form_q"),
Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE
)
for _ in range(override):
word = config.wordlist.get_word()
try:
send_keys_wait(driver.find_element(By.ID, "sb_form_q"), word)
driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER)
except Exception as e:
error(e)
sleep(10)
driver.get(f'https://www.bing.com/search?q={word}')
sleep(3)
send_keys_wait(driver.find_element(By.ID, "sb_form_q"), word)
driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER)
custom_sleep(uniform(3, 7))
try:
driver.find_element(By.ID, "sb_form_q").clear()
except Exception as e:
error(e)
try:
driver.get('https://www.bing.com/search?q=plans')
driver.find_element(By.ID, "sb_form_q").clear()
except Exception as e:
log_error(f"clear la barre de recherche - {format_error(e)}") # what is this message ??? todo
2024-02-28 10:49:27 +01:00
# Sends current account's points to database
def log_points():
driver = config.WebDriver.driver
account = config.UserCredentials.get_mail()
2024-02-27 15:05:19 +01:00
2024-02-28 10:49:27 +01:00
driver.get("https://rewards.bing.com")
custom_sleep(1)
wait_until_visible(By.CSS_SELECTOR, 'span[mee-element-ready="$ctrl.loadCounterAnimation()"]', browser=driver)
try:
points = search('availablePoints\":([\d]+)', driver.page_source)[1]
except Exception as err:
log_error(
f"Dev error, checking why it doesn't work (waited a bit, is this still white ?) {format_error(err)}")
error(f"Can't get points. {format_error(err)}")
return -1
custom_sleep(uniform(3, 20))
account_name = account.split("@")[0]
try:
add_to_database(account_name, points)
except Exception as e:
log_error(e)
# todo: refactor and check if it works at all
def fidelity():
driver = config.WebDriver.driver
2024-02-27 15:05:19 +01:00
def sub_fidelity():
try:
wait_until_visible(By.CSS_SELECTOR, 'div[class="pull-left spacer-48-bottom punchcard-row"]', browser=driver)
answer_number = search("([0-9]) of ([0-9]) completed", driver.page_source)
if answer_number is None:
answer_number = search("([0-9])&nbsp;défi\(s\) terminé\(s\) sur ([0-9])", driver.page_source)
if answer_number is None:
answer_number = search("([0-9]) de ([0-9]) finalisé", driver.page_source)
if answer_number is None:
answer_number = search("([0-9]) licence\(s\) sur ([0-9]) disponible\(s\)", driver.page_source)
if answer_number is None:
answer_number = [0, 0, 0]
for _ in range(int(answer_number[2]) - int(answer_number[1])):
driver.refresh()
custom_sleep(2)
card_elem = driver.find_element(By.CLASS_NAME, "spacer-48-bottom")
try:
button_text = search('<span class="pull-left margin-right-15">([^<^>]+)</span>',
card_elem.get_attribute("innerHTML"))[1]
2024-02-28 11:10:48 +01:00
button_card = driver.find_element(By.XPATH, f'//span[text()="{button_text}"]')
button_card.click()
except Exception as e1:
try:
recover_elem = driver.find_element(By.XPATH,
'/html/body/div[1]/div[2]/main/div[2]/div[2]/div[7]/div[3]/div[1]/a')
recover_elem.click()
except Exception as e2:
2024-02-28 11:10:48 +01:00
log_error(f"Fidelity: Multiples error - e1 : {format_error(e1)} - e2 {format_error(e2)}")
break
custom_sleep(uniform(3, 5))
driver.switch_to.window(driver.window_handles[2])
try_play(driver.title)
custom_sleep(uniform(3, 5))
try:
close_tab(driver.window_handles[2], 1)
2024-02-27 15:05:19 +01:00
except Exception as err:
error(err)
info("fidelity - done")
except Exception as err:
log_error(err)
if driver.current_url != "https://rewards.bing.com":
driver.get("https://rewards.bing.com")
try:
2024-02-28 11:10:48 +01:00
pause = driver.find_element(By.CSS_SELECTOR, f'[class="c-action-toggle c-glyph f-toggle glyph-pause"]')
pause.click()
except Exception as e:
2024-04-26 14:32:01 +02:00
debug("No pause button.")
cartes = driver.find_elements(By.CSS_SELECTOR, f'[ng-repeat="item in $ctrl.transcludedItems"]')
nb_cartes = len(cartes)
2024-04-26 14:32:01 +02:00
if nb_cartes == 0:
warning("No fidelity cards detected")
return "No cards."
checked_list_all = driver.find_elements(By.CSS_SELECTOR, f'[ng-if="$ctrl.complete"]')
for i in range(nb_cartes):
2024-02-28 11:10:48 +01:00
cartes[i].click()
checked_txt = checked_list_all[i].get_attribute("innerHTML")
ok = checked_txt.count("StatusCircleOuter checkmark")
total = checked_txt.count("StatusCircleOuter")
2024-04-26 14:32:01 +02:00
if ok != total:
elm = driver.find_elements(By.CLASS_NAME, 'clickable-link')[i]
2024-04-26 14:32:01 +02:00
# legacy code. Should be removed
if "moviesandtv" not in elm.get_attribute("innerHTML"): # not the film card
elm.click()
driver.switch_to.window(driver.window_handles[len(driver.window_handles) - 1])
sub_fidelity()
close_tab(driver.window_handles[1])
custom_sleep(1)
cartes = driver.find_elements(By.CSS_SELECTOR, f'[ng-repeat="item in $ctrl.transcludedItems"]')
checked_list_all = driver.find_elements(By.CSS_SELECTOR, f'[ng-if="$ctrl.complete"]')
def mobile_alert_popup():
driver = config.WebDriver.driver
try:
alert = driver.switch_to.alert
alert.dismiss()
except exceptions.NoAlertPresentException:
pass
except Exception as err:
log_error(err)
# todo: be coherent with pc search regarding error management
def bing_mobile_search(cred: UserCredentials, override=randint(22, 25)):
config.WebDriver.set_mobile_driver(create_driver(mobile=True))
config.WebDriver.switch_to_driver("Mobile")
driver = config.WebDriver.driver
try:
login()
mot = config.wordlist.get_word().replace(" ", "+")
driver.get(f"https://www.bing.com/search?q={mot}")
custom_sleep(uniform(1, 2))
rgpd_popup(config)
custom_sleep(uniform(1, 1.5))
for i in range(override): # 20
try:
mot = config.wordlist.get_word()
send_keys_wait(driver.find_element(By.ID, "sb_form_q"), mot)
driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER)
custom_sleep(uniform(3, 7))
mobile_alert_popup() # check for alert (asking for position or for allowing notifications)
driver.find_element(By.ID, "sb_form_q").clear()
except Exception as err:
error(err)
driver.refresh()
custom_sleep(30)
i -= 1
driver.quit()
except Exception as err:
log_error(err)
driver.quit()
finally:
config.WebDriver.switch_to_driver("PC")
def daily_routine(cred: UserCredentials, custom=False):
try:
if not custom: # custom already is logged in
login()
except Banned:
log_error("This account is locked.")
raise Banned()
except Identity:
log_error("This account has an issue.")
return
try:
all_cards()
except Banned:
log_error("banned")
raise Banned
except Exception as err:
log_error(err)
try:
fidelity()
except Exception as err:
log_error(err)
try:
bing_pc_search()
except Exception as err:
log_error(err)
try:
bing_mobile_search(cred)
except Exception as err:
log_error(err)
try:
log_points()
except Exception as err:
log_error(err)
def json_start(json_entry, cred: UserCredentials):
json_entry = json.loads(json_entry)
config.set_display(SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=2345, color_depth=24))
config.display.start()
2024-02-28 14:40:12 +01:00
account_id = 0
while config.UserCredentials.is_valid():
start = False
for action in ["unban", "tout", "pc", "mobile", "daily"]:
try:
if str(account_id) in json_entry[action]:
start = True
info(f"{cred.get_mail()} : {action}")
except KeyError:
pass
if start:
config.WebDriver.set_pc_driver(create_driver())
2024-02-28 14:29:21 +01:00
config.WebDriver.switch_to_driver("PC")
driver = config.WebDriver.driver
2024-04-26 16:06:33 +02:00
if "unban" in json_entry and str(account_id) in json_entry["unban"]:
login()
info("\nGO TO example.com TO PROCEED or wait 1200 secs.")
for _ in range(1200):
sleep(1)
if driver.current_url == "https://example.com/":
info("proceeding")
break
else:
login()
try:
2024-04-26 16:06:33 +02:00
if str(account_id) in json_entry["tout"]:
daily_routine(cred, True)
else:
try:
2024-04-26 16:06:33 +02:00
if str(account_id) in json_entry["daily"]:
try:
all_cards()
except Exception as e:
log_error(e)
except KeyError:
pass
try:
2024-04-26 16:06:33 +02:00
if str(account_id) in json_entry["pc"]:
try:
bing_pc_search()
except Exception as e:
log_error(e)
except KeyError:
pass
try:
2024-04-26 16:06:33 +02:00
if str(account_id) in json_entry["mobile"]:
try:
bing_mobile_search(cred)
except Exception as e:
log_error(e)
except KeyError:
pass
except KeyError:
pass
try:
log_points()
except Exception as e:
error(f"CustomStart {e}")
2024-04-26 16:06:33 +02:00
driver.close()
cred.next_account()
2024-02-28 14:40:12 +01:00
account_id += 1
config.display.stop()
def default_start():
if config.vnc_enabled():
config.set_display(SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=config.vnc, color_depth=24))
else:
config.set_display(SmartDisplay(size=(1920, 1080)))
config.display.start()
while config.UserCredentials.is_valid():
custom_sleep(1)
info("Starting and configuring driver.")
try:
config.WebDriver.set_pc_driver(create_driver())
except:
2024-05-16 17:52:12 +02:00
info("Could not configure driver. Trying to update it.")
subprocess.Popen(["python3", "/app/MsRewards-Reborn/modules/Tools/update_chrome.py"])
config.WebDriver.set_pc_driver(create_driver())
2024-02-27 15:22:51 +01:00
config.WebDriver.switch_to_driver("PC")
info("Driver started.")
config.WebDriver.pc_driver.implicitly_wait(3)
try:
wait_time = uniform(1200, 3600)
info(f"Waiting for {round(wait_time / 60)}min before starting")
custom_sleep(wait_time)
daily_routine(config.UserCredentials)
config.WebDriver.pc_driver.quit()
except KeyboardInterrupt:
critical("Canceled by user. Closing driver and display.")
config.WebDriver.pc_driver.quit()
config.display.stop()
break
except Banned:
warning("this account is banned. Switching to next account")
except Exception as e:
log_error(f"Error not caught. Skipping this account. " + format_error(e))
critical(f"Error not caught. Skipping this account. {e}")
config.WebDriver.pc_driver.quit()
finally:
config.UserCredentials.next_account()
config.display.stop()
def log_error(msg):
2024-02-28 00:14:42 +01:00
DiscordLogger(config).send(msg)
def check_updated():
if config.has_been_updated():
config.discord.wh.send(f"Updated to {config.version}", username="update",
2024-02-27 15:05:19 +01:00
avatar_url="https://cdn-icons-png.flaticon.com/512/1688/1688988.png")
if __name__ == "__main__":
config = Config(args)
check_updated()
match config.start:
case "json":
json_start(config.json_entry, config.UserCredentials)
case "default":
default_start()