diff --git a/bower_components/speed/empty.php b/bower_components/speed/empty.php new file mode 100644 index 000000000..7395f6cc7 --- /dev/null +++ b/bower_components/speed/empty.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/bower_components/speed/garbage.php b/bower_components/speed/garbage.php new file mode 100644 index 000000000..8aa73e5c4 --- /dev/null +++ b/bower_components/speed/garbage.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/bower_components/speed/getIP.php b/bower_components/speed/getIP.php new file mode 100644 index 000000000..0b55b77e0 --- /dev/null +++ b/bower_components/speed/getIP.php @@ -0,0 +1,3 @@ + diff --git a/bower_components/speed/speedtest_worker.js b/bower_components/speed/speedtest_worker.js new file mode 100644 index 000000000..19bc8aaf4 --- /dev/null +++ b/bower_components/speed/speedtest_worker.js @@ -0,0 +1,350 @@ +/* + HTML5 Speedtest v4.2.1 + by Federico Dossena + https://github.com/adolfintel/speedtest/ + GNU LGPLv3 License +*/ + +// data reported to main thread +var testStatus = 0 // 0=not started, 1=download test, 2=ping+jitter test, 3=upload test, 4=finished, 5=abort/error +var dlStatus = '' // download speed in megabit/s with 2 decimal digits +var ulStatus = '' // upload speed in megabit/s with 2 decimal digits +var pingStatus = '' // ping in milliseconds with 2 decimal digits +var jitterStatus = '' // jitter in milliseconds with 2 decimal digits +var clientIp = '' // client's IP address as reported by getIP.php + +// test settings. can be overridden by sending specific values with the start command +var settings = { + time_ul: 15, // duration of upload test in seconds + time_dl: 15, // duration of download test in seconds + count_ping: 35, // number of pings to perform in ping test + url_dl: 'garbage.php', // path to a large file or garbage.php, used for download test. must be relative to this js file + url_ul: 'empty.php', // path to an empty file, used for upload test. must be relative to this js file + url_ping: 'empty.php', // path to an empty file, used for ping test. must be relative to this js file + url_getIp: 'getIP.php', // path to getIP.php relative to this js file, or a similar thing that outputs the client's ip + xhr_dlMultistream: 10, // number of download streams to use (can be different if enable_quirks is active) + xhr_ulMultistream: 3, // number of upload streams to use (can be different if enable_quirks is active) + xhr_dlUseBlob: false, // if set to true, it reduces ram usage but uses the hard drive (useful with large garbagePhp_chunkSize and/or high xhr_dlMultistream) + garbagePhp_chunkSize: 20, // size of chunks sent by garbage.php (can be different if enable_quirks is active) + enable_quirks: true, // enable quirks for specific browsers. currently it overrides settings to optimize for specific browsers, unless they are already being overridden with the start command + allow_fetchAPI: false, // enables Fetch API. currently disabled because it leaks memory like no tomorrow + force_fetchAPI: false // when Fetch API is enabled, it will force usage on every browser that supports it +} + +var xhr = null // array of currently active xhr requests +var interval = null // timer used in tests + +/* + when set to true (automatically) the download test will use the fetch api instead of xhr. + fetch api is used if + -allow_fetchAPI is true AND + -(we're on chrome that supports fetch api AND enable_quirks is true) OR (we're on any browser that supports fetch api AND force_fetchAPI is true) +*/ +var useFetchAPI = false + +/* + listener for commands from main thread to this worker. + commands: + -status: returns the current status as a string of values spearated by a semicolon (;) in this order: testStatus;dlStatus;ulStatus;pingStatus;clientIp;jitterStatus + -abort: aborts the current test + -start: starts the test. optionally, settings can be passed as JSON. + example: start {"time_ul":"10", "time_dl":"10", "count_ping":"50"} +*/ +this.addEventListener('message', function (e) { + var params = e.data.split(' ') + if (params[0] === 'status') { // return status + postMessage(testStatus + ';' + dlStatus + ';' + ulStatus + ';' + pingStatus + ';' + clientIp + ';' + jitterStatus) + } + if (params[0] === 'start' && testStatus === 0) { // start new test + testStatus = 1 + try { + // parse settings, if present + var s = JSON.parse(e.data.substring(5)) + if (typeof s.url_dl !== 'undefined') settings.url_dl = s.url_dl // download url + if (typeof s.url_ul !== 'undefined') settings.url_ul = s.url_ul // upload url + if (typeof s.url_ping !== 'undefined') settings.url_ping = s.url_ping // ping url + if (typeof s.url_getIp !== 'undefined') settings.url_getIp = s.url_getIp // url to getIP.php + if (typeof s.time_dl !== 'undefined') settings.time_dl = s.time_dl // duration of download test + if (typeof s.time_ul !== 'undefined') settings.time_ul = s.time_ul // duration of upload test + if (typeof s.enable_quirks !== 'undefined') settings.enable_quirks = s.enable_quirks // enable quirks or not + if (typeof s.allow_fetchAPI !== 'undefined') settings.allow_fetchAPI = s.allow_fetchAPI // allows fetch api to be used if supported + // quirks for specific browsers. more may be added in future releases + if (settings.enable_quirks) { + var ua = navigator.userAgent + if (/Firefox.(\d+\.\d+)/i.test(ua)) { + // ff more precise with 1 upload stream + settings.xhr_ulMultistream = 1 + } + if (/Edge.(\d+\.\d+)/i.test(ua)) { + // edge more precise with 3 download streams + settings.xhr_dlMultistream = 3 + } + if ((/Safari.(\d+)/i.test(ua)) && !(/Chrome.(\d+)/i.test(ua))) { + // safari more precise with 10 upload streams and 5mb chunks for download test + settings.xhr_ulMultistream = 10 + settings.garbagePhp_chunkSize = 5 + } + if (/Chrome.(\d+)/i.test(ua) && (!!self.fetch)) { + // chrome can't handle large xhr very well, use fetch api if available and allowed + if (settings.allow_fetchAPI) useFetchAPI = true + // chrome more precise with 5 streams + settings.xhr_dlMultistream = 5 + } + } + if (typeof s.count_ping !== 'undefined') settings.count_ping = s.count_ping // number of pings for ping test + if (typeof s.xhr_dlMultistream !== 'undefined') settings.xhr_dlMultistream = s.xhr_dlMultistream // number of download streams + if (typeof s.xhr_ulMultistream !== 'undefined') settings.xhr_ulMultistream = s.xhr_ulMultistream // number of upload streams + if (typeof s.xhr_dlUseBlob !== 'undefined') settings.xhr_dlUseBlob = s.xhr_dlUseBlob // use blob for download test + if (typeof s.garbagePhp_chunkSize !== 'undefined') settings.garbagePhp_chunkSize = s.garbagePhp_chunkSize // size of garbage.php chunks + if (typeof s.force_fetchAPI !== 'undefined') settings.force_fetchAPI = s.force_fetchAPI // use fetch api on all browsers that support it if enabled + if (settings.allow_fetchAPI && settings.force_fetchAPI && (!!self.fetch)) useFetchAPI = true + } catch (e) { } + // run the tests + console.log(settings) + console.log('Fetch API: ' + useFetchAPI) + getIp(function () { dlTest(function () { testStatus = 2; pingTest(function () { testStatus = 3; ulTest(function () { testStatus = 4 }) }) }) }) + } + if (params[0] === 'abort') { // abort command + clearRequests() // stop all xhr activity + if (interval) clearInterval(interval) // clear timer if present + testStatus = 5; dlStatus = ''; ulStatus = ''; pingStatus = ''; jitterStatus = '' // set test as aborted + } +}) +// stops all XHR activity, aggressively +function clearRequests () { + if (xhr) { + for (var i = 0; i < xhr.length; i++) { + if (useFetchAPI) try { xhr[i].cancelRequested = true } catch (e) { } + try { xhr[i].onprogress = null; xhr[i].onload = null; xhr[i].onerror = null } catch (e) { } + try { xhr[i].upload.onprogress = null; xhr[i].upload.onload = null; xhr[i].upload.onerror = null } catch (e) { } + try { xhr[i].abort() } catch (e) { } + try { delete (xhr[i]) } catch (e) { } + } + xhr = null + } +} +// gets client's IP using url_getIp, then calls the done function +function getIp (done) { + xhr = new XMLHttpRequest() + xhr.onload = function () { + clientIp = xhr.responseText + done() + } + xhr.onerror = function () { + done() + } + xhr.open('GET', settings.url_getIp + '?r=' + Math.random(), true) + xhr.send() +} +// download test, calls done function when it's over +var dlCalled = false // used to prevent multiple accidental calls to dlTest +function dlTest (done) { + if (dlCalled) return; else dlCalled = true // dlTest already called? + var totLoaded = 0.0, // total number of loaded bytes + startT = new Date().getTime(), // timestamp when test was started + failed = false // set to true if a stream fails + xhr = [] + // function to create a download stream. streams are slightly delayed so that they will not end at the same time + var testStream = function (i, delay) { + setTimeout(function () { + if (testStatus !== 1) return // delayed stream ended up starting after the end of the download test + if (useFetchAPI) { + xhr[i] = fetch(settings.url_dl + '?r=' + Math.random() + '&ckSize=' + settings.garbagePhp_chunkSize).then(function (response) { + var reader = response.body.getReader() + var consume = function () { + return reader.read().then(function (result) { + if (result.done) testStream(i); else { + totLoaded += result.value.length + if (xhr[i].cancelRequested) reader.cancel() + } + return consume() + }.bind(this)) + }.bind(this) + return consume() + }.bind(this)) + } else { + var prevLoaded = 0 // number of bytes loaded last time onprogress was called + var x = new XMLHttpRequest() + xhr[i] = x + xhr[i].onprogress = function (event) { + if (testStatus !== 1) { try { x.abort() } catch (e) { } } // just in case this XHR is still running after the download test + // progress event, add number of new loaded bytes to totLoaded + var loadDiff = event.loaded <= 0 ? 0 : (event.loaded - prevLoaded) + if (isNaN(loadDiff) || !isFinite(loadDiff) || loadDiff < 0) return // just in case + totLoaded += loadDiff + prevLoaded = event.loaded + }.bind(this) + xhr[i].onload = function () { + // the large file has been loaded entirely, start again + try { xhr[i].abort() } catch (e) { } // reset the stream data to empty ram + testStream(i, 0) + }.bind(this) + xhr[i].onerror = function () { + // error, abort + failed = true + try { xhr[i].abort() } catch (e) { } + delete (xhr[i]) + }.bind(this) + // send xhr + try { if (settings.xhr_dlUseBlob) xhr[i].responseType = 'blob'; else xhr[i].responseType = 'arraybuffer' } catch (e) { } + xhr[i].open('GET', settings.url_dl + '?r=' + Math.random() + '&ckSize=' + settings.garbagePhp_chunkSize, true) // random string to prevent caching + xhr[i].send() + } + }.bind(this), 1 + delay) + }.bind(this) + // open streams + for (var i = 0; i < settings.xhr_dlMultistream; i++) { + testStream(i, 100 * i) + } + // every 200ms, update dlStatus + interval = setInterval(function () { + var t = new Date().getTime() - startT + if (t < 200) return + var speed = totLoaded / (t / 1000.0) + dlStatus = ((speed * 8) / 925000.0).toFixed(2) // 925000 instead of 1048576 to account for overhead + if ((t / 1000.0) > settings.time_dl || failed) { // test is over, stop streams and timer + if (failed || isNaN(dlStatus)) dlStatus = 'Fail' + clearRequests() + clearInterval(interval) + done() + } + }.bind(this), 200) +} +// upload test, calls done function whent it's over +// garbage data for upload test +var r = new ArrayBuffer(1048576) +try { r = new Float32Array(r); for (var i = 0; i < r.length; i++)r[i] = Math.random() } catch (e) { } +var req = [] +var reqsmall = [] +for (var i = 0; i < 20; i++) req.push(r) +req = new Blob(req) +r = new ArrayBuffer(262144) +try { r = new Float32Array(r); for (var i = 0; i < r.length; i++)r[i] = Math.random() } catch (e) { } +reqsmall.push(r) +reqsmall = new Blob(reqsmall) +var ulCalled = false // used to prevent multiple accidental calls to ulTest +function ulTest (done) { + if (ulCalled) return; else ulCalled = true // ulTest already called? + var totLoaded = 0.0 // total number of transmitted bytes + var startT = new Date().getTime() // timestamp when test was started + var failed = false // set to true if a stream fails + xhr = [] + // function to create an upload stream. streams are slightly delayed so that they will not end at the same time + var testStream = function (i, delay) { + setTimeout(function () { + if (testStatus !== 3) return // delayed stream ended up starting after the end of the upload test + var prevLoaded = 0 // number of bytes transmitted last time onprogress was called + var x = new XMLHttpRequest() + xhr[i] = x + var ie11workaround + try { + xhr[i].upload.onprogress + ie11workaround = false + } catch (e) { + ie11workaround = true + } + if (ie11workaround) { + // IE11 workarond: xhr.upload does not work properly, therefore we send a bunch of small 256k requests and use the onload event as progress. This is not precise, especially on fast connections + xhr[i].onload = function () { + totLoaded += 262144 + testStream(i, 0) + } + xhr[i].onerror = function () { + // error, abort + failed = true + try { xhr[i].abort() } catch (e) { } + delete (xhr[i]) + } + xhr[i].open('POST', settings.url_ul + '?r=' + Math.random(), true) // random string to prevent caching + xhr[i].setRequestHeader('Content-Encoding', 'identity') // disable compression (some browsers may refuse it, but data is incompressible anyway) + xhr[i].send(reqsmall) + } else { + // REGULAR version, no workaround + xhr[i].upload.onprogress = function (event) { + if (testStatus !== 3) { try { x.abort() } catch (e) { } } // just in case this XHR is still running after the upload test + // progress event, add number of new loaded bytes to totLoaded + var loadDiff = event.loaded <= 0 ? 0 : (event.loaded - prevLoaded) + if (isNaN(loadDiff) || !isFinite(loadDiff) || loadDiff < 0) return // just in case + totLoaded += loadDiff + prevLoaded = event.loaded + }.bind(this) + xhr[i].upload.onload = function () { + // this stream sent all the garbage data, start again + testStream(i, 0) + }.bind(this) + xhr[i].upload.onerror = function () { + // error, abort + failed = true + try { xhr[i].abort() } catch (e) { } + delete (xhr[i]) + }.bind(this) + // send xhr + xhr[i].open('POST', settings.url_ul + '?r=' + Math.random(), true) // random string to prevent caching + xhr[i].setRequestHeader('Content-Encoding', 'identity') // disable compression (some browsers may refuse it, but data is incompressible anyway) + xhr[i].send(req) + } + }.bind(this), 1) + }.bind(this) + // open streams + for (var i = 0; i < settings.xhr_ulMultistream; i++) { + testStream(i, 100 * i) + } + // every 200ms, update ulStatus + interval = setInterval(function () { + var t = new Date().getTime() - startT + if (t < 200) return + var speed = totLoaded / (t / 1000.0) + ulStatus = ((speed * 8) / 925000.0).toFixed(2) // 925000 instead of 1048576 to account for overhead + if ((t / 1000.0) > settings.time_ul || failed) { // test is over, stop streams and timer + if (failed || isNaN(ulStatus)) ulStatus = 'Fail' + clearRequests() + clearInterval(interval) + done() + } + }.bind(this), 200) +} +// ping+jitter test, function done is called when it's over +var ptCalled = false // used to prevent multiple accidental calls to pingTest +function pingTest (done) { + if (ptCalled) return; else ptCalled = true // pingTest already called? + var prevT = null // last time a pong was received + var ping = 0.0 // current ping value + var jitter = 0.0 // current jitter value + var i = 0 // counter of pongs received + var prevInstspd = 0 // last ping time, used for jitter calculation + xhr = [] + // ping function + var doPing = function () { + prevT = new Date().getTime() + xhr[0] = new XMLHttpRequest() + xhr[0].onload = function () { + // pong + if (i === 0) { + prevT = new Date().getTime() // first pong + } else { + var instspd = (new Date().getTime() - prevT) / 2 + var instjitter = Math.abs(instspd - prevInstspd) + if (i === 1) ping = instspd; /* first ping, can't tell jiutter yet*/ else { + ping = ping * 0.9 + instspd * 0.1 // ping, weighted average + jitter = instjitter > jitter ? (jitter * 0.2 + instjitter * 0.8) : (jitter * 0.9 + instjitter * 0.1) // update jitter, weighted average. spikes in ping values are given more weight. + } + prevInstspd = instspd + } + pingStatus = ping.toFixed(2) + jitterStatus = jitter.toFixed(2) + i++ + if (i < settings.count_ping) doPing(); else done() // more pings to do? + }.bind(this) + xhr[0].onerror = function () { + // a ping failed, cancel test + pingStatus = 'Fail' + jitterStatus = 'Fail' + clearRequests() + done() + }.bind(this) + // sent xhr + xhr[0].open('GET', settings.url_ping + '?r=' + Math.random(), true) // random string to prevent caching + xhr[0].send() + }.bind(this) + doPing() // start first ping +} diff --git a/bower_components/speed/speedtest_worker.min.js b/bower_components/speed/speedtest_worker.min.js new file mode 100644 index 000000000..fab73a0fb --- /dev/null +++ b/bower_components/speed/speedtest_worker.min.js @@ -0,0 +1 @@ +function clearRequests(){if(xhr){for(var i=0;iloadDiff||(totLoaded+=loadDiff,prevLoaded=event.loaded)}.bind(this),xhr[i].onload=function(){try{xhr[i].abort()}catch(e){}testStream(i,0)}.bind(this),xhr[i].onerror=function(){failed=!0;try{xhr[i].abort()}catch(e){}delete xhr[i]}.bind(this);try{settings.xhr_dlUseBlob?xhr[i].responseType="blob":xhr[i].responseType="arraybuffer"}catch(e){}xhr[i].open("GET",settings.url_dl+"?r="+Math.random()+"&ckSize="+settings.garbagePhp_chunkSize,!0),xhr[i].send()}}.bind(this),1+delay)}.bind(this),i=0;it)){var speed=totLoaded/(t/1e3);dlStatus=(8*speed/925e3).toFixed(2),(t/1e3>settings.time_dl||failed)&&((failed||isNaN(dlStatus))&&(dlStatus="Fail"),clearRequests(),clearInterval(interval),done())}}.bind(this),200)}}function ulTest(done){if(!ulCalled){ulCalled=!0;var totLoaded=0,startT=(new Date).getTime(),failed=!1;xhr=[];for(var testStream=function(i,delay){setTimeout(function(){if(3===testStatus){var prevLoaded=0,x=new XMLHttpRequest;xhr[i]=x;var ie11workaround;try{xhr[i].upload.onprogress,ie11workaround=!1}catch(e){ie11workaround=!0}ie11workaround?(xhr[i].onload=function(){totLoaded+=262144,testStream(i,0)},xhr[i].onerror=function(){failed=!0;try{xhr[i].abort()}catch(e){}delete xhr[i]},xhr[i].open("POST",settings.url_ul+"?r="+Math.random(),!0),xhr[i].setRequestHeader("Content-Encoding","identity"),xhr[i].send(reqsmall)):(xhr[i].upload.onprogress=function(event){if(3!==testStatus)try{x.abort()}catch(e){}var loadDiff=event.loaded<=0?0:event.loaded-prevLoaded;isNaN(loadDiff)||!isFinite(loadDiff)||0>loadDiff||(totLoaded+=loadDiff,prevLoaded=event.loaded)}.bind(this),xhr[i].upload.onload=function(){testStream(i,0)}.bind(this),xhr[i].upload.onerror=function(){failed=!0;try{xhr[i].abort()}catch(e){}delete xhr[i]}.bind(this),xhr[i].open("POST",settings.url_ul+"?r="+Math.random(),!0),xhr[i].setRequestHeader("Content-Encoding","identity"),xhr[i].send(req))}}.bind(this),1)}.bind(this),i=0;it)){var speed=totLoaded/(t/1e3);ulStatus=(8*speed/925e3).toFixed(2),(t/1e3>settings.time_ul||failed)&&((failed||isNaN(ulStatus))&&(ulStatus="Fail"),clearRequests(),clearInterval(interval),done())}}.bind(this),200)}}function pingTest(done){if(!ptCalled){ptCalled=!0;var prevT=null,ping=0,jitter=0,i=0,prevInstspd=0;xhr=[];var doPing=function(){prevT=(new Date).getTime(),xhr[0]=new XMLHttpRequest,xhr[0].onload=function(){if(0===i)prevT=(new Date).getTime();else{var instspd=((new Date).getTime()-prevT)/2,instjitter=Math.abs(instspd-prevInstspd);1===i?ping=instspd:(ping=.9*ping+.1*instspd,jitter=instjitter>jitter?.2*jitter+.8*instjitter:.9*jitter+.1*instjitter),prevInstspd=instspd}pingStatus=ping.toFixed(2),jitterStatus=jitter.toFixed(2),i++,ii;i++)req.push(r);req=new Blob(req),r=new ArrayBuffer(262144);try{r=new Float32Array(r);for(var i=0;isetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$dbOptions = $file_db->query('SELECT name FROM sqlite_master WHERE type="table" AND name="options"'); + +$hasOptions = "No"; + +foreach($dbOptions as $row) : + + if (in_array("options", $row)) : + $hasOptions = "Yes"; + endif; + +endforeach; + +if($hasOptions == "No") : + + $title = "Organizr"; + $topbar = "#333333"; + $topbartext = "#66D9EF"; + $bottombar = "#333333"; + $sidebar = "#393939"; + $hoverbg = "#AD80FD"; + $activetabBG = "#F92671"; + $activetabicon = "#FFFFFF"; + $activetabtext = "#FFFFFF"; + $inactiveicon = "#66D9EF"; + $inactivetext = "#66D9EF"; + $loading = "#66D9EF"; + $hovertext = "#000000"; + +endif; + +if($hasOptions == "Yes") : + + $resulto = $file_db->query('SELECT * FROM options'); + foreach($resulto as $row) : + + $title = isset($row['title']) ? $row['title'] : "Organizr"; + $topbartext = isset($row['topbartext']) ? $row['topbartext'] : "#66D9EF"; + $topbar = isset($row['topbar']) ? $row['topbar'] : "#333333"; + $bottombar = isset($row['bottombar']) ? $row['bottombar'] : "#333333"; + $sidebar = isset($row['sidebar']) ? $row['sidebar'] : "#393939"; + $hoverbg = isset($row['hoverbg']) ? $row['hoverbg'] : "#AD80FD"; + $activetabBG = isset($row['activetabBG']) ? $row['activetabBG'] : "#F92671"; + $activetabicon = isset($row['activetabicon']) ? $row['activetabicon'] : "#FFFFFF"; + $activetabtext = isset($row['activetabtext']) ? $row['activetabtext'] : "#FFFFFF"; + $inactiveicon = isset($row['inactiveicon']) ? $row['inactiveicon'] : "#66D9EF"; + $inactivetext = isset($row['inactivetext']) ? $row['inactivetext'] : "#66D9EF"; + $loading = isset($row['loading']) ? $row['loading'] : "#66D9EF"; + $hovertext = isset($row['hovertext']) ? $row['hovertext'] : "#000000"; + + endforeach; + +endif; +?> + + + + + + + + + + + + <?=$title;?> Chat + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+

Welcome To The Chat username;?>

+
+
+
    +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + diff --git a/chatAJAX.php b/chatAJAX.php new file mode 100644 index 000000000..28d8f8b26 --- /dev/null +++ b/chatAJAX.php @@ -0,0 +1,96 @@ +exec($sql); + sleep(0.5); + $ret = $db->exec('PRAGMA journal_mode = wal;'); + sleep(0.5); + + + header("Refresh:0"); + } + catch(PDOException $e){ + die('Failed to execute query:'. $e->getMessage()); + } + + $db=null; + +}elseif(file_exists(CHATDB)) { + + try{ + $db = new PDO('sqlite:'.CHATDB); + } + catch(PDOException $e){ + die('Failed to connect:'. $e->getMessage()); + } +} + +//check to see if the ajax call was to update db + +if (isset($_POST['text'])){ + + $msg=$_POST['text']; + $us=$_POST['user']; + $email=$_POST['email']; + + $sql ="INSERT INTO MESSAGES (USER,MESSAGE,EMAIL) VALUES(?, ?, ?)"; + + try{ + $ret = $db->prepare($sql); + $ret->execute([$us,$msg, $email]); + } + catch(PDOException $e){ + console.log('Failed to update db:'. $e->getMessage()); + } +}else{ + //the script will run for 20 seconds after the initial ajax call + $time=time()+20; + + while(time()<$time){ + if ($_POST['time']){ + $prevtime=$_POST['time']; + } + else { + $prevtime=0; + } + //query to see if there are new messages + + $sql ="SELECT TIME,USER,MESSAGE,EMAIL FROM MESSAGES WHERE TIME>? ORDER BY TIME ASC"; + + try{ + $ret = $db->prepare($sql); + $ret->execute([$prevtime]); + + $resarr = $ret->fetchAll(PDO::FETCH_ASSOC); + + //if there are no new messages in the db, sleep for half a second and then run loop again + if (!$resarr) + sleep(0.5); + else{ + echo json_encode($resarr); + break; + } + } + catch(PDOException $e){ + console.log('Failed to get messages:'. $e->getMessage()); + } + } +} + +$db=null; + +?> \ No newline at end of file diff --git a/chatjs.php b/chatjs.php new file mode 100644 index 000000000..df64b556e --- /dev/null +++ b/chatjs.php @@ -0,0 +1,386 @@ +email ) ) ); +header("Content-type: application/javascript"); +?> +/* + * JavaScript MD5 + * https://github.com/blueimp/JavaScript-MD5 + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * https://opensource.org/licenses/MIT + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/* global define */ + +;(function ($) { + 'use strict' + + /* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + function safeAdd (x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF) + var msw = (x >> 16) + (y >> 16) + (lsw >> 16) + return (msw << 16) | (lsw & 0xFFFF) + } + + /* + * Bitwise rotate a 32-bit number to the left. + */ + function bitRotateLeft (num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)) + } + + /* + * These functions implement the four basic operations the algorithm uses. + */ + function md5cmn (q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b) + } + function md5ff (a, b, c, d, x, s, t) { + return md5cmn((b & c) | ((~b) & d), a, b, x, s, t) + } + function md5gg (a, b, c, d, x, s, t) { + return md5cmn((b & d) | (c & (~d)), a, b, x, s, t) + } + function md5hh (a, b, c, d, x, s, t) { + return md5cmn(b ^ c ^ d, a, b, x, s, t) + } + function md5ii (a, b, c, d, x, s, t) { + return md5cmn(c ^ (b | (~d)), a, b, x, s, t) + } + + /* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ + function binlMD5 (x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << (len % 32) + x[(((len + 64) >>> 9) << 4) + 14] = len + + var i + var olda + var oldb + var oldc + var oldd + var a = 1732584193 + var b = -271733879 + var c = -1732584194 + var d = 271733878 + + for (i = 0; i < x.length; i += 16) { + olda = a + oldb = b + oldc = c + oldd = d + + a = md5ff(a, b, c, d, x[i], 7, -680876936) + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586) + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819) + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330) + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897) + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426) + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341) + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983) + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416) + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417) + c = md5ff(c, d, a, b, x[i + 10], 17, -42063) + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162) + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682) + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101) + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290) + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329) + + a = md5gg(a, b, c, d, x[i + 1], 5, -165796510) + d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632) + c = md5gg(c, d, a, b, x[i + 11], 14, 643717713) + b = md5gg(b, c, d, a, x[i], 20, -373897302) + a = md5gg(a, b, c, d, x[i + 5], 5, -701558691) + d = md5gg(d, a, b, c, x[i + 10], 9, 38016083) + c = md5gg(c, d, a, b, x[i + 15], 14, -660478335) + b = md5gg(b, c, d, a, x[i + 4], 20, -405537848) + a = md5gg(a, b, c, d, x[i + 9], 5, 568446438) + d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690) + c = md5gg(c, d, a, b, x[i + 3], 14, -187363961) + b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501) + a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467) + d = md5gg(d, a, b, c, x[i + 2], 9, -51403784) + c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473) + b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734) + + a = md5hh(a, b, c, d, x[i + 5], 4, -378558) + d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463) + c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562) + b = md5hh(b, c, d, a, x[i + 14], 23, -35309556) + a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060) + d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353) + c = md5hh(c, d, a, b, x[i + 7], 16, -155497632) + b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640) + a = md5hh(a, b, c, d, x[i + 13], 4, 681279174) + d = md5hh(d, a, b, c, x[i], 11, -358537222) + c = md5hh(c, d, a, b, x[i + 3], 16, -722521979) + b = md5hh(b, c, d, a, x[i + 6], 23, 76029189) + a = md5hh(a, b, c, d, x[i + 9], 4, -640364487) + d = md5hh(d, a, b, c, x[i + 12], 11, -421815835) + c = md5hh(c, d, a, b, x[i + 15], 16, 530742520) + b = md5hh(b, c, d, a, x[i + 2], 23, -995338651) + + a = md5ii(a, b, c, d, x[i], 6, -198630844) + d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415) + c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905) + b = md5ii(b, c, d, a, x[i + 5], 21, -57434055) + a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571) + d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606) + c = md5ii(c, d, a, b, x[i + 10], 15, -1051523) + b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799) + a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359) + d = md5ii(d, a, b, c, x[i + 15], 10, -30611744) + c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380) + b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649) + a = md5ii(a, b, c, d, x[i + 4], 6, -145523070) + d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379) + c = md5ii(c, d, a, b, x[i + 2], 15, 718787259) + b = md5ii(b, c, d, a, x[i + 9], 21, -343485551) + + a = safeAdd(a, olda) + b = safeAdd(b, oldb) + c = safeAdd(c, oldc) + d = safeAdd(d, oldd) + } + return [a, b, c, d] + } + + /* + * Convert an array of little-endian words to a string + */ + function binl2rstr (input) { + var i + var output = '' + var length32 = input.length * 32 + for (i = 0; i < length32; i += 8) { + output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF) + } + return output + } + + /* + * Convert a raw string to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ + function rstr2binl (input) { + var i + var output = [] + output[(input.length >> 2) - 1] = undefined + for (i = 0; i < output.length; i += 1) { + output[i] = 0 + } + var length8 = input.length * 8 + for (i = 0; i < length8; i += 8) { + output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32) + } + return output + } + + /* + * Calculate the MD5 of a raw string + */ + function rstrMD5 (s) { + return binl2rstr(binlMD5(rstr2binl(s), s.length * 8)) + } + + /* + * Calculate the HMAC-MD5, of a key and some data (raw strings) + */ + function rstrHMACMD5 (key, data) { + var i + var bkey = rstr2binl(key) + var ipad = [] + var opad = [] + var hash + ipad[15] = opad[15] = undefined + if (bkey.length > 16) { + bkey = binlMD5(bkey, key.length * 8) + } + for (i = 0; i < 16; i += 1) { + ipad[i] = bkey[i] ^ 0x36363636 + opad[i] = bkey[i] ^ 0x5C5C5C5C + } + hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8) + return binl2rstr(binlMD5(opad.concat(hash), 512 + 128)) + } + + /* + * Convert a raw string to a hex string + */ + function rstr2hex (input) { + var hexTab = '0123456789abcdef' + var output = '' + var x + var i + for (i = 0; i < input.length; i += 1) { + x = input.charCodeAt(i) + output += hexTab.charAt((x >>> 4) & 0x0F) + + hexTab.charAt(x & 0x0F) + } + return output + } + + /* + * Encode a string as utf-8 + */ + function str2rstrUTF8 (input) { + return unescape(encodeURIComponent(input)) + } + + /* + * Take string arguments and return either raw or hex encoded strings + */ + function rawMD5 (s) { + return rstrMD5(str2rstrUTF8(s)) + } + function hexMD5 (s) { + return rstr2hex(rawMD5(s)) + } + function rawHMACMD5 (k, d) { + return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d)) + } + function hexHMACMD5 (k, d) { + return rstr2hex(rawHMACMD5(k, d)) + } + + function md5 (string, key, raw) { + if (!key) { + if (!raw) { + return hexMD5(string) + } + return rawMD5(string) + } + if (!raw) { + return hexHMACMD5(key, string) + } + return rawHMACMD5(key, string) + } + + if (typeof define === 'function' && define.amd) { + define(function () { + return md5 + }) + } else if (typeof module === 'object' && module.exports) { + module.exports = md5 + } else { + $.md5 = md5 + } +}(this)); + +var last_time=0; +function sendText(){ + $('#writehere')[0].onkeydown=function(e){ + if (e.keyCode==13){ + e.preventDefault(); + if (this.value){ + var datatosend={"text":this.value,"user":"username;?>","email":"email;?>"}; + $.ajax({ + type:"POST", + url:"chatAJAX.php", + data:datatosend, + datatype:"json", + success:function(data){} + }) + this.value=''; + $("#writehere").attr('placeholder', "Sending"); + $("#writehere").prop('disabled', true); + + } + } + } +} + +function checkText(){ + $.ajax({ + type:"POST", + url:"chatAJAX.php", + data:{time:last_time}, + datatype:"json", + success:function(data){ + if (data){ + data=JSON.parse(data); + for (var i=0; iusername;?>"){ + $('#messages').append( + '
  • user

    ' + data[i].USER + '

    '+ (setDateTime(data[i].TIME)) + '

    ' + data[i].MESSAGE + '
  • ' + ); + $(".box").animate({ scrollTop: $('.box').prop("scrollHeight")}, 0); + }else{ + $('#messages').append( + '
  • user

    ' + data[i].USER + '

    '+ (setDateTime(data[i].TIME)) + '

    ' + data[i].MESSAGE + '
  • ' + ); + $(".box").animate({ scrollTop: $('.box').prop("scrollHeight")}, 0); + } + } + last_time=Date.now()/1000; + $('#messages').scrollTop($('#messages')[0].scrollHeight); + } + checkText(); + $("#writehere").attr('placeholder', "Enter your text"); + $("#writehere").prop('disabled', false); + $("#writehere").focus(); + } + }); +} + +function datecompare(date1, sign, date2) { + var day1 = date1.getDate(); + var mon1 = date1.getMonth(); + var year1 = date1.getFullYear(); + var day2 = date2.getDate(); + var mon2 = date2.getMonth(); + var year2 = date2.getFullYear(); + if (sign === '===') { + if (day1 === day2 && mon1 === mon2 && year1 === year2) return true; + else return false; + } + else if (sign === '>') { + if (year1 > year2) return true; + else if (year1 === year2 && mon1 > mon2) return true; + else if (year1 === year2 && mon1 === mon2 && day1 > day2) return true; + else return false; + } +} + +function setDateTime(timedate){ + var tempdate=new Date(timedate*1000), + date=TwoDigits(tempdate.getDate()), + month=TwoDigits(tempdate.getMonth()+1), + year=tempdate.getFullYear(), + hours=TwoDigits(tempdate.getHours()), + mins=TwoDigits(tempdate.getMinutes()), + sec=TwoDigits(tempdate.getSeconds()); + var Today = new Date(); + if(datecompare(Today, ">", tempdate)){ + return (month+'-'+date+' '+hours+':'+mins ); + } + if(datecompare(Today, "===", tempdate)){ + return (hours+':'+mins ); + } +} + +function TwoDigits(number){ + return (number<10 ? '0' : '') + number; +} + +sendText(); +checkText(); \ No newline at end of file diff --git a/config/configDefaults.php b/config/configDefaults.php index 97dd9e753..41c58da7f 100644 --- a/config/configDefaults.php +++ b/config/configDefaults.php @@ -71,4 +71,5 @@ "homepageCustomHTML1Auth" => false, "git_branch" => "master", "git_check" => true, + "speedTest" => false, ); diff --git a/css/style.css b/css/style.css index d9a65d7be..12e3207bc 100644 --- a/css/style.css +++ b/css/style.css @@ -1,4 +1,4 @@ -@charset "UTF-8"; +@charset "UTF-8"; /* * * ADVANTAGE - Responsive Admin Theme @@ -3977,12 +3977,12 @@ body .ns-effect-loadingcircle { .chat .chat-double { margin-bottom: 0; list-style: none; - padding: 20px 0 20px; + padding: 20px 10px 20px; position: relative; } .chat .chat-double li { - margin-bottom: 20px; + margin-bottom: 2px; position: relative; } @@ -4002,7 +4002,7 @@ body .ns-effect-loadingcircle { -webkit-border-radius: 3px; border-radius: 3px; background: #fff; - padding: 20px; + padding: 8px; position: relative; -webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175); box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175); @@ -4137,7 +4137,7 @@ body .ns-effect-loadingcircle { } .chat .chat-panel { - width: 47% !important; + width: 80% !important; float: right !important; } diff --git a/functions.php b/functions.php index 93fc8ffe5..9440a3818 100755 --- a/functions.php +++ b/functions.php @@ -2,7 +2,7 @@ // =================================== // Define Version - define('INSTALLEDVERSION', '1.344'); + define('INSTALLEDVERSION', '1.35'); // =================================== // Debugging output functions diff --git a/homepage.php b/homepage.php index 8d28a8193..5852b5446 100755 --- a/homepage.php +++ b/homepage.php @@ -102,6 +102,7 @@ + @@ -233,6 +234,142 @@ + + + + + + + + +
    +
    +
    +

    Run Speed Test

    +
    +
    +
    +
    +
    2 diff --git a/lang/de.ini b/lang/de.ini index 55e94a154..8e36c205e 100644 --- a/lang/de.ini +++ b/lang/de.ini @@ -250,4 +250,5 @@ REMOVE = "Remove" GIT_BRANCH = "Github branch to use when force installing (Leave this alone unless you are beta testing)" GIT_CHECK = "Check for new 'master' releases" GIT_FORCE = "Force Install Branch" -GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." \ No newline at end of file +GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." +SPEED_TEST = "Speed Test" \ No newline at end of file diff --git a/lang/en.ini b/lang/en.ini index b27ad5a12..939c0155a 100644 --- a/lang/en.ini +++ b/lang/en.ini @@ -95,7 +95,7 @@ APPLY_RELOAD = "Apply Changes To Reload The Page!" OK = "OK" COLORS_SAVED = "Colors Saved!" NEW_VERSION = "New Version Available" -CLICK_INFO = "Click Info Tab" +CLICK_INFO = "Click About Tab" WHATS_NEW = "What's New in" CHANGES = "Changes" AUTO_UPGRADE = "Auto Upgrade" @@ -250,4 +250,5 @@ REMOVE = "Remove" GIT_BRANCH = "Github branch to use when force installing (Leave this alone unless you are beta testing)" GIT_CHECK = "Check for new 'master' releases" GIT_FORCE = "Force Install Branch" -GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." \ No newline at end of file +GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." +SPEED_TEST = "Speed Test" \ No newline at end of file diff --git a/lang/es.ini b/lang/es.ini index 754257755..bf1765222 100644 --- a/lang/es.ini +++ b/lang/es.ini @@ -250,4 +250,5 @@ REMOVE = "Remove" GIT_BRANCH = "Github branch to use when force installing (Leave this alone unless you are beta testing)" GIT_CHECK = "Check for new 'master' releases" GIT_FORCE = "Force Install Branch" -GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." \ No newline at end of file +GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." +SPEED_TEST = "Speed Test" \ No newline at end of file diff --git a/lang/fr.ini b/lang/fr.ini index b489b8d2b..3718e23ba 100644 --- a/lang/fr.ini +++ b/lang/fr.ini @@ -250,4 +250,5 @@ REMOVE = "Remove" GIT_BRANCH = "Github branch to use when force installing (Leave this alone unless you are beta testing)" GIT_CHECK = "Check for new 'master' releases" GIT_FORCE = "Force Install Branch" -GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." \ No newline at end of file +GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." +SPEED_TEST = "Speed Test" \ No newline at end of file diff --git a/lang/it.ini b/lang/it.ini index 3aaeb1a45..b95e73eaa 100644 --- a/lang/it.ini +++ b/lang/it.ini @@ -250,4 +250,5 @@ REMOVE = "Remove" GIT_BRANCH = "Github branch to use when force installing (Leave this alone unless you are beta testing)" GIT_CHECK = "Check for new 'master' releases" GIT_FORCE = "Force Install Branch" -GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." \ No newline at end of file +GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." +SPEED_TEST = "Speed Test" \ No newline at end of file diff --git a/lang/nl.ini b/lang/nl.ini index ad0678201..60820fa5d 100644 --- a/lang/nl.ini +++ b/lang/nl.ini @@ -250,4 +250,5 @@ REMOVE = "Remove" GIT_BRANCH = "Github branch to use when force installing (Leave this alone unless you are beta testing)" GIT_CHECK = "Check for new 'master' releases" GIT_FORCE = "Force Install Branch" -GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." \ No newline at end of file +GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." +SPEED_TEST = "Speed Test" \ No newline at end of file diff --git a/lang/pl.ini b/lang/pl.ini index f7a67a997..8fa51d51d 100644 --- a/lang/pl.ini +++ b/lang/pl.ini @@ -250,4 +250,5 @@ REMOVE = "Remove" GIT_BRANCH = "Github branch to use when force installing (Leave this alone unless you are beta testing)" GIT_CHECK = "Check for new 'master' releases" GIT_FORCE = "Force Install Branch" -GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." \ No newline at end of file +GIT_FORCE_CONFIRM = "Are you sure you want to install this branch? Going from a newer version to an older verison is not recommended or supported." +SPEED_TEST = "Speed Test" \ No newline at end of file diff --git a/settings.php b/settings.php index 87de85924..1c5c19a22 100755 --- a/settings.php +++ b/settings.php @@ -619,6 +619,12 @@ function submitTabs(form) { 'value' => HOMEPAGEAUTHNEEDED, 'options' => $userTypes, ), + array( + 'type' => 'checkbox', + 'labelTranslate' => 'SPEED_TEST', + 'name' => 'speedTest', + 'value' => SPEEDTEST, + ), /* array( 'type' => 'custom',