diff --git a/scripts/content.js b/scripts/content.js index f461985..3348403 100644 --- a/scripts/content.js +++ b/scripts/content.js @@ -5,9 +5,12 @@ const pathnameRegex = /^\/\w{2}-\w{2}\/n?iv/; const MAX_SIGNIN_ATTEMPTS = 3; const PAGE_WAIT_TIME = 3792; const MINUTE = 60; -const RANDOM_JITTER = 0.1; +const RND_VAR_COEFF = 0.1; const SOFT_BAN_TIMEOUT = 27; -const NOTIF_CHANNEL = "snegov" +const NOTIF_CHANNEL = "snegov"; +const CHECK_OPER_HOURS = true; +const OPER_HOURS_START = 23; +const OPER_HOURS_END = 9; let cfg = { activate: undefined, @@ -50,18 +53,22 @@ function getRandomInt(max) { return Math.floor(Math.random() * Math.floor(max)); } - -function getJitter(frequency) { - return frequency * MINUTE * RANDOM_JITTER; -} - -function getFutureDate(minutes, maxRandomSeconds = 0) { +function getFutureDate(minutes, frequency) { // return date some amount of minutes in future plus random amount of seconds let futureDate = new Date(); - futureDate.setSeconds(futureDate.getSeconds() + minutes * MINUTE + getRandomInt(maxRandomSeconds)); + const randomVariation = frequency * MINUTE * RND_VAR_COEFF; + const randomSign = Math.random() < 0.5 ? -1 : 1; + const offset = randomSign * getRandomInt(randomVariation); + + futureDate.setSeconds(futureDate.getSeconds() + minutes * MINUTE + offset); return futureDate.toISOString(); } +function isNoBanTime(frequency = 5) { + let now = new Date(); + return (now.getHours() === OPER_HOURS_START && now.getMinutes() < frequency); +} + function hiddenPassword(cfg) { return { ...cfg, @@ -106,7 +113,7 @@ function ensureRequiredConsulateProperties(consCtx, consCfg, frequency = 1) { "id": consCtx[c]?.id || null, "bestDate": consCtx[c]?.bestDate || null, "currentDate": consCtx[c]?.currentDate || null, - "nextCheckAt": consCtx[c]?.nextCheckAt || getFutureDate(0, frequency * MINUTE), + "nextCheckAt": consCtx[c]?.nextCheckAt || getFutureDate(0, frequency), }; } if (!consCfg[c] || !hasAllKeys(consCfg[c], reqCfgKeys)) { @@ -332,7 +339,7 @@ async function runner() { if (key === 'frequency') { let wasChanged = false; for (let c in ctx.consulates) { - let newNextCheckAt = getFutureDate(cfg.frequency, getJitter(cfg.frequency)); + let newNextCheckAt = getFutureDate(cfg.frequency, cfg.frequency); if (ctx.consulates[c].nextCheckAt > newNextCheckAt) { console.log(`Reducing wait time for ${c} from ${ctx.consulates[c].nextCheckAt} to ${newNextCheckAt}`); ctx.consulates[c].nextCheckAt = newNextCheckAt; @@ -382,15 +389,17 @@ async function runner() { return; } - // Check if current time is between 11pm and 9am UTC (4pm - 2am PST) - let now = new Date(); - let currentHourUTC = now.getUTCHours(); - if (currentHourUTC >= 23 || currentHourUTC < 9) { - // Continue running the code - } else { - await chrome.storage.local.set({ "ctx_statusMsg": "not operational hours" }); - isRunning = false; - return; + if (CHECK_OPER_HOURS) { + // Check if current time is between 11pm and 9am UTC (4pm - 2am PST) + let now = new Date(); + let currentHourUTC = now.getUTCHours(); + if (currentHourUTC >= OPER_HOURS_START || currentHourUTC < OPER_HOURS_END) { + // Continue running the code + } else { + await chrome.storage.local.set({ "ctx_statusMsg": "not operational hours" }); + isRunning = false; + return; + } } if (isFoundAppointment) { @@ -579,6 +588,19 @@ async function runner() { if (processedConsulates > 0) { break; } + + // Reset all soft bans in the first 5 minutes of the first operational hour + let now = new Date(); + if (isNoBanTime(cfg.frequency)) { + let nextCheckAt = new Date(ctx.consulates[c].nextCheckAt); + let differenceInMinutes = (nextCheckAt.getTime() - now.getTime()) / (1000 * 60); + + if (differenceInMinutes > cfg.frequency) { + console.log(`Resetting soft ban for ${c}`); + ctx.consulates[c].nextCheckAt = getFutureDate(0, cfg.frequency); + } + } + // skip if not time to check if (ctx.consulates[c].nextCheckAt > new Date().toISOString()) { continue; @@ -590,7 +612,7 @@ async function runner() { console.log(msg); await chrome.storage.local.set({ "ctx_statusMsg": msg }); let availDates = await getAvailableDates(ctx.consulates[c].id); - ctx.consulates[c].nextCheckAt = getFutureDate(cfg.frequency, getJitter(cfg.frequency)); + ctx.consulates[c].nextCheckAt = getFutureDate(cfg.frequency, cfg.frequency); if (!availDates) { msg = `Failed to fetch available dates in ${c}`; @@ -601,21 +623,16 @@ async function runner() { // if empty list, either we're banned or non operational hours or dead consulate // wait for some time before checking again - let now = new Date(); - let currentHourUTC = now.getUTCHours(); - let currentMinuteUTC = now.getUTCMinutes(); - if (availDates.length == 0) { - msg = `No available dates in ${c}, probably banned`; + msg = `No available dates in ${c}`; console.log(msg); await chrome.storage.local.set({ "ctx_statusMsg": msg }); - // Only set SOFT_BAN_TIMEOUT if it's not the first 5 minutes of 23pm UTC - if (!(currentHourUTC === 23 && currentMinuteUTC < 5)) { - ctx.consulates[c].nextCheckAt = getFutureDate(SOFT_BAN_TIMEOUT, getJitter(cfg.frequency)); + if (!isNoBanTime(cfg.frequency)) { + console.log(`Setting soft ban for ${c}`); + ctx.consulates[c].nextCheckAt = getFutureDate(SOFT_BAN_TIMEOUT, cfg.frequency); } - ctx.consulates[c].currentDate = null; - + ctx.consulates[c].currentDate = null; continue; }