mirror of
https://gitlab.com/MrFry/moodle-test-userscript
synced 2025-04-01 20:22:48 +02:00
p2p functionality
This commit is contained in:
parent
3ad9e897f3
commit
b12e7a9a55
2 changed files with 383 additions and 157 deletions
|
@ -2,8 +2,9 @@ module.exports = {
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
es6: true,
|
es6: true,
|
||||||
node: true,
|
},
|
||||||
jest: true,
|
parserOptions: {
|
||||||
|
ecmaVersion: 8,
|
||||||
},
|
},
|
||||||
extends: ['eslint:recommended'],
|
extends: ['eslint:recommended'],
|
||||||
globals: {
|
globals: {
|
||||||
|
|
397
stable.user.js
397
stable.user.js
|
@ -46,7 +46,7 @@
|
||||||
// : Script header {{{
|
// : Script header {{{
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Moodle/Elearning/KMOOC test help
|
// @name Moodle/Elearning/KMOOC test help
|
||||||
// @version 2.1.3.15
|
// @version 2.1.4.0
|
||||||
// @description Online Moodle/Elearning/KMOOC test help
|
// @description Online Moodle/Elearning/KMOOC test help
|
||||||
// @author MrFry
|
// @author MrFry
|
||||||
// @match https://elearning.uni-obuda.hu/*
|
// @match https://elearning.uni-obuda.hu/*
|
||||||
|
@ -72,6 +72,7 @@
|
||||||
// @match https://v39.moodle.uniduna.hu/*
|
// @match https://v39.moodle.uniduna.hu/*
|
||||||
// @match https://mentok.net/*
|
// @match https://mentok.net/*
|
||||||
// @match https://qmining.frylabs.net/*
|
// @match https://qmining.frylabs.net/*
|
||||||
|
// @match https://frylabs.net/*
|
||||||
// @noframes
|
// @noframes
|
||||||
// @run-at document-start
|
// @run-at document-start
|
||||||
// @grant GM_getResourceText
|
// @grant GM_getResourceText
|
||||||
|
@ -83,16 +84,25 @@
|
||||||
// @grant GM_openInTab
|
// @grant GM_openInTab
|
||||||
// @grant unsafeWindow
|
// @grant unsafeWindow
|
||||||
// @license GNU General Public License v3.0 or later
|
// @license GNU General Public License v3.0 or later
|
||||||
// @supportURL qmining.frylabs.net
|
// @supportURL frylabs.net
|
||||||
// @contributionURL qmining.frylabs.net
|
// @contributionURL frylabs.net
|
||||||
// @namespace https://qmining.frylabs.net
|
// @namespace https://frylabs.net
|
||||||
// @updateURL https://qmining.frylabs.net/moodle-test-userscript/stable.user.js?up
|
// @updateURL https://frylabs.net/moodle-test-userscript/stable.user.js?up
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
// : }}}
|
// : }}}
|
||||||
|
|
||||||
;(function () {
|
;(function () {
|
||||||
// : ESLINT bs {{{
|
// CONFIG
|
||||||
|
let originalServer = { host: 'frylabs.net', port: 443 }
|
||||||
|
const logElementGetting = false
|
||||||
|
const logEnabled = true
|
||||||
|
const motdShowCount = 5 // Ammount of times to show motd
|
||||||
|
let infoExpireTime = 60 * 5 // Every n seconds basic info should be (re)loaded from server
|
||||||
|
let p2pInfoExpireTime = 60 * 60 * 24
|
||||||
|
const messageOpacityDelta = 0.1
|
||||||
|
const minMessageOpacity = 0.2
|
||||||
|
|
||||||
|
// : ESLINT bs {{{
|
||||||
// eslint-disable-line
|
// eslint-disable-line
|
||||||
// GM functions, only to disable ESLINT errors
|
// GM functions, only to disable ESLINT errors
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
@ -125,31 +135,21 @@
|
||||||
// Devel vars
|
// Devel vars
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// forcing pages for testing. unless you test, do not set these to true!
|
// forcing pages for testing. unless you test, do not set these to true!
|
||||||
const isDevel = true
|
const isDevel = false
|
||||||
const forcedMatchString = isDevel ? 'default' : null
|
const forcedMatchString = isDevel ? 'default' : null
|
||||||
// only one of these should be true for testing
|
// only one of these should be true for testing
|
||||||
const forceTestPage = isDevel && false
|
const forceTestPage = isDevel && false
|
||||||
const forceResultPage = isDevel && true
|
const forceResultPage = isDevel && false
|
||||||
const forceDefaultPage = isDevel && false
|
const forceDefaultPage = isDevel && false
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
|
||||||
const logElementGetting = false
|
let serverAdress = getPeerUrl(originalServer)
|
||||||
const logEnabled = true
|
let apiAdress = getPeerUrl(originalServer) + 'api/'
|
||||||
const showErrors = true
|
|
||||||
|
|
||||||
var addEventListener // add event listener function
|
var addEventListener // add event listener function
|
||||||
let serverAdress = 'https://qmining.frylabs.net/'
|
|
||||||
let apiAdress = 'https://api.frylabs.net/'
|
|
||||||
|
|
||||||
const motdShowCount = 5 /* Ammount of times to show motd */
|
|
||||||
const messageOpacityDelta = 0.1
|
|
||||||
const minMessageOpacity = 0.2
|
|
||||||
let infoExpireTime = 60 * 5 // Every n seconds basic info should be loaded from server
|
|
||||||
var motd = ''
|
var motd = ''
|
||||||
var lastestVersion = ''
|
var lastestVersion = ''
|
||||||
var subjInfo
|
var subjInfo
|
||||||
var uiShowing = true
|
let uiShowing = getVal('uishowing')
|
||||||
|
|
||||||
// array, where elems are added to shadow-root, but its position should be at target.
|
// array, where elems are added to shadow-root, but its position should be at target.
|
||||||
var updatableElements = [] // { elem: ..., target: ... }
|
var updatableElements = [] // { elem: ..., target: ... }
|
||||||
var elementUpdaterInterval = -1
|
var elementUpdaterInterval = -1
|
||||||
|
@ -158,8 +158,29 @@
|
||||||
if (isDevel) {
|
if (isDevel) {
|
||||||
warn('Moodle script running in developement mode!')
|
warn('Moodle script running in developement mode!')
|
||||||
infoExpireTime = 1
|
infoExpireTime = 1
|
||||||
serverAdress = 'http://localhost:8080/'
|
p2pInfoExpireTime = 1
|
||||||
apiAdress = 'http://localhost:8080/'
|
originalServer = { host: 'localhost', port: 8080 }
|
||||||
|
serverAdress = getPeerUrl(originalServer)
|
||||||
|
apiAdress = getPeerUrl(originalServer) + '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:///')
|
const currUrl = location.href.includes('file:///')
|
||||||
|
@ -171,8 +192,7 @@
|
||||||
const huTexts = {
|
const huTexts = {
|
||||||
fatalError:
|
fatalError:
|
||||||
'Fatál error. Check console (f12). Kattints az üzenetre az összes kérdés/válaszért manuális kereséshez! (új böngésző tab-ban)',
|
'Fatál error. Check console (f12). Kattints az üzenetre az összes kérdés/válaszért manuális kereséshez! (új böngésző tab-ban)',
|
||||||
consoleErrorInfo:
|
consoleErrorInfo: `Itteni hibák 100% a moodle hiba. Kivéve, ha oda van írva hogy script error ;) Ha ilyesmi szerepel itt, akkor olvasd el a segítség szekciót! ${serverAdress}`,
|
||||||
'Itteni hibák 100% a moodle hiba. Kivéve, ha oda van írva hogy script error ;) Ha ilyesmi szerepel itt, akkor olvasd el a segítség szekciót! https://qmining.frylabs.net/manual?scriptcmd',
|
|
||||||
freshStartWarning:
|
freshStartWarning:
|
||||||
'<h1>Moodle teszt userscript:<h1><h3>1.5.0 verzió: a script mostantól XMLHTTP kéréseket küld szerver fele! Erre a userscript futtató kiegészítőd is figyelmeztetni fog! Ha ez történik, a script rendes működése érdekében engedélyezd (Always allow domain)! Ha nem akarod, hogy ez történjen, akkor ne engedélyezd, vagy a menüben válaszd ki a "helyi fájl használata" opciót!</h3> <h3>Elküldött adatok: minden teszt után a kérdés-válasz páros. Fogadott adatok: Az összes eddig ismert kérdés. Érdemes help-et elolvasni!!!</h3><h5>Ez az ablak frissités után eltűnik. Ha nem, akkor a visza gombbal próbálkozz.</h5>',
|
'<h1>Moodle teszt userscript:<h1><h3>1.5.0 verzió: a script mostantól XMLHTTP kéréseket küld szerver fele! Erre a userscript futtató kiegészítőd is figyelmeztetni fog! Ha ez történik, a script rendes működése érdekében engedélyezd (Always allow domain)! Ha nem akarod, hogy ez történjen, akkor ne engedélyezd, vagy a menüben válaszd ki a "helyi fájl használata" opciót!</h3> <h3>Elküldött adatok: minden teszt után a kérdés-válasz páros. Fogadott adatok: Az összes eddig ismert kérdés. Érdemes help-et elolvasni!!!</h3><h5>Ez az ablak frissités után eltűnik. Ha nem, akkor a visza gombbal próbálkozz.</h5>',
|
||||||
noResult:
|
noResult:
|
||||||
|
@ -193,20 +213,24 @@
|
||||||
dataEditorTitle: 'Adatbázisban lévő kérdések szerkesztése',
|
dataEditorTitle: 'Adatbázisban lévő kérdések szerkesztése',
|
||||||
invalidPW: 'Hibás jelszó: ',
|
invalidPW: 'Hibás jelszó: ',
|
||||||
search: 'Keresés ...',
|
search: 'Keresés ...',
|
||||||
loading: 'Betöltés ...',
|
connecting: 'Csatlakozás: ',
|
||||||
login: 'Belépés',
|
login: 'Belépés',
|
||||||
newPWTitle: 'Új jelszó új felhasználónak',
|
newPWTitle: 'Új jelszó új felhasználónak',
|
||||||
pwRequest: 'Jelszó új felhasználónak',
|
pwRequest: 'Jelszó új felhasználónak',
|
||||||
noServer: 'Nem elérhető a szerver!',
|
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ó ...',
|
pwHere: 'Jelszó ...',
|
||||||
noServerConsoleMessage: `Nem elérhető a szerver, vagy kis eséllyel kezeletlen hiba történt! Ha elérhető a weboldal, akkor ott meg bírod nézni a kérdéseket itt: ${serverAdress}legacy`,
|
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`,
|
||||||
noParseableQuestionResult:
|
noParseableQuestionResult:
|
||||||
'A tesztben nem találhatók kérdések, amit fel lehet dolgozni, vagy hiba történt feldolgozásuk közben',
|
'A tesztben nem találhatók kérdések, amit fel lehet dolgozni, vagy hiba történt feldolgozásuk közben',
|
||||||
unableToParseTestQuestion:
|
unableToParseTestQuestion:
|
||||||
'Hiba történt a kérdések beolvasása közben :/ Kattints az üzenetre a manuális kereséshez (új böngésző tab-ban)',
|
'Hiba történt a kérdések beolvasása közben :/ Kattints az üzenetre a manuális kereséshez (új böngésző tab-ban)',
|
||||||
loadingAnswer: 'Válaszok betöltése ...',
|
loadingAnswer: 'Válaszok betöltése ...',
|
||||||
reinstallFromCorrectSource:
|
reinstallFromCorrectSource: `Scriptet nem a qmining weboldalról raktad fel. Könnyebb kezelhetőség szempontjából kérlek onnan telepítsd. <a href="${serverAdress}">Részletes leírás</a>`,
|
||||||
'Scriptet nem a qmining weboldalról raktad fel. Könnyebb kezelhetőség szempontjából kérlek onnan telepítsd. <a href="https://qmining.frylabs.net/manual.html#scriptreinstall">Részletes leírás</a>',
|
|
||||||
versionUpdated: 'Verzió frissítve ',
|
versionUpdated: 'Verzió frissítve ',
|
||||||
newVersionAvaible: 'Új verzió elérhető: ',
|
newVersionAvaible: 'Új verzió elérhető: ',
|
||||||
userSpecifitMotdAvailable:
|
userSpecifitMotdAvailable:
|
||||||
|
@ -1463,10 +1487,6 @@
|
||||||
|
|
||||||
log('Moodle / E-Learning script')
|
log('Moodle / E-Learning script')
|
||||||
preventWindowClose()
|
preventWindowClose()
|
||||||
console.log(
|
|
||||||
'%c Moodle / E-Learning script',
|
|
||||||
'font-weight: bold; font-size: 50px;color: yellow; text-shadow: 3px 3px 0 rgb(245,221,8) , 6px 6px 0 rgb(226,91,14) , 9px 9px 0 rgb(217,31,38) , 12px 12px 0 rgb(5,148,68) , 15px 15px 0 rgb(2,135,206) , 18px 18px 0 rgb(4,77,145) , 21px 21px 0 rgb(42,21,113)'
|
|
||||||
)
|
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'loading') {
|
||||||
document.addEventListener('DOMContentLoaded', Init)
|
document.addEventListener('DOMContentLoaded', Init)
|
||||||
|
@ -1694,13 +1714,13 @@
|
||||||
SetupMenu()
|
SetupMenu()
|
||||||
ShowMenu()
|
ShowMenu()
|
||||||
}
|
}
|
||||||
ConnectToServer(AfterLoad)
|
ConnectToServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
function Auth(pw) {
|
function Auth(pw) {
|
||||||
post('login', { pw: pw, script: true }).then((res) => {
|
post('login', { pw: pw, script: true }).then((res) => {
|
||||||
if (res.result === 'success') {
|
if (res.result === 'success') {
|
||||||
ConnectToServer(AfterLoad)
|
ConnectToServer()
|
||||||
clearAllMessages()
|
clearAllMessages()
|
||||||
resetMenu()
|
resetMenu()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1722,14 +1742,15 @@
|
||||||
elem.style.display = 'none'
|
elem.style.display = 'none'
|
||||||
})
|
})
|
||||||
SafeGetElementById('infoMainDiv', (elem) => {
|
SafeGetElementById('infoMainDiv', (elem) => {
|
||||||
elem.innerText = texts.loading
|
elem.innerText = texts.connecting + getShortServerURL(serverAdress)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function ConnectToServer(cwith) {
|
function ConnectToServer() {
|
||||||
clearAllMessages()
|
clearAllMessages()
|
||||||
GetXHRInfos()
|
GetXHRInfos()
|
||||||
.then((inf) => {
|
.then((inf) => {
|
||||||
|
try {
|
||||||
if (inf.result === 'nouser') {
|
if (inf.result === 'nouser') {
|
||||||
NoUserAction()
|
NoUserAction()
|
||||||
return
|
return
|
||||||
|
@ -1743,23 +1764,115 @@
|
||||||
setVal('userId', inf.uid)
|
setVal('userId', inf.uid)
|
||||||
overlay.querySelector(
|
overlay.querySelector(
|
||||||
'#infoMainDiv'
|
'#infoMainDiv'
|
||||||
).innerText = `${subjInfo.subjects.toLocaleString(
|
).innerText = `${subjInfo.subjects.toLocaleString()} tárgy, ${subjInfo.questions.toLocaleString()} kérdés. UID: #${getUid()}\n${getShortServerURL(
|
||||||
'hu'
|
serverAdress
|
||||||
)} tárgy, ${subjInfo.questions.toLocaleString(
|
)}`
|
||||||
'hu'
|
|
||||||
)} kérdés.\nUser ID: ${getUid()}`
|
|
||||||
if (inf.unreads.length > 0) {
|
if (inf.unreads.length > 0) {
|
||||||
overlay.querySelector('#mailButton').innerText = '📬'
|
overlay.querySelector('#mailButton').innerText = '📬'
|
||||||
}
|
}
|
||||||
// FIXME: if cwith() throws an unhandled error it sais server is not avaible
|
|
||||||
cwith()
|
getPeers().catch(() => warn('unable to get p2p info'))
|
||||||
|
AfterLoad()
|
||||||
|
} catch (e) {
|
||||||
|
warn(texts.unhandledErrorConsoleMessage)
|
||||||
|
warn(e)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch((e) => {
|
||||||
NoServerAction()
|
|
||||||
warn(texts.noServerConsoleMessage)
|
warn(texts.noServerConsoleMessage)
|
||||||
|
warn(e)
|
||||||
|
tryAnotherPeer()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function tryAnotherPeer() {
|
||||||
|
SafeGetElementById('scriptMenuDiv', (elem) => {
|
||||||
|
elem.style.backgroundColor = 'red'
|
||||||
|
})
|
||||||
|
|
||||||
|
debugLog('Unable to connect to main server, trying peers')
|
||||||
|
try {
|
||||||
|
const lastp2pinfo = JSON.parse(getVal('lastp2pinfo'))
|
||||||
|
if (
|
||||||
|
!lastp2pinfo ||
|
||||||
|
(Array.isArray(lastp2pinfo) && lastp2pinfo.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)
|
||||||
|
}
|
||||||
|
|
||||||
|
let suitablePeer = null
|
||||||
|
let i = 0
|
||||||
|
while (suitablePeer === null && i < shuffledPeers.length) {
|
||||||
|
const peer = shuffledPeers[i]
|
||||||
|
i++
|
||||||
|
|
||||||
|
const url = getPeerUrl(peer)
|
||||||
|
SafeGetElementById('infoMainDiv', (elem) => {
|
||||||
|
elem.innerText = texts.tryingPeer + getShortServerURL(url)
|
||||||
|
})
|
||||||
|
debugLog('Trying ' + url)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await head(url)
|
||||||
|
if (res.status === 401) {
|
||||||
|
debugLog(url + ' responded with ' + res.status)
|
||||||
|
} else if (res.status === 200) {
|
||||||
|
suitablePeer = peer
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugLog('Unable to connect!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suitablePeer) {
|
||||||
|
const url = getPeerUrl(suitablePeer)
|
||||||
|
debugLog('Found suitable peer with URL: ' + url + 'index: ' + i)
|
||||||
|
serverAdress = url
|
||||||
|
apiAdress = url + 'api/'
|
||||||
|
if (
|
||||||
|
suitablePeer.host === originalServer.host &&
|
||||||
|
suitablePeer.port === originalServer.port
|
||||||
|
) {
|
||||||
|
setVal('peerToUse', undefined)
|
||||||
|
usingPeer = false
|
||||||
|
} else {
|
||||||
|
setVal('peerToUse', JSON.stringify(suitablePeer))
|
||||||
|
usingPeer = true
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeGetElementById('scriptMenuDiv', (elem) => {
|
||||||
|
elem.style.backgroundColor = '#222426'
|
||||||
|
})
|
||||||
|
|
||||||
|
ConnectToServer()
|
||||||
|
} else {
|
||||||
|
SafeGetElementById('retryContainer', (elem) => {
|
||||||
|
elem.style.display = 'flex'
|
||||||
|
})
|
||||||
|
SafeGetElementById('infoMainDiv', (elem) => {
|
||||||
|
elem.innerText = texts.noPeersOnline
|
||||||
|
})
|
||||||
|
debugLog('None of the peers are online!')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
SafeGetElementById('retryContainer', (elem) => {
|
||||||
|
elem.style.display = 'flex'
|
||||||
|
})
|
||||||
|
SafeGetElementById('infoMainDiv', (elem) => {
|
||||||
|
elem.innerText = texts.peerTryingError
|
||||||
|
})
|
||||||
|
warn('Error ocurred during trying to connect to peers!')
|
||||||
|
warn(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function NoUserAction() {
|
function NoUserAction() {
|
||||||
SafeGetElementById('scriptMenuDiv', (elem) => {
|
SafeGetElementById('scriptMenuDiv', (elem) => {
|
||||||
elem.style.backgroundColor = '#44cc00'
|
elem.style.backgroundColor = '#44cc00'
|
||||||
|
@ -1772,18 +1885,6 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function NoServerAction() {
|
|
||||||
SafeGetElementById('scriptMenuDiv', (elem) => {
|
|
||||||
elem.style.backgroundColor = 'red'
|
|
||||||
})
|
|
||||||
SafeGetElementById('infoMainDiv', (elem) => {
|
|
||||||
elem.innerText = texts.noServer
|
|
||||||
})
|
|
||||||
SafeGetElementById('retryContainer', (elem) => {
|
|
||||||
elem.style.display = 'flex'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function VersionActions() {
|
function VersionActions() {
|
||||||
FreshStart()
|
FreshStart()
|
||||||
}
|
}
|
||||||
|
@ -1836,9 +1937,6 @@
|
||||||
let timeout = null
|
let timeout = null
|
||||||
const greetMsg = []
|
const greetMsg = []
|
||||||
|
|
||||||
if (isNewVersionAvaible || newVersion || showMOTD) {
|
|
||||||
greetMsg.push(texts.scriptName + info().script.version)
|
|
||||||
}
|
|
||||||
if (isNewVersionAvaible) {
|
if (isNewVersionAvaible) {
|
||||||
timeout = 5
|
timeout = 5
|
||||||
greetMsg.push(texts.newVersionAvaible + lastestVersion)
|
greetMsg.push(texts.newVersionAvaible + lastestVersion)
|
||||||
|
@ -1852,12 +1950,14 @@
|
||||||
greetMsg.push(texts.motd + motd)
|
greetMsg.push(texts.motd + motd)
|
||||||
timeout = null
|
timeout = null
|
||||||
}
|
}
|
||||||
|
if (usingPeer) {
|
||||||
|
greetMsg.push(texts.usingpeer)
|
||||||
|
}
|
||||||
|
if (greetMsg.length > 0) {
|
||||||
|
greetMsg.unshift(texts.scriptName + info().script.version)
|
||||||
|
}
|
||||||
|
|
||||||
ShowMessage(
|
ShowMessage(greetMsg.join('\n'), timeout)
|
||||||
greetMsg.join('\n'),
|
|
||||||
|
|
||||||
timeout
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// : }}}
|
// : }}}
|
||||||
|
@ -2167,6 +2267,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConvertedMessageNode(message) {
|
function getConvertedMessageNode(message) {
|
||||||
|
if (!message) return ''
|
||||||
|
|
||||||
const messageNode = document.createElement('p')
|
const messageNode = document.createElement('p')
|
||||||
const resultNode = document.createElement('p')
|
const resultNode = document.createElement('p')
|
||||||
messageNode.innerHTML = message.replace(/\n/g, '</br>')
|
messageNode.innerHTML = message.replace(/\n/g, '</br>')
|
||||||
|
@ -2263,6 +2365,7 @@
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
uiShowing = !uiShowing
|
uiShowing = !uiShowing
|
||||||
|
setVal('uishowing', uiShowing)
|
||||||
}
|
}
|
||||||
|
|
||||||
function SetupMenu() {
|
function SetupMenu() {
|
||||||
|
@ -2315,6 +2418,7 @@
|
||||||
width: width + 'px',
|
width: width + 'px',
|
||||||
opacity: getVal(`${id}_opacity`),
|
opacity: getVal(`${id}_opacity`),
|
||||||
cursor: funct ? 'pointer' : 'move',
|
cursor: funct ? 'pointer' : 'move',
|
||||||
|
display: uiShowing ? '' : 'none',
|
||||||
})
|
})
|
||||||
if (funct) {
|
if (funct) {
|
||||||
addEventListener(messageElem, 'click', funct)
|
addEventListener(messageElem, 'click', funct)
|
||||||
|
@ -2517,7 +2621,14 @@
|
||||||
result.msgContainer.child.leftSideDiv.child.matchPercent.elem.innerText =
|
result.msgContainer.child.leftSideDiv.child.matchPercent.elem.innerText =
|
||||||
isNaN(getCurrMsg().p) ? '' : getCurrMsg().p + '%'
|
isNaN(getCurrMsg().p) ? '' : getCurrMsg().p + '%'
|
||||||
|
|
||||||
|
if (isSimpleMessage) {
|
||||||
|
result.msgContainer.child.msgDiv.elem.replaceChildren()
|
||||||
|
result.msgContainer.child.msgDiv.elem.appendChild(
|
||||||
|
getConvertedMessageNode(getCurrMsg().m)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
result.msgContainer.child.msgDiv.elem.innerText = getCurrMsg().m
|
result.msgContainer.child.msgDiv.elem.innerText = getCurrMsg().m
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
warn('Error in message updating')
|
warn('Error in message updating')
|
||||||
warn(e)
|
warn(e)
|
||||||
|
@ -2545,6 +2656,8 @@
|
||||||
const id = 'scriptMenuDiv'
|
const id = 'scriptMenuDiv'
|
||||||
scriptMenuDiv.setAttribute('id', id)
|
scriptMenuDiv.setAttribute('id', id)
|
||||||
SetStyle(scriptMenuDiv, {
|
SetStyle(scriptMenuDiv, {
|
||||||
|
display: uiShowing ? 'flex' : 'none',
|
||||||
|
flexDirection: 'column',
|
||||||
width: '300px',
|
width: '300px',
|
||||||
height: '90px',
|
height: '90px',
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
|
@ -2599,9 +2712,8 @@
|
||||||
style: {
|
style: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
display: 'inline',
|
display: 'inline',
|
||||||
|
bottom: '20px',
|
||||||
left: '5px',
|
left: '5px',
|
||||||
bottom: '15px',
|
|
||||||
margin: '5px',
|
|
||||||
fontSize: '30px',
|
fontSize: '30px',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
},
|
},
|
||||||
|
@ -2643,12 +2755,20 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
statusContainer: {
|
||||||
|
style: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flex: 1,
|
||||||
|
margin: '0px 50px',
|
||||||
|
},
|
||||||
|
children: {
|
||||||
infoContainer: {
|
infoContainer: {
|
||||||
id: 'infoMainDiv',
|
id: 'infoMainDiv',
|
||||||
innerText: texts.loading,
|
innerText: texts.connecting + getShortServerURL(serverAdress),
|
||||||
style: {
|
style: {
|
||||||
color: '#ffffff',
|
color: '#ffffff',
|
||||||
margin: '5px 50px',
|
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2656,7 +2776,6 @@
|
||||||
id: 'loginDiv',
|
id: 'loginDiv',
|
||||||
style: {
|
style: {
|
||||||
display: 'none',
|
display: 'none',
|
||||||
margin: '0px 50px',
|
|
||||||
},
|
},
|
||||||
children: {
|
children: {
|
||||||
loginInput: {
|
loginInput: {
|
||||||
|
@ -2703,12 +2822,15 @@
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
scriptMenuDiv.style.background = '#262626'
|
scriptMenuDiv.style.background = '#262626'
|
||||||
SafeGetElementById('infoMainDiv', (elem) => {
|
SafeGetElementById('infoMainDiv', (elem) => {
|
||||||
elem.innerText = texts.loading
|
elem.innerText =
|
||||||
|
texts.connecting + getShortServerURL(serverAdress)
|
||||||
})
|
})
|
||||||
SafeGetElementById('retryContainer', (elem) => {
|
SafeGetElementById('retryContainer', (elem) => {
|
||||||
elem.style.display = 'none'
|
elem.style.display = 'none'
|
||||||
})
|
})
|
||||||
ConnectToServer(AfterLoad)
|
ConnectToServer()
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2801,6 +2923,24 @@
|
||||||
log('------------------------------------------')
|
log('------------------------------------------')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getShortServerURL(url) {
|
||||||
|
const maxlegnth = 30
|
||||||
|
const shortUrl = url.replace('https://', '').replace('http://', '')
|
||||||
|
if (shortUrl.length <= maxlegnth) {
|
||||||
|
return shortUrl
|
||||||
|
} else {
|
||||||
|
return shortUrl.substring(0, maxlegnth - 3) + '...'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPeerUrl(peer) {
|
||||||
|
let protocol = 'https://'
|
||||||
|
if (isDevel) {
|
||||||
|
let protocol = 'http://'
|
||||||
|
}
|
||||||
|
return protocol + peer.host + ':' + peer.port + '/'
|
||||||
|
}
|
||||||
|
|
||||||
function getUid() {
|
function getUid() {
|
||||||
return getVal('userId')
|
return getVal('userId')
|
||||||
}
|
}
|
||||||
|
@ -2896,22 +3036,12 @@
|
||||||
const now = new Date().getTime()
|
const now = new Date().getTime()
|
||||||
const lastCheck = getVal('lastInfoCheckTime')
|
const lastCheck = getVal('lastInfoCheckTime')
|
||||||
if (!lastCheck) {
|
if (!lastCheck) {
|
||||||
setVal('lastInfoCheckTime', now)
|
setVal('lastInfoCheckTime', 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastInfo = { result: 'noLastInfo' }
|
let lastInfo = { result: 'noLastInfo' }
|
||||||
try {
|
|
||||||
lastInfo = JSON.parse(getVal('lastInfo'))
|
|
||||||
} catch (e) {
|
|
||||||
if (showErrors) {
|
|
||||||
warn(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (now > lastCheck + infoExpireTime * 1000) {
|
||||||
lastInfo.result !== 'success' ||
|
|
||||||
now > lastCheck + infoExpireTime * 1000
|
|
||||||
) {
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const url =
|
const url =
|
||||||
apiAdress +
|
apiAdress +
|
||||||
|
@ -2923,11 +3053,11 @@
|
||||||
Promise.all([get(url), get(apiAdress + 'hasNewMsg')])
|
Promise.all([get(url), get(apiAdress + 'hasNewMsg')])
|
||||||
.then(([{ responseText: infos }, { responseText: hasNewMsg }]) => {
|
.then(([{ responseText: infos }, { responseText: hasNewMsg }]) => {
|
||||||
try {
|
try {
|
||||||
setVal('lastInfoCheckTime', now)
|
|
||||||
const infosObj = JSON.parse(infos)
|
const infosObj = JSON.parse(infos)
|
||||||
const hasNewMsgsObj = JSON.parse(hasNewMsg)
|
const hasNewMsgsObj = JSON.parse(hasNewMsg)
|
||||||
const merged = Object.assign({}, infosObj, hasNewMsgsObj)
|
const merged = Object.assign({}, infosObj, hasNewMsgsObj)
|
||||||
setVal('lastInfo', JSON.stringify(merged))
|
setVal('lastInfo', JSON.stringify(merged))
|
||||||
|
setVal('lastInfoCheckTime', now)
|
||||||
resolve(merged)
|
resolve(merged)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('Errro paring JSON in GetXHRInfos')
|
log('Errro paring JSON in GetXHRInfos')
|
||||||
|
@ -2944,6 +3074,7 @@
|
||||||
} else {
|
} else {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
|
lastInfo = JSON.parse(getVal('lastInfo'))
|
||||||
resolve(lastInfo)
|
resolve(lastInfo)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('Errro paring JSON in GetXHRInfos, when using old data!')
|
log('Errro paring JSON in GetXHRInfos, when using old data!')
|
||||||
|
@ -2954,12 +3085,102 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateP2pData(newData) {
|
||||||
|
const lastp2pinfo = getVal('lastp2pinfo')
|
||||||
|
const oldPeers = lastp2pinfo ? JSON.parse(lastp2pinfo) : []
|
||||||
|
const merged = newData.reduce((acc, peer) => {
|
||||||
|
const peerAlreadyExists = acc.find((existingPeer) => {
|
||||||
|
const p1 = peer.host + ':' + peer.port
|
||||||
|
const p2 = existingPeer.host + ':' + existingPeer.port
|
||||||
|
return p1 === p2
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!peerAlreadyExists) {
|
||||||
|
peer.added = new Date().getTime()
|
||||||
|
return [peer, ...acc]
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc
|
||||||
|
}, oldPeers)
|
||||||
|
return merged
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPeers() {
|
||||||
|
const now = new Date().getTime()
|
||||||
|
const lastCheck = getVal('lastp2pchecktime')
|
||||||
|
if (!lastCheck) {
|
||||||
|
setVal('lastp2pchecktime', 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastp2pinfo = {}
|
||||||
|
|
||||||
|
if (now > lastCheck + p2pInfoExpireTime * 1000) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const url = apiAdress + 'p2pinfo'
|
||||||
|
|
||||||
|
get(url)
|
||||||
|
.then(({ responseText: p2pinfo }) => {
|
||||||
|
try {
|
||||||
|
const p2pinfoObj = updateP2pData(JSON.parse(p2pinfo).myPeers)
|
||||||
|
setVal('lastp2pinfo', JSON.stringify(p2pinfoObj))
|
||||||
|
setVal('lastp2pchecktime', now)
|
||||||
|
resolve(p2pinfoObj)
|
||||||
|
} catch (e) {
|
||||||
|
log('Errro paring JSON in getPeers')
|
||||||
|
log(p2pinfo)
|
||||||
|
log(e)
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
log('Info get Error', e)
|
||||||
|
reject(e)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
lastp2pinfo = JSON.parse(getVal('lastp2pinfo'))
|
||||||
|
resolve(lastp2pinfo)
|
||||||
|
} catch (e) {
|
||||||
|
log('Errro paring JSON in GetXHRInfos, when using old data!')
|
||||||
|
log(e)
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function head(url) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
xmlhttpRequest({
|
||||||
|
method: 'HEAD',
|
||||||
|
url: url,
|
||||||
|
crossDomain: true,
|
||||||
|
timeout: 5 * 1000,
|
||||||
|
ontimeout: () => {
|
||||||
|
reject(new Error('HEAD request timed out'))
|
||||||
|
},
|
||||||
|
onload: function (response) {
|
||||||
|
resolve(response)
|
||||||
|
},
|
||||||
|
onerror: (e) => {
|
||||||
|
reject(e)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function get(url) {
|
function get(url) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
xmlhttpRequest({
|
xmlhttpRequest({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: url,
|
url: url,
|
||||||
crossDomain: true,
|
crossDomain: true,
|
||||||
|
timeout: 15 * 1000,
|
||||||
|
ontimeout: () => {
|
||||||
|
reject(new Error('GET request timed out'))
|
||||||
|
},
|
||||||
xhrFields: { withCredentials: true },
|
xhrFields: { withCredentials: true },
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
@ -2984,6 +3205,10 @@
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: url,
|
url: url,
|
||||||
crossDomain: true,
|
crossDomain: true,
|
||||||
|
timeout: 30 * 1000,
|
||||||
|
ontimeout: () => {
|
||||||
|
reject(new Error('POST request timed out'))
|
||||||
|
},
|
||||||
xhrFields: { withCredentials: true },
|
xhrFields: { withCredentials: true },
|
||||||
data: message,
|
data: message,
|
||||||
headers: {
|
headers: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue