// ==UserScript== // @name AlwaysWin-ntsmhf // @namespace https://git.qhrei.com/steven/alwayswin-ntsmhf/ // @version 0.1 // @description Make sure you are positioned where you want to be in the bidding for each county. // @author Steven Allen // @match https://leads.needtosellmyhousefast.com/* // @require https://code.jquery.com/jquery-3.7.1.min.js // @require http://crypto.stanford.edu/sjcl/sjcl.js // @icon https://www.google.com/s2/favicons?sz=64&domain=needtosellmyhousefast.com // @grant none // ==/UserScript== 'use strict'; //Load our settings //localStorage.removeItem('alwayswin_settings'); const verboseLevel=0; console.log("Loading settings"); var alwaysWinSettingsString = localStorage.getItem('alwayswin_settings'); //console.log(alwaysWinSettingsString); if(alwaysWinSettingsString == null || alwaysWinSettingsString == undefined) { const defaultSettings = {"isReloadEnabled":true, "isAutoLoginEnabled":false, "minSecondsBetweenReloads": 60, "maxSecondsBetweenReloads":300, "isGeneralCapEnabled":false, "generalCap":500, "oversight":[]}; const defaultSettingsString = JSON.stringify(defaultSettings); localStorage.setItem('alwayswin_settings',defaultSettingsString); alwaysWinSettingsString = defaultSettingsString; } var alwaysWinSettings = JSON.parse(alwaysWinSettingsString); //console.log(alwaysWinSettings); //////////// // Div injection and auto reload functions //////////// function getRandomNumberBetween(min, max) { min = Number(min); max = Number(max); return Math.floor(Math.random() * (max - min) + min); } function getCheckedValue(fieldName) { switch (fieldName) { case "isReloadEnabled": return reloadIsEnabled() ? "checked": ""; case "isAutoLoginEnabled": return autoLoginIsEnabled() ? "checked": ""; case "isGeneralCapEnabled": return generalCapIsEnabled() ? "checked" :""; default: return ""; } return ""; } function addAlwaysWinStyle(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } function handleSaveSettings() { saveSettings(); location.reload(); } function saveSettings() { let isReloadEnabledValue = document.querySelector("[name='isReloadEnabled']").checked; let isAutoLoginEnabledValue = document.querySelector("[name='isAutoLoginEnabled']").checked; let minSecondsBetweenReloadsValue = document.querySelector("[name='minSecondsBetweenReloads']").value; let maxSecondsBetweenReloadsValue = document.querySelector("[name='maxSecondsBetweenReloads']").value; let isGeneralCapEnabledValue = document.querySelector("[name='isGeneralCapEnabled']").checked; let generalCap = document.querySelector("[name='generalCap']").value; let capPresidence = document.querySelector("[name='capPresidence']").value; let oversight = []; var latestSettings = alwaysWinSettings; latestSettings.isReloadEnabled = isReloadEnabledValue; latestSettings.isAutoLoginEnabled = isAutoLoginEnabledValue; latestSettings.minSecondsBetweenReloads = minSecondsBetweenReloadsValue; latestSettings.maxSecondsBetweenReloads = maxSecondsBetweenReloadsValue; latestSettings.isGeneralCapEnabled = isGeneralCapEnabledValue; latestSettings.generalCap = generalCap; latestSettings.capPresidence = capPresidence; if(latestSettings.oversight == null || latestSettings == undefined) { latestSettings.oversight = oversight; } const latestSettingsString = JSON.stringify(latestSettings); localStorage.setItem('alwayswin_settings',latestSettingsString); alwaysWinSettingsString = latestSettings; return latestSettings; } function saveCountyInfoStats(newStats) { let existingStats = []; //get existing stats if they exist let existingStatsString = localStorage.getItem('alwayswin_stats'); if(existingStatsString != null && existingStatsString !== undefined) { existingStats = JSON.parse(existingStatsString); } const combinedStats = existingStats.concat(newStats) const updatedStatsString = JSON.stringify(combinedStats); localStorage.setItem('alwayswin_stats',updatedStatsString); //console.log(combinedStats); } function reload() { console.log("Saving settings..."); let alwaysWinSettings = saveSettings(); awLog("Its time to perform a reload."); awLog("isEnabled: "+ alwaysWinSettings.isReloadEnabled); awLog("secondsBetweenReloads:"+ alwaysWinSettings.minSecondsBetweenReloads +" - "+ alwaysWinSettings.maxSecondsBetweenReloads); if(!reloadIsEnabled() ) { awLog("Reload is not enabled"); return; } awLog("Reload is enabled. Reloading..."); location.reload(); } function reloadIsEnabled(){ var checkedValue = alwaysWinSettings.isReloadEnabled ?? false;// document.querySelector("[name='isReloadEnabled']").checked; if(checkedValue == true) { return true; } return false; } function autoLoginIsEnabled(){ var checkedValue = alwaysWinSettings.isAutoLoginEnabled ?? false; var retVal = (checkedValue == true); return retVal; } function generalCapIsEnabled () { var checkedValue = alwaysWinSettings.isGeneralCapEnabled ?? false; var retVal = (checkedValue == true); return retVal; } function getBidCapForCountyId(countyId) { //Get the default bidcap from settings var bidCap = alwaysWinSettings.generalCap; const countyOversight = alwaysWinSettings.oversight.find(({ id }) => id === countyId); if(countyFound(countyOversight)) { bidCap = countyOversight.bidCap; } return Number(bidCap); } //////////////////////////////////////////////////////////////////////////////////// // Always win code to find and take the highest/tie bid //////////////////////////////////////////////////////////////////////////////////// function getCountyInfo(countyId){ var county = document.querySelector('[data-subscription_id="'+ countyId +'"].subscription-status'); if(county === null) { console.log("county "+ countyId +" row not found"); return; } let countyRow = county.closest("tr"); let bidController = {}; bidController.countyRow = countyRow; const bidIncriment = 25; //This is hard coded into site but could change later. let num_bid = Number(countyRow.querySelector('.bid-controller--bid').value); let num_tieBid = Number(countyRow.querySelector('.bid-controller').dataset.top_bid); let num_floorBid = num_tieBid - bidIncriment; let num_winningBid = num_tieBid + bidIncriment; let num_clicksToMinWin = 1; let winGap = (num_tieBid - num_bid); if(winGap < 1) { num_clicksToMinWin = (winGap / bidIncriment) + 1; } else if(winGap > 0) { num_clicksToMinWin = (winGap + bidIncriment) / bidIncriment; } let num_bidCap = getBidCapForCountyId(countyId); let num_clicksToBidCap = num_clicksToMinWin; bidController.readTimestamp = new Date(); bidController.isEnabled = county.checked; bidController.id = county.dataset.subscription_id; bidController.name = county.closest("div").getElementsByTagName('a')[0].innerText; bidController.bid = num_bid; bidController.tieBid = num_tieBid; bidController.floorBid = num_floorBid; bidController.winningBid = num_winningBid; bidController.status = countyRow.querySelector(".bid-status").innerText;//.trim(); //countyRow.querySelector(".bid-status").dataset.bid_status; bidController.isWinning = (num_bid > num_tieBid); bidController.isWinningByTooMuch = (num_bid > num_winningBid); bidController.clicksToMinWin = num_clicksToMinWin; bidController.bidCap = num_bidCap; bidController.clicksToBidCap = num_clicksToBidCap; bidController.btnSave = countyRow.querySelector('.bid-controller-btn--save'); bidController.btnBidUp = countyRow.querySelector('.bid-controller-btn--increment'); bidController.btnBidDown = countyRow.querySelector('.bid-controller-btn--decrement'); return bidController; } function winCounty(countyJson, saveChanges) { if(countyJson?.id == undefined) { awLog("Unable to find county. So no way to win it."); return; } let countyInfo = countyJson.id + " "+ countyJson.name; //console.log(countyJson.isWinning +" = "+ countyJson.tieBid +" > "+ countyJson.bid); //console.log(countyJson.isWinningByTooMuch +" = "+ countyJson.bid +" > "+ countyJson.winningBid); //console.log("clicksToMinWin: "+ countyJson.clicksToMinWin); //console.log(countyJson); if(countyJson.clicksToMinWin == 0) { //if we made it here no changes were needed to win by just the right amount //Nothing else to do to win optimally //console.log(countyInfo +" is already winning by just the right amount"); awLog(countyInfo +" is already winning by just the right amount"); } else if(countyJson.clicksToMinWin > 0) { //console.log(countyInfo +" is currently loosing. Increasing bid now"); awLog(countyInfo +" is currently loosing by "+countyJson.clicksToMinWin+" Increasing bid now"); for(var i = 0; i < countyJson.clicksToMinWin; i++) { //console.log("calling btnBidUp.click() for "+ countyInfo); countyJson.btnBidUp.click(); } if(saveChanges) { //console.log("calling btnSave.click() for "+ countyInfo); countyJson.btnSave.click(); } } else if (countyJson.clicksToMinWin < 0) { //console.log(countyInfo +" is winning by too much. Decreasing bid now"); awLog(countyInfo +" is winning by too much. Decreasing bid now"); let clicksRemaining = Math.abs(countyJson.clicksToMinWin); while(clicksRemaining > 0) { //console.log("calling btnBidDown.click() for "+ countyInfo); countyJson.btnBidDown.click(); clicksRemaining--; } if(saveChanges) { //console.log("calling btnSave.click() for "+ countyInfo); countyJson.btnSave.click(); } } } function tieCounty(countyJson, saveChanges) { //TODO: implemnt me let countyInfo = countyJson.id + " "+ countyJson.name; awLog(countyInfo +" tieCounty code not yet implemented"); } function watchCounty(countyJson, saveChanges) { //TODO: implemnt me let countyInfo = countyJson.id + " "+ countyJson.name; awLog(countyInfo +" watchCounty code not yet implemented"); } function ignoreCounty(countyJson, saveChanges) { //TODO: implemnt me let countyInfo = countyJson.id + " "+ countyJson.name; awLog(countyInfo +" ignoreCounty code not yet implemented"); } function awLog(message) { console.log(message); const currentContent = document.getElementById("awLog").innerHTML; document.getElementById("awLog").innerHTML = currentContent +""+ message +"
"; } function encryptAndStore(encryptionKey, clearText) { return JSON.stringify(sjcl.encrypt(encryptionKey, clearText)); } function unStoreAndDecrypt (encryptionKey, jsonObj) { return sjcl.decrypt(encryptionKey, JSON.parse(jsonObj)); } function loginIfNeeded(){ var div_signin = document.querySelector('.signin-box'); var loginIsNeeded = false; if(div_signin != undefined && div_signin != null) { loginIsNeeded = true; if(!alwaysWinSettings.isAutoLoginEnabled) { console.log("AutoLogin is turned off."); awLog("AutoLogin is turned off."); return loginIsNeeded; } console.log("A signin dialog exists"); var txt_email = div_signin.querySelector("[id='email']"); var txt_password = div_signin.querySelector("[id='inputPassword']"); var btn_signin = div_signin.querySelector('.btn-signin'); //btn btn-primary btn-block btn-signin var encKey = alwaysWinSettings.encKey ?? ""; var ntsmhfUser = alwaysWinSettings.ntsmhfUser ?? ""; var ntsmhfPass = alwaysWinSettings.ntsmhfPass ?? ""; if (!encKey) { encKey = prompt('Script key not set for ' + location.hostname + '. Please enter a random string:',''); alwaysWinSettings.encKey = encKey; ntsmhfUser = ""; ntsmhfPass = ""; } if(ntsmhfUser) { ntsmhfUser = unStoreAndDecrypt(encKey, ntsmhfUser); } else { ntsmhfUser = prompt('UserName is not set for '+ location.hostname +'. Enter it now:',''); alwaysWinSettings.ntsmhfUser = encryptAndStore(encKey, ntsmhfUser); } if(ntsmhfPass) { ntsmhfPass = unStoreAndDecrypt(encKey, ntsmhfPass); } else { ntsmhfPass = prompt('Password is not set for '+ location.hostname +'. Enter it now:',''); alwaysWinSettings.ntsmhfPass = encryptAndStore(encKey, ntsmhfPass); } const latestSettingsString = JSON.stringify(alwaysWinSettings); localStorage.setItem('alwayswin_settings',latestSettingsString); ////// txt_email.value = ntsmhfUser; txt_password.value = ntsmhfPass; btn_signin.click(); } return loginIsNeeded; } function renderOption(value, selectedValue, displayValue) { if(displayValue == null || displayValue===undefined) { displayValue = value; } var optionHtml = '