Compare commits
No commits in common. "d4920ec32249b31a6884e8f9af6c72e6eaea8ef5" and "fc8e6669276a96ec8d61a747960dca45d2fc7d62" have entirely different histories.
d4920ec322
...
fc8e666927
582
V6.py
582
V6.py
@ -5,26 +5,21 @@ from modules.driver_tools import *
|
||||
from modules.cards import *
|
||||
import modules.globals as g
|
||||
|
||||
from modules.Classes.Config import Config
|
||||
from modules.Classes.UserCredentials import UserCredentials
|
||||
from modules.Tools.logger import warning, info, debug, error, critical
|
||||
|
||||
|
||||
driver = g.driver
|
||||
display = g.display
|
||||
|
||||
|
||||
# create a webdriver
|
||||
def create_driver(mobile=False):
|
||||
def create_driver(mobile=False, headless=False):
|
||||
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"
|
||||
"Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.46"
|
||||
)
|
||||
MOBILE_USER_AGENT = (
|
||||
"Mozilla/5.0 (Linux; Android 7.0; Nexus 5 Build/MRA58N)"
|
||||
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N)"
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko)"
|
||||
"Chrome/22 Mobile Safari/537.36"
|
||||
"Chrome/%s Mobile Safari/537.36"
|
||||
)
|
||||
chrome_options = webdriver.ChromeOptions()
|
||||
if mobile:
|
||||
@ -33,20 +28,20 @@ def create_driver(mobile=False):
|
||||
chrome_options.add_argument(f"--user-agent={PC_USER_AGENT}")
|
||||
# disabled as it may cause detection
|
||||
if g.proxy_enabled:
|
||||
chrome_options.add_argument(f'--proxy-server={g.proxy_address}:{g.proxy_port}')
|
||||
PROXY = f"{g.proxy_address}:{g.proxy_port}" # IP:PORT or HOST:PORT
|
||||
chrome_options.add_argument(f'--proxy-server={PROXY}')
|
||||
driver = uc.Chrome(options=chrome_options)
|
||||
set_language(driver)
|
||||
return driver
|
||||
return (driver)
|
||||
|
||||
|
||||
def log_error(error_message, l_driver=driver, log=g.full_log):
|
||||
def log_error(error, l_driver=driver, log=g.full_log):
|
||||
global driver
|
||||
if l_driver is None:
|
||||
l_driver = driver
|
||||
if type(error_message) is not str:
|
||||
error_message = format_error(error_message)
|
||||
|
||||
error(str(error_message))
|
||||
if type(error) is not str:
|
||||
error = format_error(error)
|
||||
printf(f"\n\n\033[93m Erreur : {str(error)} \033[0m\n\n")
|
||||
if g.discord_enabled_error:
|
||||
with open("page.html", "w") as f:
|
||||
try:
|
||||
@ -61,13 +56,13 @@ def log_error(error_message, l_driver=driver, log=g.full_log):
|
||||
if not log:
|
||||
embed = Embed(
|
||||
title="An Error has occured",
|
||||
description=str(error_message),
|
||||
description=str(error),
|
||||
colour=Colour.red(),
|
||||
)
|
||||
else:
|
||||
embed = Embed(
|
||||
title="Full log is enabled",
|
||||
description=str(error_message),
|
||||
description=str(error),
|
||||
colour=Colour.blue(),
|
||||
)
|
||||
file = File("screenshot.png")
|
||||
@ -78,68 +73,73 @@ def log_error(error_message, l_driver=driver, log=g.full_log):
|
||||
|
||||
|
||||
# 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:
|
||||
def close_tab(tab, SwitchTo=0) -> None:
|
||||
driver.switch_to.window(tab)
|
||||
driver.close()
|
||||
driver.switch_to.window(driver.window_handles[switch_to])
|
||||
driver.switch_to.window(driver.window_handles[SwitchTo])
|
||||
|
||||
|
||||
# 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
|
||||
# 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.")
|
||||
debug(f"override: {override}")
|
||||
printf("starting play_quiz2")
|
||||
for j in range(override):
|
||||
custom_sleep(uniform(3, 5))
|
||||
js_function = """
|
||||
function get_correct_answer(){
|
||||
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:
|
||||
# rgpd_popup(driver)
|
||||
custom_sleep(uniform(3, 5))
|
||||
|
||||
js_function = """
|
||||
function get_correct_answer(){
|
||||
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)
|
||||
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}")
|
||||
if g.log:
|
||||
progressBar(j, 10, name="quiz 2")
|
||||
|
||||
except exceptions.ElementNotInteractableException as e:
|
||||
driver.execute_script("arguments[0].click();", answer_elem)
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
break
|
||||
info("Quiz 2 done.")
|
||||
printf("play_quiz2 done")
|
||||
custom_sleep(3)
|
||||
|
||||
|
||||
def play_quiz8():
|
||||
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
|
||||
printf(f"play_quiz8 : start, override : {override}")
|
||||
try:
|
||||
counter = 0
|
||||
# rgpd_popup(driver)
|
||||
for _ in range(override):
|
||||
sleep(uniform(3, 5))
|
||||
correct_answers = []
|
||||
for i in range(1, 9): # todo: remove this odd 1-offset
|
||||
for i in range(1, 9):
|
||||
try:
|
||||
element = driver.find_element(By.ID, f"rqAnswerOption{i - 1}")
|
||||
if 'iscorrectoption="True"' in element.get_attribute("outerHTML"):
|
||||
correct_answers.append(f'rqAnswerOption{i - 1}')
|
||||
except Exception as e:
|
||||
warning(f"can't find rqAnswerOption{i - 1}. Probably already clicked" + str(e))
|
||||
printf(f"can't find rqAnswerOption{i - 1}. 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)
|
||||
counter += 1
|
||||
if g.log:
|
||||
progressBar(counter, 16, name="Quiz 8")
|
||||
try:
|
||||
answer_elem = driver.find_element(By.ID, answer_id)
|
||||
answer_elem.click()
|
||||
@ -155,28 +155,27 @@ def play_quiz8():
|
||||
|
||||
except Exception as e:
|
||||
log_error(f"{format_error(e)} \n Good answers : {' '.join(correct_answers)}")
|
||||
info("Quiz 8 done.")
|
||||
custom_sleep(3)
|
||||
|
||||
|
||||
def play_quiz4(override: int = None):
|
||||
info(f"Starting Quiz 4")
|
||||
|
||||
printf("play_quiz4 : start")
|
||||
if not override:
|
||||
try: # fidelity quiz are much longer than usual ones
|
||||
override = int(findall('rqQuestionState([\d]{1,2})"', driver.page_source)[-1])
|
||||
printf(f"Override : {override}")
|
||||
except:
|
||||
override = 3
|
||||
debug(f"Override : {override}")
|
||||
|
||||
try:
|
||||
for i in range(override):
|
||||
custom_sleep(uniform(3, 5))
|
||||
txt = driver.page_source
|
||||
# rgpd_popup(driver)
|
||||
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 = driver.find_element(By.CSS_SELECTOR, f'[data-option="{answer_option}"]')
|
||||
answer_element.click()
|
||||
except exceptions.ElementNotInteractableException:
|
||||
driver.execute_script("arguments[0].click();", answer_element)
|
||||
@ -184,30 +183,27 @@ def play_quiz4(override: int = None):
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
raise ValueError(e)
|
||||
info("Quiz 8 done.")
|
||||
custom_sleep(3)
|
||||
|
||||
|
||||
# do_poll() answer a random thing to poll, on of daily activities
|
||||
def do_poll():
|
||||
info("Starting poll")
|
||||
printf("do_poll : start")
|
||||
try:
|
||||
answer_elem = driver.find_element(By.ID, f"btoption{choice([0, 1])}")
|
||||
try:
|
||||
answer_elem = driver.find_element(By.ID, f"btoption{choice([0, 1])}")
|
||||
answer_elem.click()
|
||||
except exceptions.ElementNotInteractableException:
|
||||
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.")
|
||||
except Exception as error:
|
||||
log_error(error)
|
||||
raise ValueError(error)
|
||||
custom_sleep(3)
|
||||
|
||||
|
||||
# Find each playable card and tries to click on it to earn points
|
||||
# todo : refactor
|
||||
def all_cards():
|
||||
# input("1")
|
||||
driver.get("https://rewards.bing.com")
|
||||
wait_until_visible(By.CLASS_NAME, "c-card-content", 10, driver)
|
||||
liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
|
||||
@ -215,7 +211,7 @@ def all_cards():
|
||||
try:
|
||||
promo()
|
||||
except Exception as e:
|
||||
info("no promo card")
|
||||
printf("no promo card")
|
||||
if (len(liste) < 10): # most likely an error during loading
|
||||
if "suspendu" in driver.page_source:
|
||||
raise Banned()
|
||||
@ -328,7 +324,7 @@ def promo():
|
||||
try:
|
||||
spotify(driver)
|
||||
except:
|
||||
warning("no new windows")
|
||||
printf("no new windows", driver)
|
||||
driver.get("https://rewards.bing.com")
|
||||
driver.refresh()
|
||||
custom_sleep(3)
|
||||
@ -339,30 +335,33 @@ def try_play(nom="inconnu"):
|
||||
rgpd_popup(driver)
|
||||
|
||||
def play(number):
|
||||
if number in [8, 9]:
|
||||
if number == 8 or number == 9:
|
||||
try:
|
||||
debug(f"Quiz 8 detected on `{nom}`.")
|
||||
printf(f"\033[96mQuiz 8 detected on `{nom}` \033[0m")
|
||||
play_quiz8()
|
||||
except Exception as err:
|
||||
error(f"fail of PlayQuiz 8. Aborted {err}")
|
||||
printf(f"\033[92mQuiz 8 succeeded on `{nom}` \033[0m")
|
||||
custom_sleep(uniform(3, 5))
|
||||
except Exception as e:
|
||||
printf(f"fail of PlayQuiz 8. Aborted {e} \033[0m")
|
||||
|
||||
elif number in [4, 5]:
|
||||
elif number == 5 or number == 4:
|
||||
try:
|
||||
debug(f"Quiz 4 detected on `{nom}`")
|
||||
printf(f"\033[96mQuiz 4 detected on `{nom}` \033[0m")
|
||||
play_quiz4()
|
||||
except Exception as err:
|
||||
error(f"Fail of PlayQuiz 4. Aborted {err}.")
|
||||
printf(f"\033[92mQuiz 4 succeeded on `{nom}` \033[0m")
|
||||
custom_sleep(uniform(3, 5))
|
||||
except Exception as e:
|
||||
printf(f"Fail of PlayQuiz 4. Aborted {e} \033[0m")
|
||||
|
||||
elif number in [2, 3]:
|
||||
elif number == 3 or number == 2:
|
||||
try:
|
||||
debug(f"\033[96mQuiz 2 detected on `{nom}`\033[0m")
|
||||
printf(f"\033[96mQuiz 2 detected on `{nom}`\033[0m")
|
||||
play_quiz2()
|
||||
except Exception as err:
|
||||
error(f"fail of PlayQuiz 2. Aborted {err}")
|
||||
printf(f"\033[92mQuiz 2 succeeded on `{nom}`\033[0m")
|
||||
except Exception as e:
|
||||
printf(f"fail of PlayQuiz 2. Aborted {e}")
|
||||
else:
|
||||
error("`rqAnswerOption` present in page but no action to do.")
|
||||
|
||||
custom_sleep(uniform(3, 5))
|
||||
printf("There is an error. rqAnswerOption present in page but no action to do. skipping.")
|
||||
|
||||
if "pas connecté à Microsoft Rewards" in driver.page_source:
|
||||
custom_sleep(5)
|
||||
@ -370,44 +369,57 @@ def try_play(nom="inconnu"):
|
||||
custom_sleep(5)
|
||||
rgpd_popup(driver)
|
||||
custom_sleep(5)
|
||||
debug("Detected and fixed connection popup")
|
||||
printf("not connected, fixed")
|
||||
if "legaltextbox" in driver.current_url:
|
||||
log_error("dev1")
|
||||
driver.find_element(By.CLASS_NAME, "actionLink").click()
|
||||
log_error("dev2")
|
||||
try:
|
||||
if wait_until_visible(By.ID, "rqStartQuiz", 5, driver):
|
||||
custom_sleep(3)
|
||||
driver.find_element(By.ID, "rqStartQuiz").click() # start the quiz
|
||||
answer_number = driver.page_source.count("rqAnswerOption")
|
||||
play(answer_number)
|
||||
else:
|
||||
raise (NameError("going to next part"))
|
||||
except Exception as e: # if there is no start button, an error is thrown
|
||||
if "bt_PollRadio" in driver.page_source:
|
||||
try:
|
||||
printf("Poll detected")
|
||||
do_poll()
|
||||
printf("Poll succeeded")
|
||||
except Exception as e:
|
||||
printf(f"try_play - 1 - Poll aborted {e}")
|
||||
|
||||
if "bt_PollRadio" in driver.page_source:
|
||||
debug("Poll detected")
|
||||
do_poll()
|
||||
elif "rqQuestionState" in driver.page_source:
|
||||
try:
|
||||
number = driver.page_source.count("rqAnswerOption")
|
||||
printf(f"recovery détecté. quiz : {number}")
|
||||
play(number - 1)
|
||||
except Exception as e:
|
||||
printf(f"try_play - 2 - {e}")
|
||||
|
||||
elif "rqQuestionState" in driver.page_source:
|
||||
number = driver.page_source.count("rqAnswerOption")
|
||||
warning(f"recovery détecté. quiz : {number}")
|
||||
play(number - 1)
|
||||
elif search("([0-9]) de ([0-9]) finalisée", driver.page_source):
|
||||
printf("fidélité")
|
||||
fidelity()
|
||||
|
||||
elif search("([0-9]) de ([0-9]) finalisée", driver.page_source):
|
||||
info("On fidelity page.")
|
||||
fidelity()
|
||||
|
||||
elif wait_until_visible(By.ID, "rqStartQuiz", 5, driver):
|
||||
custom_sleep(3)
|
||||
driver.find_element(By.ID, "rqStartQuiz").click() # start the quiz
|
||||
answer_number = driver.page_source.count("rqAnswerOption")
|
||||
play(answer_number)
|
||||
|
||||
else:
|
||||
printf(f"Nothing to do on page `{nom}`")
|
||||
custom_sleep(uniform(3, 5))
|
||||
else:
|
||||
printf(f"rien à faire sur la 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(ldriver, cred: UserCredentials):
|
||||
def pwd_login(ldriver):
|
||||
printf("pwd_login : start")
|
||||
ldriver.get("https://login.live.com")
|
||||
wait_until_visible(By.ID, "i0116", browser=ldriver)
|
||||
mail_elem = ldriver.find_element(By.ID, "i0116")
|
||||
send_keys_wait(mail_elem, cred.get_mail())
|
||||
send_keys_wait(mail_elem, g._mail)
|
||||
mail_elem.send_keys(Keys.ENTER)
|
||||
wait_until_visible(By.ID, "i0118", browser=ldriver)
|
||||
pwd_elem = ldriver.find_element(By.ID, "i0118")
|
||||
send_keys_wait(pwd_elem, cred.get_password())
|
||||
send_keys_wait(pwd_elem, g._password)
|
||||
pwd_elem.send_keys(Keys.ENTER)
|
||||
custom_sleep(2)
|
||||
# 2FA
|
||||
@ -420,55 +432,71 @@ def login_part_1(ldriver, cred: UserCredentials):
|
||||
log_error(e)
|
||||
|
||||
|
||||
def cookie_login(ldriver):
|
||||
printf("cookies_login : start")
|
||||
ldriver.get("https://login.live.com")
|
||||
try:
|
||||
load_cookies(ldriver)
|
||||
except FileNotFoundError:
|
||||
printf("No cookies file Found.")
|
||||
return (False)
|
||||
except Exception as e:
|
||||
# log_error(f"Error performing cookies login. Trying with password instead. \n{str(e)}", driver)
|
||||
print("error with cookies login. IDK why (yet)")
|
||||
return (False)
|
||||
try:
|
||||
ldriver.refresh()
|
||||
except Exception as e:
|
||||
printf(format_error(e))
|
||||
printf("FIX YOUR SITE MS.......")
|
||||
|
||||
return (True)
|
||||
|
||||
|
||||
# Accept all cookies question, and check if the account is locked
|
||||
def login_part_2(ldriver):
|
||||
def login_part_2(ldriver, cookies=False):
|
||||
custom_sleep(5)
|
||||
|
||||
if 'Abuse' in ldriver.current_url:
|
||||
if ('Abuse' in ldriver.current_url):
|
||||
raise Banned()
|
||||
|
||||
if 'identity' in ldriver.current_url:
|
||||
if ('identity' in ldriver.current_url):
|
||||
raise Identity()
|
||||
|
||||
if 'notice' in ldriver.current_url:
|
||||
if ('notice' in ldriver.current_url):
|
||||
ldriver.find_element(By.ID, "id__0").click()
|
||||
|
||||
if "proof" in ldriver.current_url:
|
||||
if ("proof" in ldriver.current_url):
|
||||
ldriver.find_element(By.ID, "iLooksGood")
|
||||
|
||||
for elm_id in ["iNext", "KmsiCheckboxField", "id__0", "iLooksGood", "idSIButton9", "iCancel"]:
|
||||
if cookies:
|
||||
save_cookies(ldriver)
|
||||
for id in ["iNext", "KmsiCheckboxField", "id__0", "iLooksGood", "idSIButton9", "iCancel"]:
|
||||
if get_domain(ldriver) == "account.microsoft.com":
|
||||
break
|
||||
try:
|
||||
ldriver.find_element(By.ID, elm_id).click()
|
||||
ldriver.find_element(By.ID, id).click()
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 20, ldriver)
|
||||
|
||||
|
||||
# login() tries to login to your Microsoft account.
|
||||
# it uses global variable g._mail and g._password to login
|
||||
def login(ldriver, cred: UserCredentials):
|
||||
def login(ldriver):
|
||||
try:
|
||||
login_part_1(ldriver, cred)
|
||||
login_part_2(ldriver)
|
||||
pwd_login(ldriver)
|
||||
login_part_2(ldriver, 0)
|
||||
ldriver.get("https://rewards.bing.com/")
|
||||
except Banned:
|
||||
raise Banned()
|
||||
except Identity:
|
||||
raise Banned()
|
||||
except Exception as e:
|
||||
critical("Error not caught during login.")
|
||||
log_error(e)
|
||||
ldriver.quit()
|
||||
return False
|
||||
return (False)
|
||||
|
||||
|
||||
# Makes 30 search as PC Edge
|
||||
def bing_pc_search(override=randint(35, 40)):
|
||||
mot = choice(Liste_de_mot).replace(" ", "+")
|
||||
driver.get(f"https://www.bing.com/search?q={mot}")
|
||||
driver.get(f"https://www.bing.com/search?q={mot}") # {choice(Liste_de_mot)}')
|
||||
custom_sleep(uniform(1, 2))
|
||||
rgpd_popup(driver)
|
||||
send_keys_wait(
|
||||
@ -482,7 +510,7 @@ def bing_pc_search(override=randint(35, 40)):
|
||||
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)
|
||||
printf(e)
|
||||
sleep(10)
|
||||
driver.get(f'https://www.bing.com/search?q={word}')
|
||||
sleep(3)
|
||||
@ -492,32 +520,82 @@ def bing_pc_search(override=randint(35, 40)):
|
||||
try:
|
||||
driver.find_element(By.ID, "sb_form_q").clear()
|
||||
except Exception as e:
|
||||
error(e)
|
||||
printf(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
|
||||
log_error(f"clear la barre de recherche - {format_error(e)}")
|
||||
|
||||
|
||||
# Unban an account, called with -u parameter. You will need a phone number
|
||||
def unban() -> None:
|
||||
driver.find_element(By.ID, "StartAction").click()
|
||||
custom_sleep(2)
|
||||
txt = driver.page_source
|
||||
uuid0 = findall('wlspispHIPCountrySelect([a-z0-9]+)', txt)[0]
|
||||
uuid1 = findall('wlspispHIPPhoneInput([a-z0-9]+)', txt)[0]
|
||||
uuid2 = findall('wlspispHipSendCode([a-z0-9]+)', txt)[0]
|
||||
uuid3 = findall('wlspispSolutionElement([a-z0-9]+)', txt)[0]
|
||||
country_code_select = Select(driver.find_element(By.ID, "wlspispHIPCountrySelect" + uuid0))
|
||||
country_code_input = input("enter Country code (FR, ...) ")
|
||||
country_code_select.select_by_value(country_code_input)
|
||||
wait_until_visible(By.ID, "wlspispHIPPhoneInput" + uuid1, browser=driver)
|
||||
phone_input = input("phone number : +33")
|
||||
phone_elem = driver.find_element(By.ID, "wlspispHIPPhoneInput" + uuid1)
|
||||
phone_elem.send_keys(phone_input)
|
||||
wait_until_visible(By.ID, "wlspispHipSendCode" + uuid2, browser=driver)
|
||||
send_sms_elem = driver.find_element(By.ID, "wlspispHipSendCode" + uuid2)
|
||||
send_sms_elem.click()
|
||||
wait_until_visible(By.ID, "wlspispSolutionElement" + uuid3, browser=driver)
|
||||
sms_code_elem = driver.find_element(By.ID, "wlspispSolutionElement" + uuid3)
|
||||
sms_code_input = input("entrez le contenu du msg : ")
|
||||
sms_code_elem.send_keys(sms_code_input)
|
||||
send_box = driver.find_element(By.ID, "ProofAction")
|
||||
send_box.click()
|
||||
wait_until_visible(By.ID, "FinishAction", browser=driver)
|
||||
end_elem = driver.find_element(By.ID, "FinishAction")
|
||||
end_elem.click()
|
||||
|
||||
|
||||
# Sends points to database, discord and whatever service you want
|
||||
# todo: refactor
|
||||
def log_points(account="unknown"):
|
||||
def get_points():
|
||||
driver.get("https://rewards.bing.com")
|
||||
custom_sleep(1)
|
||||
if "/proofs/" in driver.current_url:
|
||||
webhookFailure.send(f"Is /proof Useful in logpoints?", username="Dev tests",
|
||||
avatar_url="https://cdn.discordapp.com/attachments/793934298977009677/1144560898879541268/image.png")
|
||||
for id in ["KmsiCheckboxField", "iLooksGood", "idSIButton9", "iCancel"]:
|
||||
try:
|
||||
driver.find_element(By.ID, id).click()
|
||||
except Exception as e:
|
||||
pass
|
||||
wait_until_visible(By.CSS_SELECTOR, 'span[mee-element-ready="$ctrl.loadCounterAnimation()"]', browser=driver)
|
||||
try:
|
||||
point = search('availablePoints\":([\d]+)', driver.page_source)[1]
|
||||
except Exception as e:
|
||||
sleep(5)
|
||||
log_error(
|
||||
f"Dev error, checking why it doesn't work (waited a bit, is this still white ?) {format_error(e)}",
|
||||
driver)
|
||||
error("Can't get points.")
|
||||
return -1
|
||||
return point
|
||||
driver, True)
|
||||
driver.refresh()
|
||||
sleep(5)
|
||||
point = search('availablePoints\":([\d]+)', driver.page_source)[1]
|
||||
return (point)
|
||||
|
||||
for _ in range(3):
|
||||
try:
|
||||
points = get_points()
|
||||
break
|
||||
except Exception as e:
|
||||
custom_sleep(300)
|
||||
log_error(e)
|
||||
points = None
|
||||
|
||||
if not points:
|
||||
log_error(f"impossible d'avoir les points")
|
||||
|
||||
points = get_points()
|
||||
custom_sleep(uniform(3, 20))
|
||||
account_name = account.split("@")[0]
|
||||
|
||||
@ -537,7 +615,6 @@ def log_points(account="unknown"):
|
||||
log_error(e)
|
||||
|
||||
|
||||
# todo: refactor and check if it works at all
|
||||
def fidelity():
|
||||
def sub_fidelity():
|
||||
try:
|
||||
@ -613,18 +690,17 @@ def mobile_alert_popup():
|
||||
try:
|
||||
alert = mobile_driver.switch_to.alert
|
||||
alert.dismiss()
|
||||
except exceptions.NoAlertPresentException:
|
||||
except exceptions.NoAlertPresentException as e:
|
||||
pass
|
||||
except Exception as err:
|
||||
log_error(err, mobile_driver)
|
||||
except Exception as e:
|
||||
log_error(e, mobile_driver)
|
||||
|
||||
|
||||
# todo: be coherent with pc search regarding error management
|
||||
def bing_mobile_search(cred: UserCredentials, override=randint(22, 25)):
|
||||
def bing_mobile_search(override=randint(22, 25)):
|
||||
global mobile_driver
|
||||
mobile_driver = create_driver(mobile=True)
|
||||
try:
|
||||
login(mobile_driver, cred)
|
||||
login(mobile_driver)
|
||||
mot = choice(Liste_de_mot).replace(" ", "+")
|
||||
mobile_driver.get(f"https://www.bing.com/search?q={mot}")
|
||||
custom_sleep(uniform(1, 2))
|
||||
@ -638,77 +714,145 @@ def bing_mobile_search(cred: UserCredentials, override=randint(22, 25)):
|
||||
custom_sleep(uniform(3, 7))
|
||||
mobile_alert_popup() # check for alert (asking for position or for allowing notifications)
|
||||
mobile_driver.find_element(By.ID, "sb_form_q").clear()
|
||||
except Exception as err:
|
||||
error(err)
|
||||
except Exception as e:
|
||||
printf(e)
|
||||
mobile_driver.refresh()
|
||||
custom_sleep(30)
|
||||
i -= 1
|
||||
mobile_driver.quit()
|
||||
|
||||
except Exception as err:
|
||||
log_error(err, mobile_driver)
|
||||
except Exception as e:
|
||||
log_error(e, mobile_driver)
|
||||
mobile_driver.quit()
|
||||
|
||||
|
||||
def daily_routine(cred: UserCredentials, custom=False):
|
||||
def daily_routine(custom=False):
|
||||
try:
|
||||
if not custom: # custom already is logged in
|
||||
login(driver, cred)
|
||||
if not custom: # custom already login
|
||||
login(driver)
|
||||
except Banned:
|
||||
log_error("This account is locked.", driver)
|
||||
return
|
||||
log_error("This account is locked. Fix that. (-U ?)", driver)
|
||||
return ()
|
||||
except Identity:
|
||||
log_error("This account has an issue.", driver)
|
||||
return
|
||||
log_error("This account has an issue. Fix that.", driver)
|
||||
return ()
|
||||
|
||||
try:
|
||||
all_cards()
|
||||
except Banned:
|
||||
log_error("banned", driver)
|
||||
raise Banned
|
||||
except Exception as err:
|
||||
log_error(err)
|
||||
return ("BANNED")
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
|
||||
try:
|
||||
fidelity()
|
||||
except Exception as err:
|
||||
log_error(err)
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
|
||||
try:
|
||||
bing_pc_search()
|
||||
except Exception as err:
|
||||
log_error(err)
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
|
||||
try:
|
||||
bing_mobile_search(cred)
|
||||
except Exception as err:
|
||||
log_error(err)
|
||||
bing_mobile_search()
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
|
||||
try:
|
||||
log_points(cred.get_mail())
|
||||
except Exception as err:
|
||||
log_error(err)
|
||||
log_points(g._mail)
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
|
||||
|
||||
def json_start(json_entry, cred: UserCredentials):
|
||||
def dev():
|
||||
pass
|
||||
|
||||
|
||||
def CustomStart():
|
||||
if not g.islinux:
|
||||
raise NameError(
|
||||
'You need to be on linux to do that, due to the utilisation of a module named enquieries, sorry.')
|
||||
global driver
|
||||
|
||||
system("clear") # clear from previous command to allow a clean choice
|
||||
actions = ["tout", "daily", "pc", "mobile", "log_points", "fidelity", "dev"]
|
||||
Actions = enquiries.choose("quels Actions ?", actions, multi=True)
|
||||
liste = select_accounts()
|
||||
g.start_time = time() # Reset timer to the start of the actions
|
||||
|
||||
for cred in liste:
|
||||
g._mail = cred[0]
|
||||
g._password = cred[1]
|
||||
if len(cred) == 3:
|
||||
g._otp = TOTP(cred[2])
|
||||
|
||||
driver = create_driver()
|
||||
driver.implicitly_wait(3)
|
||||
if login(driver) != "STOP":
|
||||
if "tout" in Actions:
|
||||
daily_routine(True)
|
||||
if "daily" in Actions:
|
||||
# input("0")
|
||||
try:
|
||||
all_cards()
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
if "pc" in Actions:
|
||||
try:
|
||||
bing_pc_search()
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
if "mobile" in Actions:
|
||||
try:
|
||||
bing_mobile_search()
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
if "fidelity" in Actions:
|
||||
try:
|
||||
fidelity()
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
if "dev" in Actions:
|
||||
try:
|
||||
dev()
|
||||
except Exception as e:
|
||||
printf(e)
|
||||
break
|
||||
if not "tout" in Actions:
|
||||
try:
|
||||
log_points(g._mail)
|
||||
except Exception as e:
|
||||
printf(f"CustomStart {e}")
|
||||
driver.quit()
|
||||
|
||||
|
||||
def very_custom_start(json):
|
||||
global driver
|
||||
display = SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=2345, color_depth=24)
|
||||
display.start()
|
||||
|
||||
for i in range(5):
|
||||
cred = g._cred[i]
|
||||
g._mail = cred[0]
|
||||
g._password = cred[1]
|
||||
if cred[2] != '':
|
||||
g._otp = TOTP(cred[2])
|
||||
|
||||
start = False
|
||||
for j in ["unban", "tout", "pc", "mobile", "daily"]:
|
||||
try:
|
||||
if str(i) in json_entry[j]:
|
||||
if str(i) in json[j]:
|
||||
start = True
|
||||
info(f"{cred.get_mail()} : {j}")
|
||||
print(f"{g._mail} : {j}")
|
||||
except KeyError:
|
||||
pass
|
||||
# print(f"none is set to \"{j}\"")
|
||||
if start:
|
||||
driver = create_driver()
|
||||
try:
|
||||
if str(i) in json_entry["unban"]:
|
||||
login_part_1(driver, cred)
|
||||
if str(i) in json["unban"]:
|
||||
pwd_login(driver) # TODO : define only the first part of login
|
||||
print("\nGO TO example.com TO PROCEED or wait 1200 secs.")
|
||||
for _ in range(1200):
|
||||
sleep(1)
|
||||
@ -716,18 +860,18 @@ def json_start(json_entry, cred: UserCredentials):
|
||||
print("proceeding")
|
||||
break
|
||||
else:
|
||||
login(driver, cred)
|
||||
login(driver)
|
||||
except KeyError:
|
||||
login(driver, cred)
|
||||
login(driver)
|
||||
try:
|
||||
if str(i) in json_entry["tout"]:
|
||||
daily_routine(cred)
|
||||
if str(i) in json["tout"]:
|
||||
daily_routine(True)
|
||||
except KeyError:
|
||||
pass
|
||||
# print("none is set to \"tout\"")
|
||||
else:
|
||||
try:
|
||||
if str(i) in json_entry["daily"]:
|
||||
if str(i) in json["daily"]:
|
||||
try:
|
||||
all_cards()
|
||||
except Exception as e:
|
||||
@ -736,71 +880,87 @@ def json_start(json_entry, cred: UserCredentials):
|
||||
pass
|
||||
# print("none is set to \"daily\"")
|
||||
try:
|
||||
if str(i) in json_entry["pc"]:
|
||||
if str(i) in json["pc"]:
|
||||
try:
|
||||
bing_pc_search()
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
except KeyError:
|
||||
pass
|
||||
# print("none is set to \"pc\"")
|
||||
try:
|
||||
if str(i) in json_entry["mobile"]:
|
||||
if str(i) in json["mobile"]:
|
||||
try:
|
||||
bing_mobile_search(cred)
|
||||
bing_mobile_search()
|
||||
except Exception as e:
|
||||
log_error(e)
|
||||
except KeyError:
|
||||
pass
|
||||
# print("none is set to \"mobile\"")
|
||||
try:
|
||||
log_points(g._mail)
|
||||
except Exception as e:
|
||||
printf(f"CustomStart {e}")
|
||||
|
||||
driver.close()
|
||||
cred.next_account()
|
||||
display.stop()
|
||||
|
||||
|
||||
c = Config(args)
|
||||
|
||||
if g.json_start:
|
||||
dict_data = json.loads(g.json_start.replace("'", "\""))
|
||||
json_start(dict_data, c.UserCredentials)
|
||||
if g.very_custom:
|
||||
dict_data = json.loads(g.very_custom.replace("'", "\""))
|
||||
very_custom_start(dict_data)
|
||||
|
||||
else:
|
||||
|
||||
if g.vnc_enabled or g.dev:
|
||||
display = SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=g.vnc_port, color_depth=24)
|
||||
else:
|
||||
display = SmartDisplay(size=(1920, 1080))
|
||||
display.start()
|
||||
|
||||
if g.update_version != "None":
|
||||
if g.discord_enabled_error:
|
||||
webhookFailure.send(f"Updated to {g.update_version}", username="UPDATE",
|
||||
avatar_url="https://cdn-icons-png.flaticon.com/512/1688/1688988.png")
|
||||
|
||||
while c.UserCredentials.is_valid():
|
||||
custom_sleep(1)
|
||||
info("Starting driver.")
|
||||
if g.dev:
|
||||
driver = create_driver()
|
||||
# input("kill ?")
|
||||
driver.quit()
|
||||
elif g.custom_start:
|
||||
CustomStart()
|
||||
elif g.unban:
|
||||
g._mail, g._password = select_accounts(False)[0]
|
||||
driver = create_driver()
|
||||
info("Driver started.")
|
||||
driver.implicitly_wait(3)
|
||||
try:
|
||||
wait_time = uniform(1200, 3600)
|
||||
info(f"Waiting for {round(wait_time / 60)}min before starting")
|
||||
daily_routine(c.UserCredentials)
|
||||
driver.quit()
|
||||
custom_sleep(wait_time)
|
||||
except KeyboardInterrupt:
|
||||
critical("Canceled by user. Closing driver and display.")
|
||||
driver.quit()
|
||||
display.stop()
|
||||
break
|
||||
except Exception as e:
|
||||
log_error(f"Error not caught. Skipping this account. " + format_error(e), driver)
|
||||
critical(f"Error not caught. Skipping this account. {e}")
|
||||
driver.quit()
|
||||
login(driver)
|
||||
except Banned:
|
||||
unban()
|
||||
driver.quit()
|
||||
else:
|
||||
if g.update_version != "None":
|
||||
if g.discord_enabled_error:
|
||||
webhookFailure.send(f"Updated to {g.update_version}", username="UPDATE",
|
||||
avatar_url="https://cdn-icons-png.flaticon.com/512/1688/1688988.png")
|
||||
for cred in g._cred:
|
||||
if cred[0] != "":
|
||||
g._mail = cred[0]
|
||||
g._password = cred[1]
|
||||
if cred[2] != '':
|
||||
g._otp = TOTP(cred[2])
|
||||
custom_sleep(1)
|
||||
printf("Début du driver.")
|
||||
driver = create_driver()
|
||||
printf("Driver demarré.")
|
||||
driver.implicitly_wait(3)
|
||||
try:
|
||||
attente = uniform(1200, 3600)
|
||||
printf(f"Attente de {round(attente / 60)} min avant de démarrer")
|
||||
daily_routine()
|
||||
driver.quit()
|
||||
custom_sleep(attente)
|
||||
except KeyboardInterrupt:
|
||||
printf("Canceled. Closing driver and display.")
|
||||
driver.quit()
|
||||
display.stop()
|
||||
break
|
||||
except Exception as e:
|
||||
log_error(f"Error not catched. Skipping this account. " + format_error(e), driver)
|
||||
printf(f"Error not catched. Skipping this account. {e}")
|
||||
driver.quit()
|
||||
|
||||
c.UserCredentials.next_account()
|
||||
|
||||
display.stop()
|
||||
display.stop()
|
||||
|
43
V7/V7.py
Normal file
43
V7/V7.py
Normal file
@ -0,0 +1,43 @@
|
||||
from playwright.sync_api import sync_playwright, expect, Page, BrowserContext
|
||||
from playwright_stealth import stealth_sync
|
||||
from pyvirtualdisplay.smartdisplay import SmartDisplay
|
||||
|
||||
from actions.cards import daily_cards, more_cards, all_cards
|
||||
from actions.login import login
|
||||
from actions.websearch import pc_search
|
||||
from tools.browser_setup import create_display, start_browser
|
||||
from tools.config import load_parameters, check_config
|
||||
from tools.logger import *
|
||||
import sys
|
||||
import json
|
||||
|
||||
|
||||
def routine(mail: str, pwd: str, vnc: bool = False) -> None:
|
||||
name = mail.split("@")[0]
|
||||
# display = create_display(vnc)
|
||||
# display.start()
|
||||
page, browser = start_browser(name)
|
||||
login(page, mail, pwd)
|
||||
all_cards(page)
|
||||
pc_search(page)
|
||||
# display.stop()
|
||||
browser.close()
|
||||
|
||||
|
||||
def main():
|
||||
data = load_parameters()
|
||||
check_config(data)
|
||||
|
||||
|
||||
# routine("EMAIL", "PWD", True)
|
||||
# parse_file({"accounts": {"nb": 1, 0: {"mail": "piair338@gmail.com", "pwd": "<PASSWORD>"}}})
|
||||
"""
|
||||
TODO :
|
||||
Fidelity management.
|
||||
Daily search mobile
|
||||
start -> with json config
|
||||
-> allow claiming
|
||||
-> default mode
|
||||
--vnc-- Should work, but not tested with WSL.
|
||||
remove unused imports
|
||||
"""
|
61
V7/actions/cards.py
Normal file
61
V7/actions/cards.py
Normal file
@ -0,0 +1,61 @@
|
||||
from playwright.sync_api import sync_playwright, expect, Page, BrowserContext
|
||||
from playwright_stealth import stealth_sync
|
||||
|
||||
from actions.quiz import play
|
||||
from tools.logger import *
|
||||
from tools.logger import *
|
||||
|
||||
|
||||
def all_cards(page: Page):
|
||||
# input("1")
|
||||
page.goto("https://rewards.bing.com")
|
||||
page.wait_for_load_state('load')
|
||||
daily_cards(page)
|
||||
more_cards(page)
|
||||
|
||||
|
||||
def daily_cards(page: Page):
|
||||
for i in range(1, 4):
|
||||
card = page.locator(f'#daily-sets > mee-card-group:nth-child(7) > div > mee-card:nth-child({i}) > div')
|
||||
if "mee-icon-AddMedium" not in card.inner_html():
|
||||
info(f'Daily Card {i} : {"Validated" if "mee-icon-AddMedium" not in card.inner_html() else "Failure"}')
|
||||
continue
|
||||
with page.expect_popup() as page1_info:
|
||||
card.click()
|
||||
page1 = page1_info.value
|
||||
stealth_sync(page1)
|
||||
page1.wait_for_load_state('load')
|
||||
try:
|
||||
selector = page1.get_by_role("button", name="Accepter")
|
||||
expect(selector).to_be_visible(timeout=10_000)
|
||||
selector.click()
|
||||
except AssertionError as e:
|
||||
pass # The RGPD button should not be there in the first place
|
||||
play(page1)
|
||||
page1.close()
|
||||
page.reload()
|
||||
info(f'Daily Card {i} : {"Validated" if "mee-icon-AddMedium" not in card.inner_html() else "Failure"}')
|
||||
|
||||
|
||||
def more_cards(page: Page):
|
||||
c = 1
|
||||
while c < 15: # todo I don't really know why it stops without raising any errors, but I guess it's fine
|
||||
card = page.locator(f"#more-activities > div > mee-card:nth-child({c})")
|
||||
|
||||
try:
|
||||
expect(card).to_be_visible(timeout=10_000)
|
||||
except Exception as e: # The card probably does not exist
|
||||
debug(e)
|
||||
break
|
||||
if "mee-icon-AddMedium" in card.inner_html():
|
||||
info(f"Playing more cards {c}.")
|
||||
with page.expect_popup() as page1_info:
|
||||
card.click()
|
||||
page1 = page1_info.value
|
||||
stealth_sync(page1)
|
||||
page1.wait_for_load_state('load')
|
||||
play(page1)
|
||||
page1.close()
|
||||
page.reload()
|
||||
info(f'More Card {c} : {"Validated" if "mee-icon-AddMedium" not in card.inner_html() else "Failure"}')
|
||||
c += 1
|
10
V7/actions/checks.py
Normal file
10
V7/actions/checks.py
Normal file
@ -0,0 +1,10 @@
|
||||
from playwright.sync_api import Playwright, sync_playwright, expect, Page
|
||||
from playwright_stealth import stealth_sync
|
||||
from logging import *
|
||||
|
||||
|
||||
def check_logged_in(page: Page):
|
||||
if "pas connecté à Microsoft Rewards" in page.content():
|
||||
page.locator('css=[onclick="setsrchusr()"]').click()
|
||||
page.wait_for_load_state('load')
|
||||
info('Fixed logging in in card.')
|
30
V7/actions/login.py
Normal file
30
V7/actions/login.py
Normal file
@ -0,0 +1,30 @@
|
||||
from playwright.sync_api import Playwright, sync_playwright, expect, Page
|
||||
from logging import *
|
||||
|
||||
|
||||
def login(page: Page, mail: str, pwd: str) -> None:
|
||||
page.goto("https://rewards.bing.com")
|
||||
page.wait_for_load_state('load')
|
||||
if page.url == "https://rewards.bing.com/":
|
||||
info("Logged in via cookies")
|
||||
return
|
||||
else:
|
||||
info("logging in")
|
||||
page.get_by_placeholder("Email, phone, or Skype").click()
|
||||
page.get_by_placeholder("Email, phone, or Skype").fill(mail)
|
||||
page.get_by_placeholder("Email, phone, or Skype").press("Enter")
|
||||
page.get_by_placeholder("Password").click()
|
||||
page.get_by_placeholder("Password").fill(pwd)
|
||||
page.get_by_placeholder("Password").press("Enter")
|
||||
page.get_by_label("Don't show this again").check()
|
||||
page.get_by_role("button", name="Yes").click()
|
||||
page.wait_for_url("https://rewards.bing.com/")
|
||||
page.wait_for_load_state('load')
|
||||
page.goto("https://bing.com")
|
||||
page.get_by_role("link", name="Sign in").click()
|
||||
page.get_by_role("link", name="Accept").click()
|
||||
page.wait_for_load_state('load')
|
||||
page.wait_for_timeout(3000)
|
||||
page.goto("https://rewards.bing.com")
|
||||
page.wait_for_load_state('load')
|
||||
info("Logged in via password.")
|
120
V7/actions/quiz.py
Normal file
120
V7/actions/quiz.py
Normal file
@ -0,0 +1,120 @@
|
||||
from random import choice, shuffle
|
||||
|
||||
from playwright.sync_api import Playwright, sync_playwright, expect, Page
|
||||
from playwright_stealth import stealth_sync
|
||||
from logging import *
|
||||
from re import findall, search
|
||||
from actions.checks import check_logged_in
|
||||
|
||||
|
||||
def play(page: Page):
|
||||
check_logged_in(page)
|
||||
quiz_type = detect_quiz_type(page)
|
||||
match quiz_type:
|
||||
case 8 | 9:
|
||||
info('Detected quiz_8.')
|
||||
play_quiz_8(page)
|
||||
case 5 | 4:
|
||||
info('Detected quiz_4.')
|
||||
play_quiz_4(page)
|
||||
case 3 | 2:
|
||||
info('Detected quiz_2.')
|
||||
play_quiz_2(page)
|
||||
case 1:
|
||||
info('Detected poll.')
|
||||
play_poll(page)
|
||||
case 0:
|
||||
info('Detected empty page.')
|
||||
|
||||
|
||||
def detect_quiz_type(page: Page) -> int:
|
||||
info("Detecting quiz type.")
|
||||
if "bt_PollRadio" in page.content():
|
||||
return 1
|
||||
else:
|
||||
try:
|
||||
# RGPD
|
||||
selector = page.locator("#rqStartQuiz")
|
||||
expect(selector).to_be_visible(timeout=10_000)
|
||||
selector.click()
|
||||
return page.content().count("rqAnswerOption") - 1
|
||||
except AssertionError as e:
|
||||
|
||||
if "rqQuestionState" in page.content():
|
||||
# The quiz is already started
|
||||
warning("Detected via recovery mode.")
|
||||
return page.content().count("rqAnswerOption") - 1
|
||||
return 0
|
||||
|
||||
|
||||
def play_quiz_8(page: Page):
|
||||
info("Playing quiz 8.")
|
||||
num_question = len(findall("<span id=\"rqQuestionState.\" class=\"emptyCircle\"></span>", page.content())) + 1
|
||||
info(f"Looping on {num_question} questions.")
|
||||
|
||||
counter = 0
|
||||
# rgpd_popup(driver)
|
||||
for _ in range(num_question):
|
||||
correct_answers = []
|
||||
for i in range(1, 9):
|
||||
|
||||
element = page.locator(f'#rqAnswerOption{i - 1}')
|
||||
# todo can probably be optimised using filter and has_text
|
||||
if 'iscorrectoption="True"' in element.evaluate("el => el.outerHTML"):
|
||||
correct_answers.append(f'#rqAnswerOption{i - 1}')
|
||||
shuffle(correct_answers)
|
||||
|
||||
for answer_id in correct_answers:
|
||||
page.locator(answer_id).click()
|
||||
page.wait_for_timeout(1000)
|
||||
page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout
|
||||
page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout
|
||||
|
||||
|
||||
def play_quiz_4(page: Page):
|
||||
info("Playing quiz 4.")
|
||||
num_question = len(findall("<span id=\"rqQuestionState.\" class=\"emptyCircle\"></span>", page.content())) + 1
|
||||
info(f"Looping on {num_question} questions.")
|
||||
|
||||
for i in range(num_question):
|
||||
txt = page.content()
|
||||
answer_option = search('correctAnswer":"([^"]+)', txt)[1]
|
||||
answer_option = answer_option.replace("\\u0027", "'") # replace Unicode weird symbols
|
||||
page.locator(f'css=[data-option="{answer_option}"]').click()
|
||||
info(f'Validated answer n°{i + 1}.')
|
||||
page.wait_for_load_state('load')
|
||||
debug(f'Next page loaded.')
|
||||
info("Quiz 4 successful.")
|
||||
|
||||
|
||||
def play_quiz_2(page: Page):
|
||||
info("Playing quiz 2.")
|
||||
for j in range(10): # todo de-hardcode the value
|
||||
js_function = """
|
||||
function get_correct_answer(){
|
||||
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 = page.evaluate(js_function)
|
||||
page.locator(f"#rqAnswerOption{correct_answer_value}").click()
|
||||
page.wait_for_timeout(2000)
|
||||
info("Quiz 2 successful.")
|
||||
page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout
|
||||
|
||||
|
||||
def play_poll(page: Page):
|
||||
info("Playing poll.")
|
||||
answer_elem = page.locator(f"#btoption{choice([0, 1])}")
|
||||
answer_elem.click()
|
||||
info("Poll successful.")
|
||||
page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout
|
25
V7/actions/websearch.py
Normal file
25
V7/actions/websearch.py
Normal file
@ -0,0 +1,25 @@
|
||||
from random import choice
|
||||
|
||||
from playwright.sync_api import sync_playwright, expect, Page
|
||||
from playwright_stealth import stealth_sync
|
||||
|
||||
h = open("../user_data/french", "r", encoding="utf-8")
|
||||
lines = h.readlines()
|
||||
if len(lines) < 3:
|
||||
Liste_de_mot = list(lines[0].split(","))
|
||||
else:
|
||||
Liste_de_mot = [x.replace('\n', "") for x in lines]
|
||||
h.close()
|
||||
|
||||
|
||||
def pc_search(page: Page) -> None:
|
||||
mot = choice(Liste_de_mot).replace(" ", "+")
|
||||
page.goto(f"https://www.bing.com/search?q={mot}")
|
||||
|
||||
for _ in range(35): # todo de-hardcode this variable
|
||||
word = choice(Liste_de_mot)
|
||||
page.get_by_label("Enter your search here -").click()
|
||||
page.get_by_label("Enter your search here -").fill(word)
|
||||
page.get_by_label("Enter your search here -").press("Enter")
|
||||
page.wait_for_load_state("load")
|
||||
page.wait_for_timeout(3000) # todo check if there is a better method than hardcoded timout
|
14
V7/config.example.json
Normal file
14
V7/config.example.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"accounts": {
|
||||
"nb": 1,
|
||||
"0": {
|
||||
"mail": "piair338@gmail.com",
|
||||
"pwd": "uéuéué"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"vnc_enabled": "False",
|
||||
"vnc_port": 2345,
|
||||
"claim": "False"
|
||||
}
|
||||
}
|
4
V7/requirement.txt
Normal file
4
V7/requirement.txt
Normal file
@ -0,0 +1,4 @@
|
||||
playwright
|
||||
pyvirtualdisplay
|
||||
playwright_stealth
|
||||
pillow
|
18
V7/tools/browser_setup.py
Normal file
18
V7/tools/browser_setup.py
Normal file
@ -0,0 +1,18 @@
|
||||
from playwright.sync_api import sync_playwright, expect, Page, BrowserContext
|
||||
from playwright_stealth import stealth_sync
|
||||
from pyvirtualdisplay.smartdisplay import SmartDisplay
|
||||
|
||||
|
||||
def create_display(vnc=False) -> SmartDisplay:
|
||||
if vnc:
|
||||
return SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=2345, color_depth=24)
|
||||
return SmartDisplay(size=(1920, 1080))
|
||||
|
||||
|
||||
def start_browser(name: str) -> (Page, BrowserContext):
|
||||
p = sync_playwright().start()
|
||||
browser = p.firefox.launch_persistent_context(f"./data/{name}/", headless=False, args=["--start-maximised"],
|
||||
no_viewport=True)
|
||||
page = browser.new_page()
|
||||
stealth_sync(page)
|
||||
return page, browser
|
47
V7/tools/config.py
Normal file
47
V7/tools/config.py
Normal file
@ -0,0 +1,47 @@
|
||||
from playwright.sync_api import sync_playwright, expect, Page, BrowserContext
|
||||
from playwright_stealth import stealth_sync
|
||||
from pyvirtualdisplay.smartdisplay import SmartDisplay
|
||||
|
||||
from actions.cards import daily_cards, more_cards, all_cards
|
||||
from actions.login import login
|
||||
from actions.websearch import pc_search
|
||||
from tools.browser_setup import create_display, start_browser
|
||||
from tools.logger import *
|
||||
import sys
|
||||
import json
|
||||
|
||||
|
||||
def check_config(data: dict) -> None:
|
||||
info("Checking config file.")
|
||||
try:
|
||||
assert data["accounts"]["nb"] != 0, "No accounts found in the file"
|
||||
for i in range(data["accounts"]["nb"]):
|
||||
assert data["accounts"][str(i)]["mail"] != "", f"Account {i} has no mail."
|
||||
assert data["accounts"][str(i)]["pwd"] != "", f"Account {i} has no password."
|
||||
assert data["config"]["vnc_enabled"] in ["True", "False"], f"vnc_enable should be either True or False."
|
||||
assert data["config"]["claim"] in ["True", "False"], f"claim should be either True or False."
|
||||
assert 1024 < data["config"]["vnc_port"] < 65535, f"vnc_port should be a valid port."
|
||||
assert data["config"]["vnc_port"] not in [1234], f"vnc_port should be different than the webserver's ports."
|
||||
except AssertionError as e:
|
||||
critical(e)
|
||||
exit(1)
|
||||
except KeyError as e:
|
||||
critical(f"Malformed config file. Missing {e}. Refer to the example config file.")
|
||||
exit(1)
|
||||
info("Successfully Checked config.")
|
||||
|
||||
|
||||
def load_parameters() -> dict:
|
||||
parameters = sys.argv
|
||||
if len(parameters) == 1:
|
||||
critical("Started with no parameters. Please provide at least a config file.")
|
||||
exit(1)
|
||||
if len(parameters) > 2:
|
||||
warning("Started with multiple parameters. Some will be ignored")
|
||||
try:
|
||||
with open(parameters[1], "r") as f:
|
||||
data = json.load(f)
|
||||
return data
|
||||
except FileNotFoundError:
|
||||
critical("Could not open the config file.")
|
||||
exit(1)
|
@ -30,7 +30,7 @@ class ColoredFormatter(logging.Formatter):
|
||||
|
||||
# Set up the root logger
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
root_logger.setLevel(logging.INFO)
|
||||
|
||||
# Create a console handler and set the formatter
|
||||
ch = logging.StreamHandler()
|
@ -1,15 +0,0 @@
|
||||
import json
|
||||
|
||||
from modules.Classes.UserCredentials import UserCredentials
|
||||
|
||||
|
||||
class Config:
|
||||
def __init__(self, args):
|
||||
self.args = args
|
||||
self.UserCredentials = UserCredentials()
|
||||
|
||||
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
|
||||
configs = json.load(inFile)
|
||||
for i in configs[str(args.config)]["accounts"]:
|
||||
d = configs[str(args.config)]["accounts"][i]
|
||||
self.UserCredentials.add(d["mail"], d["pwd"], d["2fa"])
|
@ -1,39 +0,0 @@
|
||||
import json
|
||||
from modules.Tools.logger import debug, warning
|
||||
|
||||
|
||||
class UserCredentials:
|
||||
def __init__(self):
|
||||
self.data = {}
|
||||
self.current = 0
|
||||
self.total = 0
|
||||
|
||||
def add(self, username: str, password: str, tfa: str = None):
|
||||
debug(f"adding account with data : Username: {username}, Password: {password}, 2FA: {'None' if tfa == '' else tfa}")
|
||||
self.data[self.total] = {
|
||||
"username": username,
|
||||
"password": password,
|
||||
"2fa": None if tfa == '' else tfa
|
||||
}
|
||||
self.total += 1
|
||||
|
||||
def tfa_enable(self):
|
||||
return self.data[self.current]["2fa"] is not None
|
||||
|
||||
def get_mail(self):
|
||||
return self.data[self.current]["username"]
|
||||
|
||||
def get_password(self):
|
||||
return self.data[self.current]["password"]
|
||||
|
||||
def get_tfa(self):
|
||||
if not self.tfa_enable():
|
||||
warning("Warning: TFA is not enabled. Calling get_tfa is an expected behaviour.")
|
||||
return self.data[self.current]["tfa"]
|
||||
|
||||
def next_account(self):
|
||||
self.current += 1
|
||||
debug(f"New credentials: {self.data[self.current]}")
|
||||
|
||||
def is_valid(self):
|
||||
return self.current < self.total
|
@ -4,29 +4,61 @@ from modules.imports import *
|
||||
import modules.globals as g
|
||||
import json
|
||||
|
||||
|
||||
class FakeWebHook:
|
||||
def send(self, text="", username='', avatar_url='', embed="", file=""):
|
||||
def send(self, text = "", username='', avatar_url='', embed = "", file =""):
|
||||
print(text)
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
help="Choose a specific config file",
|
||||
default=""
|
||||
"-o",
|
||||
"--override",
|
||||
help="override",
|
||||
dest="override",
|
||||
action="store_true"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"-u",
|
||||
"--unban",
|
||||
help="unban an account",
|
||||
dest="unban",
|
||||
action="store_true"
|
||||
)
|
||||
|
||||
|
||||
parser.add_argument(
|
||||
"-fl",
|
||||
"--fulllog",
|
||||
dest="fulllog",
|
||||
help="enable full logging in discord",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dev",
|
||||
dest="dev",
|
||||
help="enable dev mode",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
help="Choose a specific config file",
|
||||
default=""
|
||||
)
|
||||
|
||||
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--vnc",
|
||||
help="enable VNC",
|
||||
dest="vnc"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
help="display a message on discord to tell that the bot have been updated",
|
||||
dest="update_version",
|
||||
@ -34,8 +66,8 @@ parser.add_argument(
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--json",
|
||||
help="input json to start the bot with custom parameters",
|
||||
"--very-custom",
|
||||
help="Choose a specific config file",
|
||||
default=""
|
||||
)
|
||||
|
||||
@ -48,21 +80,31 @@ with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile:
|
||||
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
|
||||
config = json.load(inFile)
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
g.json_start = args.json
|
||||
g.custom_start = args.override
|
||||
g.unban = args.unban
|
||||
g.full_log = args.fulllog
|
||||
g.dev = args.dev
|
||||
g.very_custom = args.very_custom
|
||||
|
||||
if g.custom_start :
|
||||
g.log = True
|
||||
|
||||
g.vnc_enabled = args.vnc != "None"
|
||||
g.vnc_port = args.vnc
|
||||
g.update_version = args.update_version
|
||||
# global variables used later in the code
|
||||
|
||||
g.islinux = platform == "linux" # if the computer running this program is Linux, it allow more things
|
||||
g.start_time = time()
|
||||
|
||||
|
||||
# path configurations
|
||||
g.mot_path = "/usr/share/dict/french"
|
||||
g.credential_path = "/app/MsRewards-Reborn/user_data/login.csv"
|
||||
|
||||
|
||||
discord_conf = config[args.config]["discord"]
|
||||
|
||||
# discord configuration
|
||||
@ -73,35 +115,39 @@ g.discord_enabled_success = discord[discord_conf]["successT"] == "True"
|
||||
|
||||
g.avatar_url = settings["avatarlink"]
|
||||
|
||||
if not g.json_start:
|
||||
if not g.very_custom :
|
||||
if g.discord_enabled_error:
|
||||
webhookFailure = Webhook.from_url(g.discord_error_link, adapter=RequestsWebhookAdapter())
|
||||
if g.discord_enabled_success:
|
||||
webhookSuccess = Webhook.from_url(g.discord_success_link, adapter=RequestsWebhookAdapter())
|
||||
else:
|
||||
else :
|
||||
webhookFailure = FakeWebHook()
|
||||
webhookSuccess = FakeWebHook()
|
||||
|
||||
|
||||
# base settings
|
||||
g.discord_embed = False # send new point value in an embed, fixed for now
|
||||
g.discord_embed = False # send new point value in an embed, fixed for now
|
||||
g.headless = False
|
||||
|
||||
# proxy settings
|
||||
g.proxy_enabled = config[args.config]["proxy"] != "-1"
|
||||
if g.proxy_enabled:
|
||||
if g.proxy_enabled :
|
||||
g.proxy_address = proxy[config[args.config]["proxy"]]["address"]
|
||||
g.proxy_port = proxy[config[args.config]["proxy"]]["port"]
|
||||
|
||||
|
||||
g.fast = False
|
||||
|
||||
# list of words
|
||||
with open(g.mot_path, "r", encoding="utf-8") as h:
|
||||
lines = h.readlines()
|
||||
if len(lines) < 3:
|
||||
Liste_de_mot = list(lines[0].split(","))
|
||||
else:
|
||||
Liste_de_mot = [x.replace('\n', "") for x in lines]
|
||||
h = open(g.mot_path, "r", encoding="utf-8")
|
||||
lines = h.readlines()
|
||||
if len(lines) < 3 :
|
||||
Liste_de_mot = list(lines[0].split(","))
|
||||
else :
|
||||
Liste_de_mot = [x.replace('\n', "") for x in lines]
|
||||
h.close()
|
||||
|
||||
|
||||
if g.proxy_enabled:
|
||||
setup_proxy(g.proxy_address, g.proxy_port)
|
||||
Credentials = [ (config[args.config]['accounts'][x]["mail"],config[args.config]['accounts'][x]["pwd"],config[args.config]['accounts'][x]["2fa"]) for x in config[args.config]['accounts']]
|
||||
g._cred = Credentials
|
||||
|
||||
if g.proxy_enabled :
|
||||
setup_proxy(g.proxy_address,g.proxy_port)
|
||||
|
@ -8,7 +8,7 @@ def set_language(ldriver):
|
||||
ldriver.get("chrome://settings/languages")
|
||||
action = ActionChains(ldriver)
|
||||
action.reset_actions()
|
||||
# select language
|
||||
# select langage
|
||||
x_coord = 1200
|
||||
y_coord = 150
|
||||
action.move_by_offset(x_coord, y_coord).click().perform()
|
||||
|
@ -1,11 +1,18 @@
|
||||
driver = None
|
||||
_mail = '_mail temp'
|
||||
_password = '_password temp'
|
||||
_otp = '_otp temp'
|
||||
display = None
|
||||
log = False
|
||||
_cred = []
|
||||
custom_start = False
|
||||
unban = False
|
||||
log = False
|
||||
full_log = False
|
||||
vnc_enabled = False
|
||||
vnc_port = 2345
|
||||
points_file = "/"
|
||||
update_version = False
|
||||
islinux = True
|
||||
start_time = 0
|
||||
mot_path = "/"
|
||||
credential_path = "/"
|
||||
@ -25,6 +32,8 @@ sql_usr = "None"
|
||||
sql_pwd = "azerty"
|
||||
sql_host = "https://example.com"
|
||||
sql_database = "MsRewards"
|
||||
dev = False
|
||||
norvege = False
|
||||
database_error_override = False
|
||||
json_start = ""
|
||||
fast = False
|
||||
very_custom=""
|
Loading…
Reference in New Issue
Block a user