diff --git a/package.json b/package.json index c22b4080..073533cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.4.9-a", + "version": "0.4.9-b", "keywords": [ "Remote Management", "Intel AMT", diff --git a/views/player.handlebars b/views/player.handlebars index 2a3f503d..41b9e70d 100644 --- a/views/player.handlebars +++ b/views/player.handlebars @@ -60,6 +60,8 @@ + + @@ -91,6 +93,7 @@ var recFileEndTime = 0; var recFileMetadata = null; var recFileProtocol = 0; + var recFileIndexBasePtr = null; var agentDesktop = null; var amtDesktop = null; var playing = false; @@ -138,6 +141,22 @@ } } + function readBlockAt(ptr, func) { + var fr = new FileReader(); + fr.onload = function () { + var type = ReadShort(this.result, 0); + var flags = ReadShort(this.result, 2); + var size = ReadInt(this.result, 4); + var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12); + if ((ptr + 16 + size) > recFile.size) { func(-1); } else { + var fr2 = new FileReader(); + fr2.onload = function () { func(type, flags, time, this.result); }; + fr2.readAsBinaryString(recFile.slice(ptr + 16, ptr + 16 + size)); + } + }; + fr.readAsBinaryString(recFile.slice(ptr, ptr + 16)); + } + function readLastBlock(func) { if (recFile.size < 32) { func(-1); } else { var fr = new FileReader(); @@ -181,6 +200,12 @@ else if (p == 101) { p = "Intel® AMT Redirection"; } x += addInfoNoEsc("Protocol", p); } + if (recFileMetadata.indexInterval) { + recFileIndexBasePtr = recFilePtr; + x += addInfoNoEsc("Seeking", format("Indexed every {0} seconds", recFileMetadata.indexInterval)); + QE('SeekBackwardButton', true); + QE('SeekForwardButton', true); + } QV('DeskParent', true); QV('TermParent', false); if (recFileMetadata.protocol == 1) { @@ -235,8 +260,8 @@ } } - function processBlockEx(type, flags, time, data) { - if (playing == false) return; + function processBlockEx(type, flags, time, data, forced) { + if ((playing == false) && (forced !== true)) return; var flagBinary = (flags & 1) != 0, flagUser = (flags & 2) != 0; // Update the clock @@ -298,6 +323,8 @@ QE('PlayButton', false); QE('PauseButton', false); QE('RestartButton', false); + QE('SeekBackwardButton', false); + QE('SeekForwardButton', false); QS('progressbar').width = '0px'; QH('timespan', '00:00:00'); QV('metadatadiv', true); @@ -491,6 +518,42 @@ } } + function seekBackward() { + //console.log('seekBackward'); + seek(5); + } + + function seekForward() { + //console.log('seekForward'); + seek(10); + } + + + var SeekIndex; + var SeekIndexPtr; + function seek(indexNumber) { + //console.log('seek', indexNumber); + if ((recFileMetadata.indexes == null) || (recFileMetadata.indexes[indexNumber] == null)) return null; + restart(); + //pause(); + if (agentDesktop) { agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height); } + SeekIndex = recFileMetadata.indexes[indexNumber]; + SeekIndexPtr = 3; + var ptr = SeekIndex[0]; + var width = SeekIndex[1]; + var height = SeekIndex[2]; + seekFetchNext(); + } + + function seekFetchNext() { + if (SeekIndex[SeekIndexPtr] == null) { return; } + readBlockAt(recFileIndexBasePtr + SeekIndex[SeekIndexPtr], function (type, flags, time, data) { + SeekIndexPtr++; + processBlockEx(type, flags, time, data, true); + seekFetchNext(); + }); + } + // // POPUP DIALOG // diff --git a/webserver.js b/webserver.js index c06d2fa8..5d8766c2 100644 --- a/webserver.js +++ b/webserver.js @@ -2088,7 +2088,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { // Server the player page function handlePlayerRequest(req, res) { const domain = checkUserIpAddress(req, res); - if ((domain == null) || (domain.redirects == null)) { res.sendStatus(404); return; } + if (domain == null) { res.sendStatus(404); return; } parent.debug('web', 'handlePlayerRequest: sending player'); res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });