Skip to content

Instantly share code, notes, and snippets.

@christophernarciso
Last active May 15, 2020 04:18
Show Gist options
  • Save christophernarciso/4fdb905d00db2983ff3e519e6fcce18f to your computer and use it in GitHub Desktop.
Save christophernarciso/4fdb905d00db2983ff3e519e6fcce18f to your computer and use it in GitHub Desktop.
Rough draft runescape prime member added
const {Builder, By, Key, until, util} = require('selenium-webdriver');
const FileReader = require('filereader');
const fs = require('fs');
const config = require('./config');
let driver = new Builder().forBrowser('chrome').build();
// CONSTANTS
const RS_URL = "https://secure.runescape.com/m=weblogin/loginform?mod=twitch_integration&ssl=1&dest";
const RS_FAIL_URL = "https://secure.runescape.com/m=weblogin/login.ws";
const RS_REDIRECT_URL = "https://www.runescape.com/account/linked-accounts/twitch/played-before";
const RS_REDEEMED_URL = "/account/linked-accounts/twitch/redeem";
const TW_URL = "https://www.twitch.tv/login";
const RS_SITE_KEY = "6Lcsv3oUAAAAAGFhlKrkRb029OHio098bbeyi_Hv";
const TW_SITE_KEY = "6Ld65QcTAAAAAMBbAE8dkJq4Wi4CsJy7flvKhYqX";
const CAP_KEY = config.captchaKey;
const TW_HOME_URL = "https://www.twitch.tv/?no-reload=true";
const TW_REDEEM_URL = "https://id.twitch.tv/oauth2/authorize";
const readFileData = (input) => {
return fs.readFileSync(input, 'utf8').split('\r\n');
};
const saveFileData = (output, msg) => {
return fs.appendFile(output, msg + '\n', (err) => {
// throws an error, you could also catch it here
if (err) throw err;
// success case, the file was saved
console.log(`Saved information to file: ${output}\n${msg}`);
});
};
const browserReset = async () => {
await driver.quit().then(_ => {
console.log("Finished one link...");
});
driver = await new Builder().forBrowser('chrome').build();
await timeout(5000);
await driver.get(TW_URL).then(_ => driver.wait(until.titleIs('Log In - Twitch'), 20000));
};
const twitchLogin = async (driver, tw_acc, index) => {
const credentials = tw_acc.split(':');
await driver.findElement(By.xpath('//input[contains(@type,\'text\')]'))
.then(e => e.sendKeys(credentials[0]))
.then(_ => timeout(1500));
await driver.findElement(By.xpath('//input[contains(@type,\'password\')]'))
.then(e => e.sendKeys(credentials[1]))
.then(_ => timeout(1500));
await driver.findElement(By.xpath('/html/body/div[1]/div/div[1]/div[3]/div/div/div/div[3]/form/div/div[3]/button'))
.then(e => e.click())
.then(_ => driver.wait(until.titleIs('Twitch'), 20000))
.catch(error => {
saveFileData(config.outputFailFileName, `Failure in twitch account: ${credentials}`);
return index++;
});
return index;
};
const twitchHandler = async (driver, url, tw_acc, index) => {
if (url.startsWith(TW_REDEEM_URL)) {
console.log('ON REDEEEM AUTH2');
await driver.findElement(By.className('button button--large js-authorize'))
.then(e => e.click())
.then(_ => driver.wait(until.titleIs('Twitch - Played Before? - RuneScape | Old School RuneScape'), 20000));
return index;
}
await driver.findElement(By.xpath('//*[@id="root"]/div/div[2]/nav/div/div[3]/div[2]/div/div/div[1]/div/div[1]/button'))
.then(e => e.click())
.then(_ => timeout(2000))
.then(_ => driver.findElement(By.xpath('//*[@id="root"]/div/div[2]/nav/div/div[3]/div[2]/div/div/div[2]/div/div/div[2]/div/div[3]/div/div/div[1]/div[1]/div/p')))
.then(e => e.click())
.then(_ => timeout(1000));
const offers = await driver.findElements(By.className('tw-align-items-center tw-align-middle tw-border-bottom-left-radius-small tw-border-bottom-right-radius-small tw-border-top-left-radius-small tw-border-top-right-radius-small tw-button-icon tw-button-icon--small tw-core-button tw-core-button--small tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative'))
.then(found => {
if (!!found.length)
return found;
});
let inc = false;
for (let i = 0; i < offers.length; i++) {
await driver.findElement(By.className('tw-c-text-alt-2 tw-font-size-7'))
.then(e => e.getText())
.then(txt => {
console.log(txt);
if (txt === 'Jagex') {
if (elementExists(driver, By.xpath('/html/body/div[1]/div/div[2]/nav/div/div[3]/div[2]/div/div/div[2]/div/div/div[2]/div/div[3]/div/div/div[1]/div[2]/div/div/div[2]/div[3]/div[1]/h4/div'))) {
const msg = `TWITCH ACCOUNT REDEEMED ALREADY: ${tw_acc}`;
saveFileData(config.outputFailFileName, msg);
inc = true;
return;
}
console.log('FOUND JAGEX OFFER!');
driver.findElement(By.className('tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-core-button tw-core-button--primary tw-full-width tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative'))
.then(e => e.click())
.then(_ => timeout(3000))
.then(_ => driver.get('https://www.runescape.com/account/linked-accounts/twitch/redeem'))
.then(_ => driver.wait(until.titleIs('Twitch - Authorize Application'), 20000));
} else {
console.log('REMOVE OFFER');
offers[i].click().then(_ => console.log('OFFER REMOVED'));
}
});
await timeout(2000);
}
return inc ? index++ : index;
};
const rsHandler = async (driver, url, index, list_rs) => {
if (url.startsWith(RS_REDIRECT_URL)) {
await driver.findElement(By.linkText('Yes - Log in'))
.then(e => e.click())
.then(_ => driver.wait(until.titleIs('Log In - RuneScape | Old School RuneScape'), 20000));
return index;
} else if (url.startsWith(RS_REDEEMED_URL)) {
await driver.findElement(By.linkText('Confirm'))
.then(e => e.click())
.then(_ => timeout(5000))
.then(_ => driver.wait(until.elementIsVisible(driver.findElement(By.className('m-callout m-callout--type-success'))), 10000))
.catch(error => {
saveFileData(config.outputFailFileName, `Failure with runescape account: ${list_rs[index]}`);
});
await browserReset();
return index++;
}
};
const rsLogin = async (driver, rs_acc) => {
const credentials = rs_acc.split(':');
await driver.findElement(By.id('login-username'))
.then(e => e.sendKeys(credentials[0]))
.then(_ => timeout(1500));
await driver.findElement(By.id('login-password'))
.then(e => e.sendKeys(credentials[1]))
.then(_ => timeout(1500));
const requestId = await initiateCaptchaRequest();
const response = await pollForRequestResults(requestId);
await driver.executeScript("document.getElementById('g-recaptcha-response').innerHTML = '" + response + "'; onSubmit();")
.then(_ => timeout(5000));
};
const elementExists = async (driver, By) => {
try {
driver.findElement(By).then(found => console.log('Element found? %s', !!found.length));
return true;
} catch (e) {
return false;
}
};
const verifyIndex = async (rs_index, tw_index, list_tw, list_rs) => {
if (rs_index > list_tw.length)
return false;
if (tw_index > list_rs.length)
return false;
return true;
};
async function initiateCaptchaRequest() {
const formData = {
method: 'userrecaptcha',
key: CAP_KEY,
googlekey: RS_SITE_KEY,
pageurl: RS_URL,
invisible: "1",
json: 1
};
const response = await request.post('http://2captcha.com/in.php', {form: formData});
return JSON.parse(response).request;
}
async function pollForRequestResults(id, retries = 30, interval = 1500, delay = 15000) {
await timeout(delay);
return poll({
taskFn: requestCaptchaResults(id),
interval,
retries
});
}
function requestCaptchaResults(requestId) {
const url = `http://2captcha.com/res.php?key=${CAP_KEY}&action=get&id=${requestId}&json=1`;
return async function () {
return new Promise(async function (resolve, reject) {
const rawResponse = await request.get(url);
const resp = JSON.parse(rawResponse);
if (resp.status === 0) return reject(resp.request);
resolve(resp.request);
});
}
}
const timeout = millis => new Promise(resolve => setTimeout(resolve, millis));
(async function main() {
const list_tw = readFileData(config.twitchFileName);
const list_rs = readFileData(config.runescapeFileName);
let tw_index = 0;
let rs_index = 0;
let curr_tw = list_tw[tw_index];
let curr_rs = list_rs[rs_index];
await driver.get(TW_URL).then(_ => driver.wait(until.titleIs('Log In - Twitch'), 20000));
while (true) {
console.log('Loop');
let url = await driver.getCurrentUrl().then(url => {
return url;
});
if (url === TW_URL)
tw_index = await twitchLogin(driver, curr_tw);
else if (url === TW_HOME_URL || url.startsWith(TW_REDEEM_URL)) {
const lastIndex = tw_index;
tw_index = await twitchHandler(driver, url, curr_tw, tw_index);
console.log(tw_index);
if (tw_index > lastIndex) {
curr_tw = list_tw[tw_index];
console.log(`Current information in twitchHandler():\nIndex ${tw_index} | TW ${curr_tw} | RS ${curr_rs}`);
await browserReset();
}
} else if (url.startsWith(RS_URL))
await rsLogin(driver, curr_rs);
else if (url.startsWith(RS_REDIRECT_URL) || url.startsWith(RS_REDEEMED_URL)) {
const lastIndex = rs_index;
rs_index = await rsHandler(driver, url, rs_index, list_rs);
if (rs_index > lastIndex) {
const msg = `${list_rs[lastIndex]}:${list_tw[tw_index]}`;
saveFileData(config.outputSuccessFileName, msg);
tw_index++;
}
const check = await verifyIndex(rs_index, tw_index, list_tw, list_rs);
if (!check) {
console.log('FINISHED LIST OR CANNOT CONTINUE');
await driver.quit();
}
curr_tw = list_tw[tw_index];
curr_rs = list_rs[rs_index];
console.log(`Current information:\nIndex ${rs_index} | TW ${curr_tw} | RS ${curr_rs}`);
}
await timeout(1000);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment