Compare commits

..

No commits in common. "49b691d73605490e8e4b35e57a8b501e1c337adc" and "3c9d20891cc65ea99c480b5df019a3b3f0358892" have entirely different histories.

34 changed files with 346340 additions and 998 deletions

3
.gitignore vendored
View File

@ -15,6 +15,3 @@ nohup.out
points.csv points.csv
file.png file.png
user_data/configs.json user_data/configs.json
*.ts
LICENSE
README.md

View File

@ -1,5 +1,5 @@
nohup redis-server &> nohup_redis.out & nohup bash /app/MsRewards-Reborn/sse.sh &
nohup bash /app/MsRewards-Reborn/sse.sh &> nohup_sse.out &
service grafana-server start service grafana-server start
service nginx start service nginx start
nohup redis-server &
gunicorn --reload --worker-class gevent -b 0.0.0.0:6666 'app:app' gunicorn --reload --worker-class gevent -b 0.0.0.0:6666 'app:app'

View File

@ -1,20 +0,0 @@
{
"name": "static",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/xterm": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/xterm/-/xterm-5.3.0.tgz",
"integrity": "sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg=="
},
"node_modules/xterm-addon-fit": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
"peerDependencies": {
"xterm": "^5.0.0"
}
}
}
}

View File

@ -1,2 +0,0 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(self,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core,t=e._renderService.dimensions;if(0===t.css.cell.width||0===t.css.cell.height)return;const r=0===this._terminal.options.scrollback?0:e.viewport.scrollBarWidth,i=window.getComputedStyle(this._terminal.element.parentElement),o=parseInt(i.getPropertyValue("height")),s=Math.max(0,parseInt(i.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),l=o-(parseInt(n.getPropertyValue("padding-top"))+parseInt(n.getPropertyValue("padding-bottom"))),a=s-(parseInt(n.getPropertyValue("padding-right"))+parseInt(n.getPropertyValue("padding-left")))-r;return{cols:Math.max(2,Math.floor(a/t.css.cell.width)),rows:Math.max(1,Math.floor(l/t.css.cell.height))}}}})(),e})()));
//# sourceMappingURL=xterm-addon-fit.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,26 +0,0 @@
{
"name": "xterm-addon-fit",
"version": "0.8.0",
"author": {
"name": "The xterm.js authors",
"url": "https://xtermjs.org/"
},
"main": "lib/xterm-addon-fit.js",
"types": "typings/xterm-addon-fit.d.ts",
"repository": "https://github.com/xtermjs/xterm.js",
"license": "MIT",
"keywords": [
"terminal",
"xterm",
"xterm.js"
],
"scripts": {
"build": "../../node_modules/.bin/tsc -p .",
"prepackage": "npm run build",
"package": "../../node_modules/.bin/webpack",
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^5.0.0"
}
}

View File

@ -1,209 +0,0 @@
/**
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
* https://github.com/chjj/term.js
* @license MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Originally forked from (with the author's permission):
* Fabrice Bellard's javascript vt100 for jslinux:
* http://bellard.org/jslinux/
* Copyright (c) 2011 Fabrice Bellard
* The original design remains. The terminal itself
* has been extended to include xterm CSI codes, among
* other features.
*/
/**
* Default styles for xterm.js
*/
.xterm {
cursor: text;
position: relative;
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}
.xterm.focus,
.xterm:focus {
outline: none;
}
.xterm .xterm-helpers {
position: absolute;
top: 0;
/**
* The z-index of the helpers must be higher than the canvases in order for
* IMEs to appear on top.
*/
z-index: 5;
}
.xterm .xterm-helper-textarea {
padding: 0;
border: 0;
margin: 0;
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
position: absolute;
opacity: 0;
left: -9999em;
top: 0;
width: 0;
height: 0;
z-index: -5;
/** Prevent wrapping so the IME appears against the textarea at the correct position */
white-space: nowrap;
overflow: hidden;
resize: none;
}
.xterm .composition-view {
/* TODO: Composition position got messed up somewhere */
background: #000;
color: #FFF;
display: none;
position: absolute;
white-space: nowrap;
z-index: 1;
}
.xterm .composition-view.active {
display: block;
}
.xterm .xterm-viewport {
/* On OS X this is required in order for the scroll bar to appear fully opaque */
background-color: #000;
overflow-y: scroll;
cursor: default;
position: absolute;
right: 0;
left: 0;
top: 0;
bottom: 0;
}
.xterm .xterm-screen {
position: relative;
}
.xterm .xterm-screen canvas {
position: absolute;
left: 0;
top: 0;
}
.xterm .xterm-scroll-area {
visibility: hidden;
}
.xterm-char-measure-element {
display: inline-block;
visibility: hidden;
position: absolute;
top: 0;
left: -9999em;
line-height: normal;
}
.xterm.enable-mouse-events {
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
cursor: default;
}
.xterm.xterm-cursor-pointer,
.xterm .xterm-cursor-pointer {
cursor: pointer;
}
.xterm.column-select.focus {
/* Column selection mode */
cursor: crosshair;
}
.xterm .xterm-accessibility,
.xterm .xterm-message {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 10;
color: transparent;
pointer-events: none;
}
.xterm .live-region {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
}
.xterm-dim {
/* Dim should not apply to background, so the opacity of the foreground color is applied
* explicitly in the generated class and reset to 1 here */
opacity: 1 !important;
}
.xterm-underline-1 { text-decoration: underline; }
.xterm-underline-2 { text-decoration: double underline; }
.xterm-underline-3 { text-decoration: wavy underline; }
.xterm-underline-4 { text-decoration: dotted underline; }
.xterm-underline-5 { text-decoration: dashed underline; }
.xterm-overline {
text-decoration: overline;
}
.xterm-overline.xterm-underline-1 { text-decoration: overline underline; }
.xterm-overline.xterm-underline-2 { text-decoration: overline double underline; }
.xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; }
.xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; }
.xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; }
.xterm-strikethrough {
text-decoration: line-through;
}
.xterm-screen .xterm-decoration-container .xterm-decoration {
z-index: 6;
position: absolute;
}
.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer {
z-index: 7;
}
.xterm-decoration-overview-ruler {
z-index: 8;
position: absolute;
top: 0;
right: 0;
pointer-events: none;
}
.xterm-decoration-top {
z-index: 2;
position: relative;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,100 +0,0 @@
{
"name": "xterm",
"description": "Full xterm terminal, in your browser",
"version": "5.3.0",
"main": "lib/xterm.js",
"style": "css/xterm.css",
"types": "typings/xterm.d.ts",
"repository": "https://github.com/xtermjs/xterm.js",
"license": "MIT",
"keywords": [
"cli",
"command-line",
"console",
"pty",
"shell",
"ssh",
"styles",
"terminal-emulator",
"terminal",
"tty",
"vt100",
"webgl",
"xterm"
],
"scripts": {
"prepackage": "npm run build",
"package": "webpack",
"package-headless": "webpack --config ./webpack.config.headless.js",
"postpackage-headless": "node ./bin/package_headless.js",
"start": "node demo/start",
"build-demo": "webpack --config ./demo/webpack.config.js",
"start-debug": "node --inspect-brk demo/start",
"lint": "eslint -c .eslintrc.json --max-warnings 0 --ext .ts src/ addons/",
"lint-api": "eslint --no-eslintrc -c .eslintrc.json.typings --max-warnings 0 --no-ignore --ext .d.ts typings/",
"test": "npm run test-unit",
"posttest": "npm run lint",
"test-api": "npm run test-api-chromium",
"test-api-chromium": "node ./bin/test_api.js --browser=chromium --timeout=20000",
"test-api-firefox": "node ./bin/test_api.js --browser=firefox --timeout=20000",
"test-api-webkit": "node ./bin/test_api.js --browser=webkit --timeout=20000",
"test-playwright": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4",
"test-playwright-chromium": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='Chrome Stable'",
"test-playwright-firefox": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='Firefox Stable'",
"test-playwright-webkit": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='WebKit'",
"test-playwright-debug": "playwright test -c ./out-test/playwright/playwright.config.js --headed --workers 1 --timeout 30000",
"test-unit": "node ./bin/test.js",
"test-unit-coverage": "node ./bin/test.js --coverage",
"test-unit-dev": "cross-env NODE_PATH='./out' mocha",
"build": "tsc -b ./tsconfig.all.json",
"install-addons": "node ./bin/install-addons.js",
"presetup": "npm run install-addons",
"setup": "npm run build",
"prepublishOnly": "npm run package",
"watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput",
"benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json",
"benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/test/benchmark/*benchmark.js",
"benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/test/benchmark/*benchmark.js",
"clean": "rm -rf lib out addons/*/lib addons/*/out",
"vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts"
},
"devDependencies": {
"@playwright/test": "^1.37.1",
"@types/chai": "^4.2.22",
"@types/debug": "^4.1.7",
"@types/deep-equal": "^1.0.1",
"@types/express": "4",
"@types/express-ws": "^3.0.1",
"@types/glob": "^7.2.0",
"@types/jsdom": "^16.2.13",
"@types/mocha": "^9.0.0",
"@types/node": "^18.16.0",
"@types/utf8": "^3.0.0",
"@types/webpack": "^5.28.0",
"@types/ws": "^8.2.0",
"@typescript-eslint/eslint-plugin": "^6.2.00",
"@typescript-eslint/parser": "^6.2.00",
"chai": "^4.3.4",
"cross-env": "^7.0.3",
"deep-equal": "^2.0.5",
"eslint": "^8.45.0",
"eslint-plugin-jsdoc": "^39.3.6",
"express": "^4.17.1",
"express-ws": "^5.0.2",
"glob": "^7.2.0",
"jsdom": "^18.0.1",
"mocha": "^10.1.0",
"mustache": "^4.2.0",
"node-pty": "^0.10.1",
"nyc": "^15.1.0",
"source-map-loader": "^3.0.0",
"source-map-support": "^0.5.20",
"ts-loader": "^9.3.1",
"typescript": "^5.1.6",
"utf8": "^3.0.0",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.1",
"ws": "^8.2.3",
"xterm-benchmark": "^0.3.1"
}
}

View File

@ -1,26 +0,0 @@
{
"name": "static",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
}
},
"node_modules/xterm": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/xterm/-/xterm-5.3.0.tgz",
"integrity": "sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg=="
},
"node_modules/xterm-addon-fit": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
"peerDependencies": {
"xterm": "^5.0.0"
}
}
}
}

View File

@ -1,6 +0,0 @@
{
"dependencies": {
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
}
}

View File

@ -1,48 +1,35 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block left_pannel %}override{% endblock %} {% block left_pannel %}override{% endblock %}
{% block content %} {% block content %}
{% if not current_user.is_authenticated %} {%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button> <button class="unselected" onclick="location.href = '/login';">login</button>
{% else %} {% else %}
<link rel="stylesheet" href="{{ url_for('static', filename='node_modules/xterm/css/xterm.css') }}"/> <table>
<script src="{{ url_for('static', filename='node_modules/xterm/lib/xterm.js') }}"></script> <tr>
<script src="{{ url_for('static', filename='node_modules/xterm-addon-fit/lib/xterm-addon-fit.js') }}"></script> <td width="20%" height="90%">
<script> <div id="console"></div>
document.getElementsByClassName("content")[0].style.padding = "0 0" </td>
</script> <td width="80%">
<div style="height: 100%"> <iframe src="/novnc/vnc.html?resize=scale&path=novnc/websockify&autoconnect=true&view_only" width="100%" height="100%" frameborder="0"></iframe>
</td>
</tr>
</table>
<div id="console" style="height: 100%; width: 20%; float:left;"></div>
<div style="height: 100%; width: 80%; float:left;">
<iframe src="/novnc/vnc.html?resize=scale&path=novnc/websockify&autoconnect=true&view_only"
width="100%" height="100%" frameborder="0"></iframe>
</div>
</div>
<script> <script>
var term = new Terminal(); const consoleElement = document.getElementById('console');
const fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(document.getElementById('console'));
fitAddon.fit()
addEventListener("transitionend", (event) => {
fitAddon.fit()
});
document.getElementById("console").style.textAlign = "left"
const eventSource = new EventSource('/stream'); const eventSource = new EventSource('/stream');
eventSource.onmessage = (event) => { eventSource.onmessage = (event) => {
term.writeln(event.data) document.getElementById("console").innerHTML = event.data + document.getElementById("console").innerHTML
}; };
addEventListener("resize", (event) => {
fitAddon.fit()
});
</script>
{% endif %} </script>
{% endblock %} {% endif %}
{%endblock %}

547
V6.py
View File

@ -1,43 +1,84 @@
#!/usr/bin/python3.10 #!/usr/bin/python3.10
from modules.Classes.Config import Config
from modules.Classes.DiscordLogger import DiscordLogger
from modules.Classes.UserCredentials import UserCredentials
from modules.Tools.logger import warning, critical
from modules.cards import *
from modules.config import * from modules.config import *
from modules.db import add_to_database
from modules.driver_tools import *
from modules.error import * from modules.error import *
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 # create a webdriver
def create_driver(mobile=False): def create_driver(mobile=False):
pc_user_agent = ( PC_USER_AGENT = (
"Mozilla/5.0 (X11; Linux x86_64)" "Mozilla/5.0 (X11; Linux x86_64)"
"AppleWebKit/537.36 (KHTML, like Gecko)" "AppleWebKit/537.36 (KHTML, like Gecko)"
"Chrome/122.0.0.0 Safari/537.36 Edg/122.0.2088.46" "Chrome/122.0.0.0 Safari/537.36 Edg/122.0.2088.46"
) )
mobile_user_agent = ( MOBILE_USER_AGENT = (
"Mozilla/5.0 (Linux; Android 7.0; Nexus 5 Build/MRA58N)" "Mozilla/5.0 (Linux; Android 7.0; Nexus 5 Build/MRA58N)"
"AppleWebKit/537.36 (KHTML, like Gecko)" "AppleWebKit/537.36 (KHTML, like Gecko)"
"Chrome/22 Mobile Safari/537.36" "Chrome/22 Mobile Safari/537.36"
) )
chrome_options = webdriver.ChromeOptions() chrome_options = webdriver.ChromeOptions()
if mobile: if mobile:
chrome_options.add_argument(f"--user-agent={mobile_user_agent}") chrome_options.add_argument(f"--user-agent={MOBILE_USER_AGENT}")
else: else:
chrome_options.add_argument(f"--user-agent={pc_user_agent}") chrome_options.add_argument(f"--user-agent={PC_USER_AGENT}")
# disabled as it may cause detection # disabled as it may cause detection
if config.proxy.is_enabled(): if g.proxy_enabled:
chrome_options.add_argument(f'--proxy-server={config.proxy.ip}:{config.proxy.port}') chrome_options.add_argument(f'--proxy-server={g.proxy_address}:{g.proxy_port}')
driver = uc.Chrome(options=chrome_options) driver = uc.Chrome(options=chrome_options)
set_language(driver) set_language(driver)
return driver return driver
def log_error(error_message, 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 g.discord_enabled_error:
with open("page.html", "w") as f:
try:
f.write(l_driver.page_source)
except:
f.write("the driver has closed or crashed. Can't access page content")
try:
img = display.waitgrab()
img.save("screenshot.png")
except:
l_driver.save_screenshot("screenshot.png")
if not log:
embed = Embed(
title="An Error has occured",
description=str(error_message),
colour=Colour.red(),
)
else:
embed = Embed(
title="Full log is enabled",
description=str(error_message),
colour=Colour.blue(),
)
file = File("screenshot.png")
embed.set_image(url="attachment://screenshot.png")
embed.set_footer(text=g._mail)
webhookFailure.send(embed=embed, username="error", file=file, avatar_url=g.avatar_url)
webhookFailure.send(username="error", file=File("page.html"), avatar_url=g.avatar_url)
# close the tab currently on and go back to the one first, or the one specified # 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, switch_to: int = 0) -> None:
driver = config.WebDriver.driver
driver.switch_to.window(tab) driver.switch_to.window(tab)
driver.close() driver.close()
driver.switch_to.window(driver.window_handles[switch_to]) driver.switch_to.window(driver.window_handles[switch_to])
@ -48,18 +89,13 @@ def close_tab(tab, switch_to: int = 0) -> None:
# Can be useful in some case, where the program crashes before finishing the quiz # Can be useful in some case, where the program crashes before finishing the quiz
def play_quiz2(override=10) -> None: def play_quiz2(override=10) -> None:
info("Starting to play quiz 2.") info("Starting to play quiz 2.")
driver = config.WebDriver.driver
debug(f"override: {override}") debug(f"override: {override}")
for j in range(override): for j in range(override):
custom_sleep(uniform(3, 5)) custom_sleep(uniform(3, 5))
js_function = """ js_function = """
function get_correct_answer(){ function get_correct_answer(){
function br(n) { 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
for (var r, t = 0, i = 0; i < n.length; i++) function namedRAValue() { //allow calls to getRAvalue
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() return _w.getRAValue()
}; };
if (br(document.getElementById("rqAnswerOption0").attributes["data-option"].value) == namedRAValue()){ if (br(document.getElementById("rqAnswerOption0").attributes["data-option"].value) == namedRAValue()){
@ -86,7 +122,6 @@ def play_quiz2(override=10) -> None:
def play_quiz8(): def play_quiz8():
driver = config.WebDriver.driver
info(f"Starting Quiz 8") info(f"Starting Quiz 8")
override = len(findall("<span id=\"rqQuestionState.\" class=\"emptyCircle\"></span>", driver.page_source)) + 1 override = len(findall("<span id=\"rqQuestionState.\" class=\"emptyCircle\"></span>", driver.page_source)) + 1
debug(f"override : {override}") debug(f"override : {override}")
@ -95,13 +130,13 @@ def play_quiz8():
for _ in range(override): for _ in range(override):
sleep(uniform(3, 5)) sleep(uniform(3, 5))
correct_answers = [] correct_answers = []
for i in range(8): for i in range(1, 9): # todo: remove this odd 1-offset
try: try:
element = driver.find_element(By.ID, f"rqAnswerOption{i}") element = driver.find_element(By.ID, f"rqAnswerOption{i - 1}")
if 'iscorrectoption="True"' in element.get_attribute("outerHTML"): if 'iscorrectoption="True"' in element.get_attribute("outerHTML"):
correct_answers.append(f'rqAnswerOption{i}') correct_answers.append(f'rqAnswerOption{i - 1}')
except Exception as e: except Exception as e:
warning(f"can't find rqAnswerOption{i}. Probably already clicked" + str(e)) warning(f"can't find rqAnswerOption{i - 1}. Probably already clicked" + str(e))
shuffle(correct_answers) shuffle(correct_answers)
for answer_id in correct_answers: for answer_id in correct_answers:
wait_until_visible(By.ID, answer_id, timeout=20, browser=driver) wait_until_visible(By.ID, answer_id, timeout=20, browser=driver)
@ -115,25 +150,22 @@ def play_quiz8():
answer_elem = driver.find_element(By.ID, answer_id) answer_elem = driver.find_element(By.ID, answer_id)
answer_elem.click() answer_elem.click()
except ElementClickInterceptedException: except ElementClickInterceptedException:
rgpd_popup(config) rgpd_popup(driver)
correct_answers.append(answer_id) correct_answers.append(answer_id)
except Exception as e: except Exception as e:
log_error(f"{format_error(e)} \n Good answers : {' '.join(correct_answers)}") log_error(f"{format_error(e)} \n Good answers : {' '.join(correct_answers)}")
raise ValueError(format_error(e))
info("Quiz 8 done.") info("Quiz 8 done.")
custom_sleep(3) custom_sleep(3)
def play_quiz4(override: int = None): def play_quiz4(override: int = None):
info(f"Starting Quiz 4") info(f"Starting Quiz 4")
driver = config.WebDriver.driver
if not override: if not override:
try: # fidelity quiz are much longer than usual ones try: # fidelity quiz are much longer than usual ones
override = int(findall('rqQuestionState([\d]{1,2})"', driver.page_source)[-1]) override = int(findall('rqQuestionState([\d]{1,2})"', driver.page_source)[-1])
except Exception as err: except:
debug(err)
override = 3 override = 3
debug(f"Override : {override}") debug(f"Override : {override}")
@ -159,14 +191,11 @@ def play_quiz4(override: int = None):
# do_poll() answer a random thing to poll, on of daily activities # do_poll() answer a random thing to poll, on of daily activities
def do_poll(): def do_poll():
info("Starting poll") info("Starting poll")
driver = config.WebDriver.driver
try: try:
answer_elem = driver.find_element(By.ID, f"btoption{choice([0, 1])}") answer_elem = driver.find_element(By.ID, f"btoption{choice([0, 1])}")
try: try:
answer_elem.click() answer_elem.click()
except exceptions.ElementNotInteractableException: except exceptions.ElementNotInteractableException:
warning("element not clickable. Waiting a bit and retrying.")
custom_sleep(uniform(2, 2.5))
driver.execute_script("arguments[0].click();", answer_elem) driver.execute_script("arguments[0].click();", answer_elem)
custom_sleep(uniform(2, 2.5)) custom_sleep(uniform(2, 2.5))
except Exception as err: except Exception as err:
@ -177,95 +206,106 @@ def do_poll():
# Find each playable card and tries to click on it to earn points # Find each playable card and tries to click on it to earn points
# todo : refactor
def all_cards(): def all_cards():
driver = config.WebDriver.driver
driver.get("https://rewards.bing.com") driver.get("https://rewards.bing.com")
wait_until_visible(By.CLASS_NAME, "c-card-content", 10, driver) wait_until_visible(By.CLASS_NAME, "c-card-content", 10, driver)
liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
custom_sleep(2) custom_sleep(2)
try: try:
promo() promo()
except Exception as e: except Exception as e:
debug(e)
info("no promo card") info("no promo card")
if (len(liste) < 10): # most likely an error during loading
if len(card_list) < 10: # most likely an error during loading
if "suspendu" in driver.page_source: if "suspendu" in driver.page_source:
raise Banned() raise Banned()
driver.refresh() driver.refresh()
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content") liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
if len(card_list) < 10: if (len(liste) < 10):
log_error("Less than 10 cards. Most likely an error with login.") log_error("Less than 10 cards. Most likely an error with login.", driver)
return "Not enough cards" return ("PAS ASSEZ DE CARTES")
if (len(liste) < 20): # most likely not in france
for i in range(len(card_list)): printf("moins de 20 cartes. Probablement pas en France.")
debug(f"carte {i}") for i in range(len(liste)):
checked = False printf(f"carte {i}")
try: try:
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML") checked = ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML"))
except StaleElementReferenceException: except StaleElementReferenceException:
driver.refresh() driver.refresh()
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content") liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
warning(f"staled, {len(card_list)}") printf(f"staled, {len(liste)}")
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML") checked = ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML"))
except IndexError: except IndexError:
driver.get("https://rewards.bing.com") driver.get("https://rewards.bing.com")
custom_sleep(10) custom_sleep(10)
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content") liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
try: try:
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML") checked = ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML"))
except IndexError: except IndexError:
if i == len(card_list) and i > 15: if i == len(liste) & i > 15:
checked = False checked = False
# input("2")
if checked: if checked:
custom_sleep(1.5) custom_sleep(1.5)
driver.execute_script("arguments[0].scrollIntoView();", card_list[i]) driver.execute_script("arguments[0].scrollIntoView();", liste[i])
custom_sleep(1.5) custom_sleep(1.5)
card_list[i].click() # input("3")
liste[i].click()
# input("4")
if len(driver.window_handles) > 1: if len(driver.window_handles) > 1:
driver.switch_to.window(driver.window_handles[1]) driver.switch_to.window(driver.window_handles[1])
# input("5")
try_play(driver.title)
close_tab(driver.window_handles[1])
try:
driver.refresh()
liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
if ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML")):
printf(f"carte {i} not okay. Retrying.")
try:
liste[i].click()
except:
log_error("problème inconnu ? sauf si c'est un element obscure...", driver)
driver.get("https://rewards.bing.com")
checked = ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML"))
driver.switch_to.window(driver.window_handles[1])
try_play(driver.title) try_play(driver.title)
close_tab(driver.window_handles[1]) close_tab(driver.window_handles[1])
if ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML")):
try: driver.execute_script("arguments[0].scrollIntoView();", liste[i])
driver.refresh() log_error(f"Card {i} Can't be completed. Why MS ?", driver)
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content") liste[i].click()
if "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML"):
driver.execute_script("arguments[0].scrollIntoView();", card_list[i])
card_list[i].click()
driver.switch_to.window(driver.window_handles[1]) driver.switch_to.window(driver.window_handles[1])
log_error(f"Cart completion - log - 2", driver)
custom_sleep(10) custom_sleep(10)
log_error(f"Card {i} Can't be completed. Why MS ?") log_error(f"Cart completion - log - 3 - after 10 sec", driver)
try: try:
try_play(driver.title) # go back to the main page try_play(driver.title) # go back to the main page
try: try:
close_tab(driver.window_handles[1]) close_tab(driver.window_handles[1])
except Exception as e: except:
debug(e) pass
except Exception as e: except:
debug(e) driver.get("https://rewards.bing.com")
except:
pass
else:
try:
welcome_tour(liste[i], driver)
except Exception as e:
printf("no new windows" + format_error(e))
driver.get("https://rewards.bing.com") driver.get("https://rewards.bing.com")
except Exception as err:
log_error(err)
custom_sleep(3) custom_sleep(3)
def promo(): def promo():
driver = config.WebDriver.driver
for i in range(5): for i in range(5):
elm = driver.find_element(By.ID, "promo-item") elm = driver.find_element(By.ID, "promo-item")
wait_until_visible(By.ID, "promo-item", 5, driver) wait_until_visible(By.ID, "promo-item", 5, driver)
if not elm: if not elm:
break break
if i > 3: if i > 3:
log_error("There is more than 3 promo cards, most likely an unskippable one.") log_error("plus de 3 promo cards, probablement une pa skipable", driver)
try: try:
driver.find_element(By.CSS_SELECTOR, driver.find_element(By.CSS_SELECTOR,
'i[class="mee-icon pull-left icon mee-icon-Cancel ng-scope"]').click() 'i[class="mee-icon pull-left icon mee-icon-Cancel ng-scope"]').click()
@ -275,8 +315,10 @@ def promo():
try: try:
elm.click() elm.click()
except Exception as e: except Exception as e:
# log_error(e, driver)
driver.execute_script("arguments[0].click();", elm) driver.execute_script("arguments[0].click();", elm)
warning(f"that shouldn't be there (promo), but the workaround seemed to work {e}") # log_error(e, driver)
printf(f"that should't be there (promo), but the workarround seemed to work {e}")
custom_sleep(3) custom_sleep(3)
if len(driver.window_handles) > 1: if len(driver.window_handles) > 1:
driver.switch_to.window(driver.window_handles[len(driver.window_handles) - 1]) driver.switch_to.window(driver.window_handles[len(driver.window_handles) - 1])
@ -285,17 +327,16 @@ def promo():
else: else:
try: try:
spotify(driver) spotify(driver)
except Exception as e: except:
warning(f"no new windows {format_error(e)}") warning("no new windows")
driver.get("https://rewards.bing.com") driver.get("https://rewards.bing.com")
driver.refresh() driver.refresh()
custom_sleep(3) custom_sleep(3)
# Find out which type of action to do # Find out which type of action to do
def try_play(nom="unknown"): def try_play(nom="inconnu"):
driver = config.WebDriver.driver rgpd_popup(driver)
rgpd_popup(config)
def play(number): def play(number):
if number in [8, 9]: if number in [8, 9]:
@ -327,7 +368,7 @@ def try_play(nom="unknown"):
custom_sleep(5) custom_sleep(5)
driver.find_element(By.CSS_SELECTOR, '[onclick="setsrchusr()"]').click() driver.find_element(By.CSS_SELECTOR, '[onclick="setsrchusr()"]').click()
custom_sleep(5) custom_sleep(5)
rgpd_popup(config) rgpd_popup(driver)
custom_sleep(5) custom_sleep(5)
debug("Detected and fixed connection popup") debug("Detected and fixed connection popup")
@ -335,6 +376,11 @@ def try_play(nom="unknown"):
debug("Poll detected") debug("Poll detected")
do_poll() do_poll()
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): elif search("([0-9]) de ([0-9]) finalisée", driver.page_source):
info("On fidelity page.") info("On fidelity page.")
fidelity() fidelity()
@ -345,102 +391,93 @@ def try_play(nom="unknown"):
answer_number = driver.page_source.count("rqAnswerOption") answer_number = driver.page_source.count("rqAnswerOption")
play(answer_number) play(answer_number)
elif "rqQuestionState" in driver.page_source:
number = driver.page_source.count("rqAnswerOption")
warning(f"recovery detected. quiz : {number}")
play(number - 1)
else: else:
info(f"Nothing to do on page `{nom}`") printf(f"Nothing to do on page `{nom}`")
custom_sleep(uniform(3, 5)) custom_sleep(uniform(3, 5))
# Login with password or with cookies. # Login with password or with cookies.
# The driver should be in the same state on both case # The driver should be in the same state on both case
def login_part_1(): def login_part_1(ldriver, cred: UserCredentials):
info("Starting part 1 of login") printf("pwd_login : start")
driver = config.WebDriver.driver ldriver.get("https://login.live.com")
driver.get("https://login.live.com") wait_until_visible(By.ID, "i0116", browser=ldriver)
wait_until_visible(By.ID, "i0116", browser=driver) mail_elem = ldriver.find_element(By.ID, "i0116")
mail_elem = driver.find_element(By.ID, "i0116") send_keys_wait(mail_elem, cred.get_mail())
send_keys_wait(mail_elem, config.UserCredentials.get_mail())
mail_elem.send_keys(Keys.ENTER) mail_elem.send_keys(Keys.ENTER)
wait_until_visible(By.ID, "i0118", browser=driver) wait_until_visible(By.ID, "i0118", browser=ldriver)
pwd_elem = driver.find_element(By.ID, "i0118") pwd_elem = ldriver.find_element(By.ID, "i0118")
send_keys_wait(pwd_elem, config.UserCredentials.get_password()) send_keys_wait(pwd_elem, cred.get_password())
pwd_elem.send_keys(Keys.ENTER) pwd_elem.send_keys(Keys.ENTER)
custom_sleep(2) custom_sleep(2)
# 2FA # 2FA
if "Entrez le code de sécurité" in driver.page_source: if "Entrez le code de sécurité" in ldriver.page_source:
try: try:
a2f_elem = driver.find_element(By.ID, "idTxtBx_SAOTCC_OTC") a2f_elem = ldriver.find_element(By.ID, "idTxtBx_SAOTCC_OTC")
a2f_elem.send_keys(config.UserCredentials.get_tfa().now()) a2f_elem.send_keys(g._otp.now())
a2f_elem.send_keys(Keys.ENTER) a2f_elem.send_keys(Keys.ENTER)
except Exception as err: except Exception as e:
log_error(err) log_error(e)
# Accept all cookies question, and check if the account is locked # Accept all cookies question, and check if the account is locked
def login_part_2(): def login_part_2(ldriver):
driver = config.WebDriver.driver
custom_sleep(5) custom_sleep(5)
if 'Abuse' in driver.current_url: if 'Abuse' in ldriver.current_url:
raise Banned() raise Banned()
if 'identity' in driver.current_url: if 'identity' in ldriver.current_url:
raise Identity() raise Identity()
if 'notice' in driver.current_url: if 'notice' in ldriver.current_url:
driver.find_element(By.ID, "id__0").click() ldriver.find_element(By.ID, "id__0").click()
if "proof" in driver.current_url: if "proof" in ldriver.current_url:
driver.find_element(By.ID, "iLooksGood") ldriver.find_element(By.ID, "iLooksGood")
for elm_id in ["checkboxField", "KmsiCheckboxField", "acceptButton", "iNext", "id__0", "iLooksGood", "idSIButton9", for elm_id in ["iNext", "KmsiCheckboxField", "id__0", "iLooksGood", "idSIButton9", "iCancel"]:
"iCancel"]: if get_domain(ldriver) == "account.microsoft.com":
if get_domain(driver) == "account.microsoft.com":
break break
try: try:
driver.find_element(By.ID, elm_id).click() ldriver.find_element(By.ID, elm_id).click()
except Exception as e: except Exception as e:
debug(e) pass
wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 20, driver) wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 20, ldriver)
# login() tries to login to your Microsoft account. # login() tries to login to your Microsoft account.
# it uses global variable g._mail and g._password to login # it uses global variable g._mail and g._password to login
def login(): def login(ldriver, cred: UserCredentials):
driver = config.WebDriver.driver
try: try:
login_part_1() login_part_1(ldriver, cred)
login_part_2() login_part_2(ldriver)
driver.get("https://rewards.bing.com/") ldriver.get("https://rewards.bing.com/")
except Banned: except Banned:
raise Banned() raise Banned()
except Identity: except Identity:
raise Banned() raise Banned()
except Exception as err: except Exception as e:
critical("Error not caught during login." + format_error(err)) critical("Error not caught during login.")
log_error(err) log_error(e)
driver.quit() ldriver.quit()
return False return False
# Makes 30 search as PC Edge # Makes 30 search as PC Edge
def bing_pc_search(override=randint(35, 40)): def bing_pc_search(override=randint(35, 40)):
driver = config.WebDriver.driver mot = choice(Liste_de_mot).replace(" ", "+")
driver.get(f"https://www.bing.com/search?q={config.wordlist.get_word().replace(' ', '+')}") driver.get(f"https://www.bing.com/search?q={mot}")
custom_sleep(uniform(1, 2)) custom_sleep(uniform(1, 2))
rgpd_popup(config) rgpd_popup(driver)
send_keys_wait( send_keys_wait(
driver.find_element(By.ID, "sb_form_q"), driver.find_element(By.ID, "sb_form_q"),
Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE
) )
for _ in range(override): for _ in range(override):
word = config.wordlist.get_word() word = choice(Liste_de_mot)
try: try:
send_keys_wait(driver.find_element(By.ID, "sb_form_q"), word) send_keys_wait(driver.find_element(By.ID, "sb_form_q"), word)
driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER) driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER)
@ -463,25 +500,37 @@ def bing_pc_search(override=randint(35, 40)):
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)}") # what is this message ??? todo
# Sends current account's points to database # Sends points to database, discord and whatever service you want
def log_points(): # todo: refactor
driver = config.WebDriver.driver def log_points(account="unknown"):
account = config.UserCredentials.get_mail() def get_points():
driver.get("https://rewards.bing.com") driver.get("https://rewards.bing.com")
custom_sleep(1) custom_sleep(1)
wait_until_visible(By.CSS_SELECTOR, 'span[mee-element-ready="$ctrl.loadCounterAnimation()"]', browser=driver) wait_until_visible(By.CSS_SELECTOR, 'span[mee-element-ready="$ctrl.loadCounterAnimation()"]', browser=driver)
try: try:
points = search('availablePoints\":([\d]+)', driver.page_source)[1] point = search('availablePoints\":([\d]+)', driver.page_source)[1]
except Exception as err: except Exception as e:
log_error( log_error(
f"Dev error, checking why it doesn't work (waited a bit, is this still white ?) {format_error(err)}") f"Dev error, checking why it doesn't work (waited a bit, is this still white ?) {format_error(e)}",
error(f"Can't get points. {format_error(err)}") driver)
error("Can't get points.")
return -1 return -1
return point
points = get_points()
custom_sleep(uniform(3, 20)) custom_sleep(uniform(3, 20))
account_name = account.split("@")[0] account_name = account.split("@")[0]
if g.discord_enabled_success:
if g.discord_embed:
embed = Embed(
title=f"{account_name} actuellement à {str(points)} points", colour=Colour.green()
)
embed.set_footer(text=account_name)
webhookSuccess.send(embed=embed)
else:
webhookSuccess.send(f"{account_name} actuellement à {str(points)} points")
try: try:
add_to_database(account_name, points) add_to_database(account_name, points)
except Exception as e: except Exception as e:
@ -490,8 +539,6 @@ def log_points():
# todo: refactor and check if it works at all # todo: refactor and check if it works at all
def fidelity(): def fidelity():
driver = config.WebDriver.driver
def sub_fidelity(): def sub_fidelity():
try: try:
wait_until_visible(By.CSS_SELECTOR, 'div[class="pull-left spacer-48-bottom punchcard-row"]', browser=driver) wait_until_visible(By.CSS_SELECTOR, 'div[class="pull-left spacer-48-bottom punchcard-row"]', browser=driver)
@ -511,15 +558,15 @@ def fidelity():
try: try:
button_text = search('<span class="pull-left margin-right-15">([^<^>]+)</span>', button_text = search('<span class="pull-left margin-right-15">([^<^>]+)</span>',
card_elem.get_attribute("innerHTML"))[1] card_elem.get_attribute("innerHTML"))[1]
button_card = driver.find_element(By.XPATH, f'//span[text()="{button_text}"]') bouton_card = driver.find_element(By.XPATH, f'//span[text()="{button_text}"]')
button_card.click() bouton_card.click()
except Exception as e1: except Exception as e1:
try: try:
recover_elem = driver.find_element(By.XPATH, 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') '/html/body/div[1]/div[2]/main/div[2]/div[2]/div[7]/div[3]/div[1]/a')
recover_elem.click() recover_elem.click()
except Exception as e2: except Exception as e2:
log_error(f"Fidelity: Multiples error - e1 : {format_error(e1)} - e2 {format_error(e2)}") log_error(f"fidélité - double erreur - e1 : {format_error(e1)} - e2 {format_error(e2)}")
break break
custom_sleep(uniform(3, 5)) custom_sleep(uniform(3, 5))
driver.switch_to.window(driver.window_handles[2]) driver.switch_to.window(driver.window_handles[2])
@ -527,25 +574,26 @@ def fidelity():
custom_sleep(uniform(3, 5)) custom_sleep(uniform(3, 5))
try: try:
close_tab(driver.window_handles[2], 1) close_tab(driver.window_handles[2], 1)
except Exception as err: except Exception as e:
error(err) printf(e)
info("fidelity - done") printf("fidelity - done")
except Exception as err: except Exception as e:
log_error(err) log_error(e)
if driver.current_url != "https://rewards.bing.com": if driver.current_url != "https://rewards.bing.com":
driver.get("https://rewards.bing.com") driver.get("https://rewards.bing.com")
try: try:
pause = driver.find_element(By.CSS_SELECTOR, f'[class="c-action-toggle c-glyph f-toggle glyph-pause"]') pause = driver.find_element(By.CSS_SELECTOR,
f'[class="c-action-toggle c-glyph f-toggle glyph-pause"]') # mettre le truc en pause
pause.click() pause.click()
except Exception as e: except Exception as e:
error(f"Error while clicking pause. Probably no cards. {e}") printf(f"erreur lors du click de pause: probablement pas de cartes {e}")
return "no cards" return ("no cards")
cartes = driver.find_elements(By.CSS_SELECTOR, f'[ng-repeat="item in $ctrl.transcludedItems"]') cartes = driver.find_elements(By.CSS_SELECTOR, f'[ng-repeat="item in $ctrl.transcludedItems"]')
nb_cartes = len(cartes) nb_cartes = len(cartes)
checked_list_all = driver.find_elements(By.CSS_SELECTOR, f'[ng-if="$ctrl.complete"]') checked_list_all = driver.find_elements(By.CSS_SELECTOR, f'[ng-if="$ctrl.complete"]')
for i in range(nb_cartes): for i in range(nb_cartes):
cartes[i].click() cartes[i].click() # affiche la bonne carte
checked_txt = checked_list_all[i].get_attribute("innerHTML") checked_txt = checked_list_all[i].get_attribute("innerHTML")
ok = checked_txt.count("StatusCircleOuter checkmark") ok = checked_txt.count("StatusCircleOuter checkmark")
total = checked_txt.count("StatusCircleOuter") total = checked_txt.count("StatusCircleOuter")
@ -562,67 +610,61 @@ def fidelity():
def mobile_alert_popup(): def mobile_alert_popup():
driver = config.WebDriver.driver
try: try:
alert = driver.switch_to.alert alert = mobile_driver.switch_to.alert
alert.dismiss() alert.dismiss()
except exceptions.NoAlertPresentException: except exceptions.NoAlertPresentException:
pass pass
except Exception as err: except Exception as err:
log_error(err) log_error(err, mobile_driver)
# todo: be coherent with pc search regarding error management # todo: be coherent with pc search regarding error management
def bing_mobile_search(cred: UserCredentials, override=randint(22, 25)): def bing_mobile_search(cred: UserCredentials, override=randint(22, 25)):
config.WebDriver.set_mobile_driver(create_driver(mobile=True)) global mobile_driver
config.WebDriver.switch_to_driver("Mobile") mobile_driver = create_driver(mobile=True)
driver = config.WebDriver.driver
try: try:
login() login(mobile_driver, cred)
mot = config.wordlist.get_word().replace(" ", "+") mot = choice(Liste_de_mot).replace(" ", "+")
driver.get(f"https://www.bing.com/search?q={mot}") mobile_driver.get(f"https://www.bing.com/search?q={mot}")
custom_sleep(uniform(1, 2)) custom_sleep(uniform(1, 2))
rgpd_popup(config) rgpd_popup(mobile_driver)
custom_sleep(uniform(1, 1.5)) custom_sleep(uniform(1, 1.5))
for i in range(override): # 20 for i in range(override): # 20
try: try:
mot = config.wordlist.get_word() mot = choice(Liste_de_mot)
send_keys_wait(driver.find_element(By.ID, "sb_form_q"), mot) send_keys_wait(mobile_driver.find_element(By.ID, "sb_form_q"), mot)
driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER) mobile_driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER)
custom_sleep(uniform(3, 7)) custom_sleep(uniform(3, 7))
mobile_alert_popup() # check for alert (asking for position or for allowing notifications) mobile_alert_popup() # check for alert (asking for position or for allowing notifications)
driver.find_element(By.ID, "sb_form_q").clear() mobile_driver.find_element(By.ID, "sb_form_q").clear()
except Exception as err: except Exception as err:
error(err) error(err)
driver.refresh() mobile_driver.refresh()
custom_sleep(30) custom_sleep(30)
i -= 1 i -= 1
driver.quit() mobile_driver.quit()
except Exception as err: except Exception as err:
log_error(err) log_error(err, mobile_driver)
driver.quit() mobile_driver.quit()
finally:
config.WebDriver.switch_to_driver("PC")
def daily_routine(cred: UserCredentials, custom=False): def daily_routine(cred: UserCredentials, custom=False):
try: try:
if not custom: # custom already is logged in if not custom: # custom already is logged in
login() login(driver, cred)
except Banned: except Banned:
log_error("This account is locked.") log_error("This account is locked.", driver)
return return
except Identity: except Identity:
log_error("This account has an issue.") log_error("This account has an issue.", driver)
return return
try: try:
all_cards() all_cards()
except Banned: except Banned:
log_error("banned") log_error("banned", driver)
raise Banned raise Banned
except Exception as err: except Exception as err:
log_error(err) log_error(err)
@ -643,59 +685,58 @@ def daily_routine(cred: UserCredentials, custom=False):
log_error(err) log_error(err)
try: try:
log_points() log_points(cred.get_mail())
except Exception as err: except Exception as err:
log_error(err) log_error(err)
def json_start(json_entry, cred: UserCredentials): def json_start(json_entry, cred: UserCredentials):
json_entry = json.loads(json_entry) global driver
display = SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=2345, color_depth=24)
display.start()
config.set_display(SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=2345, color_depth=24)) for i in range(5):
config.display.start()
account_id = 0
while config.UserCredentials.is_valid():
start = False start = False
for action in ["unban", "tout", "pc", "mobile", "daily"]: for j in ["unban", "tout", "pc", "mobile", "daily"]:
try: try:
if str(account_id) in json_entry[action]: if str(i) in json_entry[j]:
start = True start = True
info(f"{cred.get_mail()} : {action}") info(f"{cred.get_mail()} : {j}")
except KeyError: except KeyError:
pass pass
if start: if start:
config.WebDriver.set_pc_driver(create_driver()) driver = create_driver()
config.WebDriver.switch_to_driver("PC")
driver = config.WebDriver.driver
try: try:
if str(account_id) in json_entry["unban"]: if str(i) in json_entry["unban"]:
login_part_1() login_part_1(driver, cred)
info("\nGO TO example.com TO PROCEED or wait 1200 secs.") print("\nGO TO example.com TO PROCEED or wait 1200 secs.")
for _ in range(1200): for _ in range(1200):
sleep(1) sleep(1)
if driver.current_url == "https://example.com/": if driver.current_url == "https://example.com/":
info("proceeding") print("proceeding")
break break
else: else:
login() login(driver, cred)
except KeyError: except KeyError:
login() login(driver, cred)
try: try:
if str(account_id) in json_entry["tout"]: if str(i) in json_entry["tout"]:
daily_routine(cred, True) daily_routine(cred)
except KeyError: except KeyError:
pass pass
# print("none is set to \"tout\"")
else: else:
try: try:
if str(account_id) in json_entry["daily"]: if str(i) in json_entry["daily"]:
try: try:
all_cards() all_cards()
except Exception as e: except Exception as e:
log_error(e) log_error(e)
except KeyError: except KeyError:
pass pass
# print("none is set to \"daily\"")
try: try:
if str(account_id) in json_entry["pc"]: if str(i) in json_entry["pc"]:
try: try:
bing_pc_search() bing_pc_search()
except Exception as e: except Exception as e:
@ -703,7 +744,7 @@ def json_start(json_entry, cred: UserCredentials):
except KeyError: except KeyError:
pass pass
try: try:
if str(account_id) in json_entry["mobile"]: if str(i) in json_entry["mobile"]:
try: try:
bing_mobile_search(cred) bing_mobile_search(cred)
except Exception as e: except Exception as e:
@ -711,67 +752,55 @@ def json_start(json_entry, cred: UserCredentials):
except KeyError: except KeyError:
pass pass
try: try:
log_points() log_points(g._mail)
except Exception as e: except Exception as e:
error(f"CustomStart {e}") printf(f"CustomStart {e}")
driver.close() driver.close()
cred.next_account() cred.next_account()
account_id += 1 display.stop()
config.display.stop()
def default_start(): c = Config(args)
if config.vnc_enabled():
config.set_display(SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=config.vnc, color_depth=24)) if g.json_start:
dict_data = json.loads(g.json_start.replace("'", "\""))
json_start(dict_data, c.UserCredentials)
else:
if g.vnc_enabled or g.dev:
display = SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=g.vnc_port, color_depth=24)
else: else:
config.set_display(SmartDisplay(size=(1920, 1080))) display = SmartDisplay(size=(1920, 1080))
config.display.start() display.start()
while config.UserCredentials.is_valid(): if g.update_version != "None":
custom_sleep(1) if g.discord_enabled_error:
info("Starting and configuring driver.") webhookFailure.send(f"Updated to {g.update_version}", username="UPDATE",
config.WebDriver.set_pc_driver(create_driver())
config.WebDriver.switch_to_driver("PC")
info("Driver started.")
config.WebDriver.pc_driver.implicitly_wait(3)
try:
wait_time = uniform(1200, 3600)
wait_time = 10 # the display closes when I ctrl + c
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 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()
config.UserCredentials.next_account()
config.display.stop()
def log_error(msg):
DiscordLogger(config).send(msg)
def check_updated():
debug(f"updated: {config.has_been_updated()}")
if config.has_been_updated():
config.discord.wh.send(f"Updated to {config.version}", username="update",
avatar_url="https://cdn-icons-png.flaticon.com/512/1688/1688988.png") avatar_url="https://cdn-icons-png.flaticon.com/512/1688/1688988.png")
while c.UserCredentials.is_valid():
custom_sleep(1)
info("Starting driver.")
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()
if __name__ == "__main__": c.UserCredentials.next_account()
config = Config(args)
check_updated()
match config.start:
case "json":
json_start(config.json_entry, config.UserCredentials)
case "default": display.stop()
default_start()

View File

@ -1 +1 @@
sudo docker build --no-cache --network host -t msrewards . && sudo docker run -d --restart unless-stopped -p 1234:1234 -p 2345:2345 -ti --shm-size=2gb --name MsRewards msrewards sudo docker build --no-cache --network host -t msrewards . && sudo docker run -d --restart unless-stopped -p 1234:1234 -ti --shm-size=2gb --name MsRewards msrewards

View File

@ -1,19 +0,0 @@
version: '3.8'
services:
msrewards:
build:
context: .
dockerfile: Dockerfile
# optional if you have Dockerfile in the same directory
# arguments:
# - ARG_NAME=value # If you have build arguments
image: msrewards
container_name: MsRewards
restart: unless-stopped
ports:
- "1234:1234"
- "2345:2345"
shm_size: 2gb
volumes:
- "./data/:/data"

View File

@ -1,79 +1,15 @@
import json import json
from discord import Webhook, RequestsWebhookAdapter
from modules.Classes.DiscordConfig import DiscordConfig, FakeWebHook
from modules.Classes.Driver import Driver
from modules.Classes.Proxy import Proxy
from modules.Classes.UserCredentials import UserCredentials from modules.Classes.UserCredentials import UserCredentials
from modules.Classes.WordList import WordList
class Config: class Config:
def __init__(self, args): def __init__(self, args):
"""
open config file
"""
with open("/app/MsRewards-Reborn/user_data/discord.json", "r") as inFile:
discord = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/settings.json", "r") as inFile:
settings = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile:
proxy = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
config = json.load(inFile)
"""
setup standalone stuff
"""
self.args = args self.args = args
self.start = "json" if args.json else "default"
self.json_entry = args.json.replace("'", "\"")
self.wordlist = WordList("/usr/share/dict/french")
self.vnc = args.vnc
self.version = args.update_version
self.WebDriver = Driver()
self.display = None
"""
setup UserCredential
"""
self.UserCredentials = UserCredentials() self.UserCredentials = UserCredentials()
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile: with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile) configs = json.load(inFile)
for i in configs[str(args.config)]["accounts"]: for i in configs[str(args.config)]["accounts"]:
d = configs[str(args.config)]["accounts"][i] d = configs[str(args.config)]["accounts"][i]
self.UserCredentials.add(d["mail"], d["pwd"], d["2fa"]) self.UserCredentials.add(d["mail"], d["pwd"], d["2fa"])
"""
Setup discord
"""
self.discord = DiscordConfig()
self.discord.avatar_url = settings["avatarlink"]
self.discord.wh_link = discord[config[args.config]["discord"]]["errorsL"]
if self.discord.wh_link != "":
self.discord.wh = Webhook.from_url(self.discord.wh_link, adapter=RequestsWebhookAdapter())
else:
self.discord.wh = FakeWebHook()
"""
setup proxy
"""
proxy_conf = config[args.config]["proxy"]
if proxy_conf != "-1":
proxy_address = proxy[config[args.config]["proxy"]]["address"]
proxy_port = proxy[config[args.config]["proxy"]]["port"]
else:
proxy_address = ""
proxy_port = ""
self.proxy = Proxy(proxy_conf, proxy_address, proxy_port)
def vnc_enabled(self):
return self.vnc != "None"
def set_display(self, display):
self.display = display
def has_been_updated(self):
return self.version != "None"

View File

@ -1,14 +0,0 @@
from modules.Tools.logger import debug
class DiscordConfig:
def __init__(self):
self.avatar_url = ""
self.wh_link = None
self.wh = None
class FakeWebHook:
def send(self, *args):
debug(f"Used a webhook call without webhook url with {args}")

View File

@ -1,36 +0,0 @@
from discord import Embed, Colour, File
from modules.Classes.Config import Config
from modules.Tools.logger import error
from modules.Tools.tools import format_error
class DiscordLogger:
def __init__(self, config: Config):
self.config = config
def send(self, message: str):
driver = self.config.WebDriver.driver
if type(message) is not str:
message = format_error(message)
error(message)
with open("page.html", "w") as f:
try:
f.write(driver.page_source)
except Exception as e:
error(e)
f.write("the driver has closed or crashed. Can't access page content")
img = self.config.display.waitgrab()
img.save("screenshot.png")
embed = Embed(
title="An Error has occurred",
description=str(message),
colour=Colour.red(),
)
file = File("screenshot.png")
embed.set_image(url="attachment://screenshot.png")
embed.set_footer(text=self.config.UserCredentials.get_mail())
self.config.discord.wh.send(embed=embed, username="error", file=file, avatar_url=self.config.discord.avatar_url)
self.config.discord.wh.send(username="error", file=File("page.html"), avatar_url=self.config.discord.avatar_url)

View File

@ -1,22 +0,0 @@
class Driver:
def __init__(self):
self.pc_driver = None
self.mobile_driver = None
self.driver = None
def set_pc_driver(self, pc_driver):
self.pc_driver = pc_driver
def set_mobile_driver(self, mobile_driver):
self.mobile_driver = mobile_driver
def switch_to_driver(self, driver: str):
match driver:
case "pc" | "PC" | "Pc":
self.driver = self.pc_driver
case "mobile" | "Mobile":
self.driver = self.mobile_driver
case _:
raise ValueError("The driver must be either pc or mobile")

View File

@ -1,9 +0,0 @@
class Proxy:
def __init__(self, enabled: str, ip: str = None, port: str = None):
self.ip = ip
self.port = port
self.enabled = enabled != "-1"
def is_enabled(self):
return self.enabled

View File

@ -1,5 +1,4 @@
from pyotp import TOTP import json
from modules.Tools.logger import debug, warning from modules.Tools.logger import debug, warning
@ -10,8 +9,7 @@ class UserCredentials:
self.total = 0 self.total = 0
def add(self, username: str, password: str, tfa: str = None): def add(self, username: str, password: str, tfa: str = None):
debug( debug(f"adding account with data : Username: {username}, Password: {password}, 2FA: {'None' if tfa == '' else tfa}")
f"adding account with data : Username: {username}, Password: {password}, 2FA: {'None' if tfa == '' else tfa}")
self.data[self.total] = { self.data[self.total] = {
"username": username, "username": username,
"password": password, "password": password,
@ -31,14 +29,11 @@ class UserCredentials:
def get_tfa(self): def get_tfa(self):
if not self.tfa_enable(): if not self.tfa_enable():
warning("Warning: TFA is not enabled. Calling get_tfa is an expected behaviour.") warning("Warning: TFA is not enabled. Calling get_tfa is an expected behaviour.")
return TOTP(self.data[self.current]["tfa"]) return self.data[self.current]["tfa"]
def next_account(self): def next_account(self):
self.current += 1 self.current += 1
if self.is_valid():
debug(f"New credentials: {self.data[self.current]}") debug(f"New credentials: {self.data[self.current]}")
else:
debug("No new credentials.")
def is_valid(self): def is_valid(self):
return self.current < self.total return self.current < self.total

View File

@ -1,13 +0,0 @@
import random
class WordList:
def __init__(self, path):
with open(path, "r", encoding="utf-8") as h:
lines = h.readlines()
self.words = [x.replace('\n', "") for x in lines]
random.shuffle(self.words)
def get_word(self):
return self.words.pop(0)

View File

@ -29,8 +29,8 @@ class ColoredFormatter(logging.Formatter):
# Set up the root logger # Set up the root logger
root_logger = logging.getLogger(__name__) root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO) root_logger.setLevel(logging.DEBUG)
# Create a console handler and set the formatter # Create a console handler and set the formatter
ch = logging.StreamHandler() ch = logging.StreamHandler()

View File

@ -1,36 +0,0 @@
from time import sleep
from modules.Tools.logger import info, error
# return current page domain
def get_domain(driver):
return driver.current_url.split("/")[2]
def custom_sleep(temps):
try:
if True: # todo: change this awful condition
points = ["", "", "", "", "", "", "", ""]
passe = 0
for _ in range(int(temps)):
for i in range(8):
sleep(0.125)
passe += 0.125
print(f"{points[i]} - {round(float(temps) - passe, 3)}", end="\r")
print(" ", end="\r")
else:
sleep(temps)
except KeyboardInterrupt:
info("Wait canceled.")
except Exception as err:
error(err)
def format_error(e) -> str:
tb = e.__traceback__
txt = ""
while tb is not None:
txt = txt + f" -> {tb.tb_frame.f_code.co_name} ({tb.tb_lineno}) "
tb = tb.tb_next
return txt + "\n" + str(e)

View File

@ -1,5 +1,14 @@
#!/usr/bin/python3.10 #!/usr/bin/python3.10
from modules.driver_tools import *
from modules.imports import * from modules.imports import *
import modules.globals as g
import json
class FakeWebHook:
def send(self, text="", username='', avatar_url='', embed="", file=""):
print(text)
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@ -30,4 +39,69 @@ parser.add_argument(
default="" default=""
) )
with open("/app/MsRewards-Reborn/user_data/discord.json", "r") as inFile:
discord = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/settings.json", "r") as inFile:
settings = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile:
proxy = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
config = json.load(inFile)
args = parser.parse_args() args = parser.parse_args()
g.json_start = args.json
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.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
g.discord_success_link = discord[discord_conf]["successL"]
g.discord_error_link = discord[discord_conf]["errorsL"]
g.discord_enabled_error = discord[discord_conf]["errorsT"] == "True"
g.discord_enabled_success = discord[discord_conf]["successT"] == "True"
g.avatar_url = settings["avatarlink"]
if not g.json_start:
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:
webhookFailure = FakeWebHook()
webhookSuccess = FakeWebHook()
# base settings
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:
g.proxy_address = proxy[config[args.config]["proxy"]]["address"]
g.proxy_port = proxy[config[args.config]["proxy"]]["port"]
# 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]
if g.proxy_enabled:
setup_proxy(g.proxy_address, g.proxy_port)

View File

@ -1,66 +1,67 @@
import sqlite3 import sqlite3
#Create a new row, for the account [compte] whith [points] points
# Create a new row, for the account [compte] whith [points] points def add_row(compte, points, mycursor, mydb):
def add_row(account, points, mycursor, mydb):
sql = "INSERT INTO daily (compte, points, date) VALUES (?, ?, date())" sql = "INSERT INTO daily (compte, points, date) VALUES (?, ?, date())"
val = (account, points) val = (compte, points)
mycursor.execute(sql, val) mycursor.execute(sql, val)
mydb.commit() mydb.commit()
# printf(mycursor.rowcount, "record created.") #printf(mycursor.rowcount, "record created.")
# update the ammount of points for the account [compte] #update the ammount of points for the account [compte]
def update_row(account, points, mycursor, mydb): def update_row(compte, points, mycursor, mydb):
sql = f"UPDATE daily SET points = {points} WHERE compte = '{account}' AND date = date() ;" sql = f"UPDATE daily SET points = {points} WHERE compte = '{compte}' AND date = date() ;"
mycursor.execute(sql) mycursor.execute(sql)
mydb.commit() mydb.commit()
#printf(mycursor.rowcount, "record(s) updated")
# update the value of last_pts for the table comptes # update the value of last_pts for the table comptes
def update_last(account, points, mycursor, mydb): def update_last(compte, points, mycursor, mydb):
sql1 = f"UPDATE comptes SET last_pts = {points} WHERE compte = '{account}';" sql1 = f"UPDATE comptes SET last_pts = {points} WHERE compte = '{compte}';"
sql2 = f"select * from comptes where compte = '{account}'" sql2 = f"select * from comptes where compte = '{compte}'"
sql3 = f"INSERT INTO comptes (compte, last_pts,banned) VALUES ('{account}', {points}, 0)" sql3 = f"INSERT INTO comptes (compte, last_pts,banned) VALUES ('{compte}', {points}, 0)"
cmd = mycursor.execute(sql2) cmd = mycursor.execute(sql2)
if len(list(cmd)) == 0: if len(list(cmd)) == 0:
mycursor.execute(sql3) mycursor.execute(sql3)
else: else :
mycursor.execute(sql1) mycursor.execute(sql1)
mydb.commit() mydb.commit()
#printf(mycursor.rowcount, "record(s) updated")
# if return if there already is a line in the database for the account [compte]. if same_point is enabled, the line must also have the same number of points
# Return if there already is a line in the database for the account [account].
# if same_point is enabled, the line must also have the same number of points
# SQLITE # SQLITE
def get_row(account, points, mycursor, same_points=True): def get_row(compte, points, mycursor, same_points = True):
if same_points: if same_points :
mycursor.execute(f"SELECT * FROM daily WHERE points = {points} AND compte = '{account}' AND date = date() ;") mycursor.execute(f"SELECT * FROM daily WHERE points = {points} AND compte = '{compte}' AND date = date() ;")
else: else :
mycursor.execute(f"SELECT * FROM daily WHERE compte = '{account}' AND date = date() ;") mycursor.execute(f"SELECT * FROM daily WHERE compte = '{compte}' AND date = date() ;")
myresult = mycursor.fetchall() myresult = mycursor.fetchall()
return (len(myresult) == 1) return(len(myresult) == 1)
def add_to_database(account, points): def add_to_database(compte, points, save_if_fail=True):
if points is None: if points is None:
pass pass
else: else:
mydb = sqlite3.connect("/app/MsRewards-Reborn/MsRewards.db") mydb = sqlite3.connect("/app/MsRewards-Reborn/MsRewards.db")
mycursor = mydb.cursor() mycursor = mydb.cursor()
if get_row(compte, points,mycursor, True): #check if the row exist with the same ammount of points and do nothind if it does
if get_row(account, points, mycursor, True): #printf("les points sont deja bon")
# check if the row exist with the same amount of points and do nothing if it does #return(0)
pass pass
elif get_row(compte, points,mycursor, False) : #check if the row exist, but without the same ammount of points and update the point account then
# check if the row exist, but without the same amount of points and update the point account then update_row(compte, points,mycursor,mydb)
elif get_row(account, points, mycursor, False): #printf("row updated")
update_row(account, points, mycursor, mydb) #return(1)
else : # if the row don't exist, create it with the good ammount of points
else: # if the row don't exist, create it with the good amount of points add_row(compte, points,mycursor,mydb)
add_row(account, points, mycursor, mydb) #return(2) #printf("row added")
if int(points) > 10 :
if int(points) > 10: update_last(compte, points, mycursor, mydb)
update_last(account, points, mycursor, mydb)
mycursor.close() mycursor.close()
mydb.close() mydb.close()

View File

@ -1,13 +1,7 @@
from random import uniform from modules.imports import *
from modules.config import *
from selenium.common import TimeoutException from modules.tools import *
from selenium.webdriver import ActionChains, Keys import modules.globals as g
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from modules.Tools.logger import debug
from modules.Tools.tools import *
def set_language(ldriver): def set_language(ldriver):
@ -22,10 +16,10 @@ def set_language(ldriver):
# scroll down # scroll down
action.reset_actions() action.reset_actions()
elm = ldriver.find_element(By.XPATH, "/html/body") elm = ldriver.find_element(By.XPATH, "/html/body")
ActionChains(ldriver) \ ActionChains(ldriver)\
.send_keys("french") \ .send_keys("french")\
.pause(0.5) \ .pause(0.5)\
.send_keys(Keys.TAB + Keys.TAB + Keys.ENTER + Keys.TAB + Keys.TAB + Keys.ENTER) \ .send_keys(Keys.TAB + Keys.TAB + Keys.ENTER + Keys.TAB + Keys.TAB + Keys.ENTER)\
.perform() .perform()
x_coord = 1163 x_coord = 1163
y_coord = 717 y_coord = 717
@ -39,34 +33,64 @@ def set_language(ldriver):
action.click().perform() action.click().perform()
# Deal with RGPD popup as well as some random popup like 'are you satisfied' one def setup_proxy(ip: str, port: str) -> None:
def rgpd_popup(config) -> None: PROXY = f"{ip}:{port}"
for i in ["bnp_btn_accept", "bnp_hfly_cta2", "bnp_hfly_close"]: webdriver.DesiredCapabilities.FIREFOX['proxy'] = {
try: "httpProxy": PROXY,
config.WebDriver.driver.find_element(By.ID, i).click() "sslProxy": PROXY,
except Exception as err: "proxyType": "MANUAL",
debug(err) }
#Deal with RGPD popup as well as some random popup like 'are you satisfied' one
def rgpd_popup(driver) -> None:
for i in ["bnp_btn_accept", "bnp_hfly_cta2", "bnp_hfly_close"] :
try:
driver.find_element(By.ID, i).click()
except:
pass
# save webdriver cookies
def save_cookies(driver) -> None:
if g.dev:
f = open(f"{'/'.join(__file__.split('/')[:-2])}/user_data/cookies/{g._mail}_unsafe.pkl", "w")
for i in driver.get_cookies():
f.write(str(i) + "\n")
f.close()
else :
pickle.dump(driver.get_cookies(), open(f"{'/'.join(__file__.split('/')[:-2])}/user_data/cookies/{g._mail}.pkl", "wb"))
# load cookies previously saved to the driver
def load_cookies(driver) -> None:
if g.dev:
f = open(f"{'/'.join(__file__.split('/')[:-2])}/user_data/cookies/{g._mail}_unsafe.pkl", "r")
lines = f.readlines()
f.close()
cookies = [literal_eval(x) for x in lines]
else :
cookies = pickle.load(open(f"{'/'.join(__file__.split('/')[:-2])}/user_data/cookies/{g._mail}.pkl", "rb"))
for cookie in cookies:
driver.add_cookie(cookie)
""" """
send_keys_wait([selenium element:element, str:keys]) send the different keys to the field element, with a random send_keys_wait([selenium element:element, str:keys]) send the different keys to the field element, with a random time between each press to simulate human action.
time between each press to simulate human action.
keys can be an string, but also selenium keys keys can be an string, but also selenium keys
""" """
def send_keys_wait(element, keys: str) -> None: def send_keys_wait(element, keys: str) -> None:
for i in keys: for i in keys:
element.send_keys(i) element.send_keys(i)
sleep(uniform(0.1, 0.3)) sleep(uniform(0.1, 0.3))
# Wait for the presence of the element identifier or [timeout]s # Wait for the presence of the element identifier or [timeout]s
def wait_until_visible(search_by: str, identifier: str, timeout: int = 20, browser=None) -> bool: def wait_until_visible(search_by: str, identifier: str, timeout = 20, browser = None) -> None:
try: try :
WebDriverWait(browser, timeout).until( WebDriverWait(browser, timeout).until(EC.visibility_of_element_located((search_by,identifier)), "element not found")
expected_conditions.visibility_of_element_located((search_by, identifier)), "element not found") return(True)
return True
except TimeoutException as e: except TimeoutException as e:
error(f"element {identifier} not found after {timeout}s") printf(f"element {identifier} not found after {timeout}s")
return False return(False)

View File

@ -1,10 +1,8 @@
class Banned(Exception): class Banned(Exception):
pass pass
class NotBanned(Exception): class NotBanned(Exception):
pass pass
class Identity(Exception): class Identity(Exception):
pass pass

30
modules/globals.py Normal file
View File

@ -0,0 +1,30 @@
driver = None
display = None
log = False
full_log = False
vnc_enabled = False
vnc_port = 2345
points_file = "/"
update_version = False
start_time = 0
mot_path = "/"
credential_path = "/"
discord_success_link = "https://example.com"
discord_error_link = "https://example.com"
discord_enabled_error = False
discord_enabled_success = False
avatar_url = ""
fidelity_link = "None"
discord_embed = False
headless = False
proxy_enabled = False
proxy_address = "0.0.0.0"
proxy_port = "0"
sql_enabled = False
sql_usr = "None"
sql_pwd = "azerty"
sql_host = "https://example.com"
sql_database = "MsRewards"
norvege = False
database_error_override = False
json_start = ""

82
modules/tools.py Normal file
View File

@ -0,0 +1,82 @@
from modules.imports import *
from modules.config import *
from modules.db import *
import modules.globals as g
# add the time arround the text given in [text]&
def Timer(text: str) -> str:
return(f"[{g._mail.split('@')[0]} - {datetime.today().strftime('%d/%m')} - {timedelta(seconds = round(float(time() - g.start_time)))}] " + str(text))
# replace the function print, with more options
# [txt] : string, [driver] : selenium webdriver
def printf(txt):
print(Timer(txt))
# return current page domain
def get_domain(driver):
return(driver.current_url.split("/")[2])
# check if the user is using IPV4 using ipify.org
# [driver] : selenium webdriver
# never used here
# can be useful as Ms had issues with IPV6 at some point
def check_ipv4(driver):
driver.get("https://api64.ipify.org")
elm = driver.find_element(By.TAG_NAME, "body")
if len(elm.text.split('.')) == 4 :
return True
return False
def custom_sleep(temps):
try :
if g.log : #only print sleep when user see it
points = ["", "", "", "", "", "", "", ""]
passe = 0
for i in range(int(temps)):
for i in range(8):
sleep(0.125)
passe += 0.125
print(f"{points[i]} - {round(float(temps) - passe, 3)}", end="\r")
print(" ", end="\r")
else:
sleep(temps)
except KeyboardInterrupt :
print("attente annulée")
def format_error(e) -> str:
tb = e.__traceback__
txt = ""
while tb != None :
txt = txt + f" -> {tb.tb_frame.f_code.co_name} ({tb.tb_lineno}) "
tb = tb.tb_next
return(txt + "\n" + str(e))
def progressBar(current, total=30, barLength=20, name="Progress"):
percent = float(current + 1) * 100 / total
arrow = "-" * int(percent / 100 * barLength - 1) + ">"
spaces = " " * (barLength - len(arrow))
print(name + ": [%s%s] %d %%" % (arrow, spaces, percent), end="\r")
def save_points_from_file(file):
with open(file) as f:
read = reader(f)
points_list = list(read)
for item in points_list:
compte, points = item[0], item[1]
add_to_database(compte, points, g.sql_host,g.sql_usr,g.sql_pwd,g.sql_database, save_if_fail=False)
with open(file, "w") as f:
f.write("")
def select_accounts(multiple = True):
system("clear") # clear from previous command to allow a clean choice
emails = [x[0] for x in g._cred] # list of all email adresses
emails_selected = enquiries.choose(f"quel{'s' if multiple else ''} compte{'s' if multiple else ''} ?", emails, multi=multiple)
return([x for x in g._cred if x[0] in emails_selected])

View File

@ -4,7 +4,7 @@ selenium
pillow pillow
pyvirtualdisplay pyvirtualdisplay
undetected_chromedriver undetected_chromedriver
requests>=2.31.0 requests
flask flask
flask_sse flask_sse
EasyProcess EasyProcess

345731
user_data/french Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
v6.8.40 v6.8.0