From 095915d08f7076eeaab4ecac7ac9540295c1f222 Mon Sep 17 00:00:00 2001 From: mrfry Date: Tue, 18 Apr 2023 09:00:46 +0200 Subject: [PATCH] handling no server url on startup --- .gitignore | 1 - user.js => stable.user.js | 394 ++++++++++++++++++++------------------ 2 files changed, 207 insertions(+), 188 deletions(-) rename user.js => stable.user.js (92%) diff --git a/.gitignore b/.gitignore index 963f3d3..3c3629e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ node_modules -stable.user.js diff --git a/user.js b/stable.user.js similarity index 92% rename from user.js rename to stable.user.js index e3809e0..60dbace 100755 --- a/user.js +++ b/stable.user.js @@ -23,20 +23,20 @@ // =============================================================================== // =============================================================================== // -// HA EZT LÁTOD, ÉS TELEPÍTENI AKARTAD A SCRIPTET, AKKOR -// NINCS USERSCRIPT KEZELŐ BŐVÍTMÉNYED. +// HA EZT LÁTOD, ÉS TELEPÍTENI AKARTAD A SCRIPTET, AKKOR +// NINCS USERSCRIPT KEZELŐ BŐVÍTMÉNYED. // -// Telepíts egy userscript kezelőt, például a Tampermonkey-t: -// https://www.tampermonkey.net/ +// Telepíts egy userscript kezelőt, például a Tampermonkey-t: +// https://www.tampermonkey.net/ // // =============================================================================== // -// IF YOU ARE SEEING THIS MESSAGE, AND YOU WANTED TO -// INSTALL THIS SCRIPT, THEN YOU DON'T HAVE ANY USERSCRIPT -// MANAGER INSTALLED. +// IF YOU ARE SEEING THIS MESSAGE, AND YOU WANTED TO +// INSTALL THIS SCRIPT, THEN YOU DON'T HAVE ANY USERSCRIPT +// MANAGER INSTALLED. // -// Install a userscript manager, for example Tampermonkey: -// https://www.tampermonkey.net/ +// Install a userscript manager, for example Tampermonkey: +// https://www.tampermonkey.net/ // // =============================================================================== // =============================================================================== @@ -46,7 +46,7 @@ // : Script header {{{ // ==UserScript== // @name Moodle/Elearning/KMOOC test help -// @version 2.1.4.4 +// @version 2.1.5.0 // @description Online Moodle/Elearning/KMOOC test help // @author MrFry // @match https://elearning.uni-obuda.hu/* @@ -71,8 +71,6 @@ // @match https://moodle.uni-corvinus.hu/* // @match https://v39.moodle.uniduna.hu/* // @match https://mentok.net/* -// @match https://qmining.[DOMAIN]/* -// @match https://[DOMAIN]/* // @noframes // @run-at document-start // @grant GM_getResourceText @@ -84,18 +82,17 @@ // @grant GM_openInTab // @grant unsafeWindow // @license GNU General Public License v3.0 or later -// @supportURL [DOMAIN] -// @contributionURL [DOMAIN] -// @namespace https://[DOMAIN] -// @updateURL https://[DOMAIN]/moodle-test-userscript/stable.user.js?up +// @supportURL https://gitlab.com/MrFry/moodle-test-userscript +// @contributionURL https://gitlab.com/MrFry/moodle-test-userscript +// @namespace https://gitlab.com/MrFry/moodle-test-userscript +// @updateURL https://gitlab.com/MrFry/moodle-test-userscript/-/raw/master/stable.user.js // ==/UserScript== // : }}} // eslint-disable-next-line @typescript-eslint/no-extra-semi ;(function () { // CONFIG - let originalServer = { host: '[DOMAIN]', port: 443 } - setVal('serverToUse', JSON.stringify(originalServer)) + let serverToUse = getJSONVal('serverToUse') const logElementGetting = false const logEnabled = true const motdShowCount = 5 // Ammount of times to show motd @@ -112,9 +109,19 @@ function getVal(name) { return GM_getValue(name) } + function getJSONVal(name) { + try { + return JSON.parse(GM_getValue(name)) + } catch (e) { + return null + } + } function setVal(name, val) { return GM_setValue(name, val) } + function setJSONVal(name, val) { + return GM_setValue(name, JSON.stringify(val)) + } function delVal(name) { return GM_deleteValue(name) } @@ -145,8 +152,8 @@ const forceDefaultPage = isDevel && false // ------------------------------------------------------------------------------ - let serverAdress = getPeerUrl(originalServer) - let apiAdress = getPeerUrl(originalServer) + 'api/' + let serverAdress = getPeerUrl(serverToUse) + let apiAdress = getPeerUrl(serverToUse) + 'api/' var addEventListener // add event listener function var motd = '' var lastestVersion = '' @@ -161,30 +168,12 @@ warn('Moodle script running in developement mode!') infoExpireTime = 1 p2pInfoExpireTime = 1 - originalServer = { host: 'localhost', port: 8080 } - serverAdress = getPeerUrl(originalServer) - apiAdress = getPeerUrl(originalServer) + 'api/' + const devServerToUse = { host: 'localhost', port: 8080 } + serverAdress = getPeerUrl(devServerToUse) + apiAdress = getPeerUrl(devServerToUse) + 'api/' setVal('motdcount', 5) } - const peerToUseString = getVal('peerToUse') - var usingPeer = false - if (peerToUseString) { - try { - const peerToUse = JSON.parse(peerToUseString) - - if (peerToUse && peerToUse.host && peerToUse.port) { - const url = getPeerUrl(peerToUse) - debugLog('Using saved peer url: ' + url) - serverAdress = url - apiAdress = url + 'api/' - usingPeer = true - } - } catch (e) { - debugLog('peerToUse not JSON') - } - } - const currUrl = location.href.includes('file:///') ? 'https://elearning.uni-obuda.hu/' : location.href @@ -202,15 +191,15 @@ videoHelp: 'Miután elindítottad: Play/pause: space. Seek: Bal/jobb nyíl.', help: 'Help', donate: 'Donate', - retry: 'Újrapróbálás', + retry: 'Újra', invalidPW: 'Hibás jelszó: ', connecting: 'Csatlakozás: ', + connect: 'Csatlakozás', login: 'Belépés', noServer: 'Nem elérhető a szerver!', tryingPeer: 'Csatlakozás: ', noPeersOnline: 'Egy peer sem elérhető!', peerTryingError: 'Hiba peerek keresése közben!', - usingpeer: `A script eredeti szervere megszűnt, vagy nem elérhető, így egy másik peert használ! Hogy továbbra is kapj frissítéseekt újra kell telepítened a scriptet. További infó: ${serverAdress}faq?tab=newpeer`, pwHere: 'Jelszó ...', noServerConsoleMessage: `Nem elérhető a szerver! Ha elérhető a weboldal, akkor ott meg bírod nézni a kérdéseket itt: ${serverAdress}allQuestions`, unhandledErrorConsoleMessage: `Kezeletlen hiba történt! Ha elérhető a weboldal, akkor ott meg bírod nézni a kérdéseket itt: ${serverAdress}allQuestions`, @@ -224,6 +213,9 @@ scriptName: 'Moodle/Elearning/KMOOC segéd ', userMOTD: 'Felhasználó MOTD (ezt csak te látod):\n', motd: 'MOTD:\n', + noHostText: '', + hostHere: 'Qmining szerver domain-je...', + invalidDomain: 'Hibás domain!\nHelyes formátum: "qmining.com"', } var texts = huTexts @@ -1625,61 +1617,7 @@ // : }}} // : Loading {{{ - function HandleQminingSite(url) { - try { - const idInput = document.getElementById('cid') - if (idInput) { - idInput.value = getCid() - } - } catch (e) { - warn('Error filling client ID input', e) - } - try { - const sideLinks = document.getElementById('sideBarLinks') - if (!sideLinks) { - return - } - Array.from(sideLinks.childNodes).forEach((link) => { - link.addEventListener('mousedown', () => { - FillFeedbackCID(url, link) - }) - }) - - FillFeedbackCID( - url, - document - .getElementById('sideBarLinks') - .getElementsByClassName('active')[0] - ) - } catch (e) { - warn('Error filling client ID input', e) - } - } - - function FillFeedbackCID(url, link) { - try { - if (link.id === 'feedback') { - const cidSetInterval = setInterval(() => { - const cid = document.getElementById('cid') - if (cid) { - cid.value = getCid() + '|' + info().script.version - window.clearInterval(cidSetInterval) - } - }, 100) - } - } catch (e) { - warn('Error filling client ID input', e) - } - } - function Init() { - const url = currUrl - - if (url.includes(serverAdress.split('/')[2])) { - HandleQminingSite(url) - return - } - try { addEventListener = (function () { if (document.addEventListener) { @@ -1695,10 +1633,16 @@ } catch (e) { Exception(e, 'script error at addEventListener:') } - VersionActions() - if (!url.includes('.pdf')) { + + if (!currUrl.includes('.pdf')) { ShowMenu() } + + if (!serverToUse) { + noHostAction() + return + } + ConnectToServer() } @@ -1732,6 +1676,7 @@ } function ConnectToServer() { + console.info('Connecting to:', serverAdress) clearAllMessages() SafeGetElementById('peerSelector', (elem) => { elem.style.display = 'none' @@ -1755,9 +1700,6 @@ overlay.querySelector( '#infoMainDiv' ).innerText = `${subjInfo.subjects.toLocaleString()} tárgy, ${subjInfo.questions.toLocaleString()} kérdés. UID: #${getUid()}` - if (inf.unreads.length > 0) { - overlay.querySelector('#mailButton').innerText = '📬' - } getPeers().catch(() => warn('unable to get p2p info')) SafeGetElementById('peerSelector', (elem) => { @@ -1776,7 +1718,7 @@ elem.innerText = texts.noServer }) - if (skipAvailablePeerFind || !getVal('lastp2pinfo')) { + if (skipAvailablePeerFind || !getVal('peers')) { connectionErrorAction() } else { tryAnotherPeer() @@ -1787,20 +1729,13 @@ async function tryAnotherPeer() { debugLog('Unable to connect to main server, trying peers') try { - const lastp2pinfo = JSON.parse(getVal('lastp2pinfo')) - if ( - !lastp2pinfo || - (Array.isArray(lastp2pinfo) && lastp2pinfo.length === 0) - ) { + const peers = getJSONVal('peers') + if (!peers || peers.length === 0) { debugLog('No saved p2p info available!') return } - debugLog('Saved peers: ', lastp2pinfo) - const shuffledPeers = lastp2pinfo.sort(() => 0.5 - Math.random()) - if (usingPeer) { - debugLog('Added original server') - shuffledPeers.unshift(originalServer) - } + debugLog('Saved peers: ', peers) + const shuffledPeers = peers.sort(() => 0.5 - Math.random()) let suitablePeer = null let i = 0 @@ -1846,24 +1781,26 @@ } function connectToPeer(peer) { - const url = getPeerUrl(peer) - serverAdress = url - apiAdress = url + 'api/' - if ( - peer.host === originalServer.host && - peer.port === originalServer.port - ) { - setVal('peerToUse', undefined) - usingPeer = false - } else { - setVal('peerToUse', JSON.stringify(peer)) - usingPeer = true + const newPeers = getJSONVal('peers').filter((x) => { + return getPeerUrl(x) !== getPeerUrl(peer) + }) + if (serverToUse) { + newPeers.push(serverToUse) } + setVal('peers', JSON.stringify(newPeers)) + setVal('serverToUse', JSON.stringify(peer)) + SafeGetElementById('peerSelector', (elem) => { + updatePeerSelector(elem) + }) SafeGetElementById('scriptMenuDiv', (elem) => { elem.style.backgroundColor = '#222426' }) + const url = getPeerUrl(peer) + serverToUse = peer + serverAdress = url + apiAdress = url + 'api/' ConnectToServer() } @@ -1894,8 +1831,74 @@ }) } - function VersionActions() { - FreshStart() + function noHostAction() { + const elementIdsToHide = ['buttonContainer'] + elementIdsToHide.forEach((id) => { + SafeGetElementById(id, (elem) => { + elem.style.display = 'none' + }) + }) + SafeGetElementById('retryContainer', (elem) => { + elem.style.display = 'none' + }) + SafeGetElementById('peerSelector', (elem) => { + elem.style.display = 'none' + }) + SafeGetElementById('scriptMenuDiv', (elem) => { + elem.style.backgroundColor = '#262626' + }) + SafeGetElementById('infoMainDiv', (elem) => { + elem.innerText = texts.noHostText + }) + SafeGetElementById('hostInputContainer', (elem) => { + elem.style.display = 'flex' + }) + } + + function addHost(val) { + let isHostValid = false + let hostUrl = val + const regex = new RegExp('[a-zA-Z]+(?:\\.[a-zA-Z]+)+') + if (hostUrl.match(regex) || hostUrl.includes('localhost')) { + if (hostUrl.includes('://')) { + hostUrl = hostUrl.split('//')[1] + } + if (hostUrl.endsWith('/')) { + hostUrl = hostUrl.replace(/\//, '') + } + isHostValid = true + } + + if (!isHostValid) { + SafeGetElementById('infoMainDiv', (elem) => { + elem.innerText = texts.invalidDomain + }) + return + } + + let port = hostUrl.includes('https') ? 433 : 80 + if (hostUrl.split(':').length > 1) { + port = hostUrl.split(':')[1] + port = port.replace(/\//g, '') + hostUrl = hostUrl.replace(':' + port, '') + } + + SafeGetElementById('buttonContainer', (elem) => { + elem.style.display = 'flex' + }) + SafeGetElementById('hostInputContainer', (elem) => { + elem.style.display = 'none' + }) + + serverToUse = { host: hostUrl, port: port } + setJSONVal('serverToUse', serverToUse) + serverAdress = getPeerUrl(serverToUse) + apiAdress = getPeerUrl(serverToUse) + 'api/' + SafeGetElementById('infoMainDiv', (elem) => { + elem.innerText = texts.connecting + getShortServerURL(serverAdress) + }) + debugLog({ serverAdress: serverAdress, apiAdress: apiAdress }) + ConnectToServer() } // : }}} @@ -1959,9 +1962,6 @@ greetMsg.push(texts.motd + motd) timeout = null } - if (usingPeer) { - greetMsg.push(texts.usingpeer) - } if (greetMsg.length > 0) { greetMsg.unshift(texts.scriptName + info().script.version) } @@ -2180,19 +2180,6 @@ // : Version action functions {{{ - function FreshStart() { - var firstRun = getVal('firstRun') // if the current run is the frst - if (firstRun === undefined || firstRun === true) { - setVal('firstRun', false) - ShowHelp(true) // showing help - registerScript() - - document.write(texts.freshStartWarning) - document.close() - throw new Error('something, so this stuff stops') - } - } - function registerScript() { try { // uncomment to re-register again every page refresh @@ -2638,7 +2625,7 @@ display: 'flex', flexDirection: 'column', width: '300px', - height: '100px', + height: '110px', position: 'fixed', padding: '3px 0px', bottom: '30px', @@ -2685,25 +2672,8 @@ scriptMenuDiv.parentNode.removeChild(scriptMenuDiv) }, }, - mailButton: { - id: 'mailButton', - innerText: '📭', - style: { - position: 'absolute', - display: 'inline', - bottom: '20px', - left: '5px', - fontSize: '30px', - cursor: 'pointer', - }, - title: 'Messages', - onClick: () => { - openInTab(serverAdress + 'chat', { - active: true, - }) - }, - }, buttonContainer: { + id: 'buttonContainer', style: { display: 'flex', justifyContent: 'center', @@ -2740,7 +2710,7 @@ flexDirection: 'column', justifyContent: 'center', flex: 1, - margin: '0px 50px', + margin: '0px 10px', }, children: { infoContainer: { @@ -2763,13 +2733,13 @@ color: 'white', border: '1px solid #f2cb05', cursor: 'pointer', + margin: '4px 0px', }) - // FIXME: add new peers here after load - const peers = [ - originalServer, - ...JSON.parse(getVal('lastp2pinfo')), - ] + const peers = getJSONVal('peers') + if (serverToUse) { + peers.push(serverToUse) + } if (peers.length === 1) { return document.createElement('span') @@ -2828,6 +2798,36 @@ }, }, }, + hostInputContainer: { + id: 'hostInputContainer', + style: { + display: 'none', + }, + children: { + peerInput: { + customElem: () => { + const peerInput = document.createElement('input') + peerInput.setAttribute('id', 'peerInput') + peerInput.type = 'text' + peerInput.placeholder = texts.hostHere + SetStyle(peerInput, { + width: '100%', + textAlign: 'center', + }) + return peerInput + }, + }, + connectButton: { + innerText: texts.connect, + style: buttonStyle, + onClick: () => { + SafeGetElementById('peerInput', (elem) => { + addHost(elem.value) + }) + }, + }, + }, + }, retryContainer: { id: 'retryContainer', style: { @@ -2840,6 +2840,7 @@ style: { position: '', padding: '0px 8px', + margin: '0px 4px', border: '1px solid #333', borderRadius: '2px', color: '#ffffff', @@ -2857,6 +2858,21 @@ ConnectToServer() }, }, + anotherPeerButton: { + innerText: '~Másik peer...~', + style: { + position: '', + padding: '0px 8px', + margin: '0px 4px', + border: '1px solid #333', + borderRadius: '2px', + color: '#ffffff', + cursor: 'pointer', + }, + onClick: () => { + noHostAction() + }, + }, }, }, }, @@ -2873,14 +2889,21 @@ function updatePeerSelector(selector) { try { - const peers = [originalServer, ...JSON.parse(getVal('lastp2pinfo'))] + const peers = getJSONVal('peers') + if (serverToUse) { + peers.push(serverToUse) + } - const selectedPeer = JSON.parse(getVal('peerToUse')) + const selectedPeer = getVal('serverToUse') + ? JSON.parse(getVal('serverToUse')) + : null const selectedIndex = peers.findIndex((x) => { return getPeerUrl(x) === getPeerUrl(selectedPeer) }) selector.value = selectedIndex - } catch (e) {} + } catch (e) { + debugLog('error in updatePeerSelector') + } } // : }}} @@ -2962,6 +2985,7 @@ } function getShortServerURL(url) { + if (!url) return const maxlegnth = 30 const shortUrl = url.replace('https://', '').replace('http://', '') if (shortUrl.length <= maxlegnth) { @@ -2972,6 +2996,7 @@ } function getPeerUrl(peer, forDisplay) { + if (!peer) return if (forDisplay) { return peer.host + ':' + peer.port } @@ -3092,18 +3117,16 @@ '&cid=' + getCid() - Promise.all([get(url), get(apiAdress + 'hasNewMsg')]) - .then(([{ responseText: infos }, { responseText: hasNewMsg }]) => { + get(url) + .then(({ responseText: infos }) => { try { - const infosObj = JSON.parse(infos) - const hasNewMsgsObj = JSON.parse(hasNewMsg) - const merged = Object.assign({}, infosObj, hasNewMsgsObj) - setVal('lastInfo', JSON.stringify(merged)) + const infos = JSON.parse(infos) + setVal('lastInfo', JSON.stringify(infos)) setVal('lastInfoCheckTime', now) - resolve(merged) + resolve(infos) } catch (e) { log('Error parsing JSON in GetXHRInfos') - log({ infos: infos, hasNewMsg: hasNewMsg }) + log({ infos: infos }) log(e) reject(e) } @@ -3128,8 +3151,8 @@ } function updateP2pData(newData) { - const lastp2pinfo = getVal('lastp2pinfo') - const oldPeers = lastp2pinfo ? JSON.parse(lastp2pinfo) : [] + const peers = getJSONVal('peers') + const oldPeers = peers || [] const merged = newData.reduce((acc, peer) => { const peerAlreadyExists = acc.find((existingPeer) => { const p1 = peer.host + ':' + peer.port @@ -3155,8 +3178,6 @@ lastCheck = 0 } - let lastp2pinfo = {} - if (now > lastCheck + p2pInfoExpireTime * 1000) { return new Promise((resolve, reject) => { const url = apiAdress + 'p2pinfo' @@ -3165,7 +3186,7 @@ .then(({ responseText: p2pinfo }) => { try { const p2pinfoObj = updateP2pData(JSON.parse(p2pinfo).myPeers) - setVal('lastp2pinfo', JSON.stringify(p2pinfoObj)) + setJSONVal('peers', p2pinfoObj) setVal('lastp2pchecktime', now) resolve(p2pinfoObj) } catch (e) { @@ -3183,8 +3204,7 @@ } else { return new Promise((resolve, reject) => { try { - lastp2pinfo = JSON.parse(getVal('lastp2pinfo')) - resolve(lastp2pinfo) + resolve(getJSONVal('peers')) } catch (e) { log('Error parsing JSON in getPeers, when using old data!') log(e)