handling no server url on startup

This commit is contained in:
mrfry 2023-04-18 09:00:46 +02:00
parent 3b13893bf9
commit 095915d08f
2 changed files with 207 additions and 188 deletions

1
.gitignore vendored
View file

@ -1,2 +1 @@
node_modules
stable.user.js

View file

@ -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ó: <a href="${serverAdress}faq?tab=newpeer">${serverAdress}faq?tab=newpeer</a>`,
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)