diff --git a/interface/resources/qml/ConnectionFailureDialog.qml b/interface/resources/qml/ConnectionFailureDialog.qml new file mode 100644 index 0000000000..0d5bdfd38d --- /dev/null +++ b/interface/resources/qml/ConnectionFailureDialog.qml @@ -0,0 +1,14 @@ +import QtQuick.Dialogs 1.2 as OriginalDialogs + +import "dialogs" + +MessageDialog { + id: root + objectName: "ConnectionFailureDialog" + + title: "No Connection" + text: "Unable to connect to this domain. Click the 'GO TO' button on the toolbar to visit another domain." + buttons: OriginalDialogs.StandardButton.Ok + icon: OriginalDialogs.StandardIcon.Warning + defaultButton: OriginalDialogs.StandardButton.NoButton; +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9653fb29ce..0351df0bc8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -882,8 +882,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo UserActivityLogger::getInstance().logAction("launch", properties); - _connectionMonitor.init(); - // Tell our entity edit sender about our known jurisdictions _entityEditSender.setServerJurisdictions(&_entityServerJurisdictions); _entityEditSender.setMyAvatar(myAvatar.get()); @@ -1376,6 +1374,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } } + _connectionMonitor.init(); + // After all of the constructor is completed, then set firstRun to false. firstRun.set(false); } @@ -2165,13 +2165,10 @@ void Application::resizeGL() { auto offscreenUi = DependencyManager::get(); auto uiSize = displayPlugin->getRecommendedUiSize(); // Bit of a hack since there's no device pixel ratio change event I can find. - static qreal lastDevicePixelRatio = 0; - qreal devicePixelRatio = _window->devicePixelRatio(); - if (offscreenUi->size() != fromGlm(uiSize) || devicePixelRatio != lastDevicePixelRatio) { + if (offscreenUi->size() != fromGlm(uiSize)) { qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize; offscreenUi->resize(fromGlm(uiSize), true); _offscreenContext->makeCurrent(); - lastDevicePixelRatio = devicePixelRatio; } } diff --git a/interface/src/ConnectionMonitor.cpp b/interface/src/ConnectionMonitor.cpp index 4061209127..fcb1908994 100644 --- a/interface/src/ConnectionMonitor.cpp +++ b/interface/src/ConnectionMonitor.cpp @@ -13,34 +13,42 @@ #include "ui/DialogsManager.h" -#include #include #include -#include +#include +// Because the connection monitor is created at startup, the time we wait on initial load +// should be longer to allow the application to initialize. +static const int ON_INITIAL_LOAD_DISPLAY_AFTER_DISCONNECTED_FOR_X_MS = 10000; static const int DISPLAY_AFTER_DISCONNECTED_FOR_X_MS = 5000; void ConnectionMonitor::init() { // Connect to domain disconnected message auto nodeList = DependencyManager::get(); const DomainHandler& domainHandler = nodeList->getDomainHandler(); - connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &ConnectionMonitor::disconnectedFromDomain); - connect(&domainHandler, &DomainHandler::connectedToDomain, this, &ConnectionMonitor::connectedToDomain); + connect(&domainHandler, &DomainHandler::resetting, this, &ConnectionMonitor::startTimer); + connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &ConnectionMonitor::startTimer); + connect(&domainHandler, &DomainHandler::connectedToDomain, this, &ConnectionMonitor::stopTimer); + connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &ConnectionMonitor::stopTimer); _timer.setSingleShot(true); - _timer.setInterval(DISPLAY_AFTER_DISCONNECTED_FOR_X_MS); if (!domainHandler.isConnected()) { - _timer.start(); + _timer.start(ON_INITIAL_LOAD_DISPLAY_AFTER_DISCONNECTED_FOR_X_MS); } - auto dialogsManager = DependencyManager::get(); - connect(&_timer, &QTimer::timeout, dialogsManager.data(), &DialogsManager::indicateDomainConnectionFailure); + connect(&_timer, &QTimer::timeout, this, []() { + qDebug() << "ConnectionMonitor: Showing connection failure window"; + DependencyManager::get()->setDomainConnectionFailureVisibility(true); + }); } -void ConnectionMonitor::disconnectedFromDomain() { - _timer.start(); +void ConnectionMonitor::startTimer() { + qDebug() << "ConnectionMonitor: Starting timer"; + _timer.start(DISPLAY_AFTER_DISCONNECTED_FOR_X_MS); } -void ConnectionMonitor::connectedToDomain(const QString& name) { +void ConnectionMonitor::stopTimer() { + qDebug() << "ConnectionMonitor: Stopping timer"; _timer.stop(); + DependencyManager::get()->setDomainConnectionFailureVisibility(false); } diff --git a/interface/src/ConnectionMonitor.h b/interface/src/ConnectionMonitor.h index ddd80c4af5..e3d393163b 100644 --- a/interface/src/ConnectionMonitor.h +++ b/interface/src/ConnectionMonitor.h @@ -23,8 +23,8 @@ public: void init(); private slots: - void disconnectedFromDomain(); - void connectedToDomain(const QString& name); + void startTimer(); + void stopTimer(); private: QTimer _timer; diff --git a/interface/src/ui/ConnectionFailureDialog.cpp b/interface/src/ui/ConnectionFailureDialog.cpp new file mode 100644 index 0000000000..560c76629b --- /dev/null +++ b/interface/src/ui/ConnectionFailureDialog.cpp @@ -0,0 +1,3 @@ +#include "ConnectionFailureDialog.h" + +HIFI_QML_DEF(ConnectionFailureDialog) diff --git a/interface/src/ui/ConnectionFailureDialog.h b/interface/src/ui/ConnectionFailureDialog.h new file mode 100644 index 0000000000..94cab7d11d --- /dev/null +++ b/interface/src/ui/ConnectionFailureDialog.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +class ConnectionFailureDialog : public OffscreenQmlDialog { + Q_OBJECT + HIFI_QML_DECL +}; \ No newline at end of file diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 2be4793b92..679fb7f59d 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -21,6 +21,7 @@ #include "AddressBarDialog.h" #include "BandwidthDialog.h" #include "CachesSizeDialog.h" +#include "ConnectionFailureDialog.h" #include "DiskCacheEditor.h" #include "DomainConnectionDialog.h" #include "HMDToolsDialog.h" @@ -59,8 +60,12 @@ void DialogsManager::showFeed() { emit setUseFeed(true); } -void DialogsManager::indicateDomainConnectionFailure() { - OffscreenUi::information("No Connection", "Unable to connect to this domain. Click the 'GO TO' button on the toolbar to visit another domain."); +void DialogsManager::setDomainConnectionFailureVisibility(bool visible) { + if (visible) { + ConnectionFailureDialog::show(); + } else { + ConnectionFailureDialog::hide(); + } } void DialogsManager::toggleDiskCacheEditor() { diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index dfd787bce8..e89bc43020 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -44,7 +44,7 @@ public slots: void toggleAddressBar(); void showAddressBar(); void showFeed(); - void indicateDomainConnectionFailure(); + void setDomainConnectionFailureVisibility(bool visible); void toggleDiskCacheEditor(); void toggleLoginDialog(); void showLoginDialog(); diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index 636ae9ad4f..c82c2b4a32 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -430,26 +430,23 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { rootContext->setContextProperty("resourceDirectoryUrl", QUrl::fromLocalFile(PathUtils::resourcesPath())); } +static uvec2 clampSize(const uvec2& size, uint32_t maxDimension) { + return glm::clamp(size, glm::uvec2(1), glm::uvec2(maxDimension)); +} + +static QSize clampSize(const QSize& qsize, uint32_t maxDimension) { + return fromGlm(clampSize(toGlm(qsize), maxDimension)); +} + void OffscreenQmlSurface::resize(const QSize& newSize_, bool forceResize) { if (!_quickWindow) { return; } - const float MAX_OFFSCREEN_DIMENSION = 4096; - QSize newSize = newSize_; - - if (newSize.width() > MAX_OFFSCREEN_DIMENSION || newSize.height() > MAX_OFFSCREEN_DIMENSION) { - float scale = std::min( - ((float)newSize.width() / MAX_OFFSCREEN_DIMENSION), - ((float)newSize.height() / MAX_OFFSCREEN_DIMENSION)); - newSize = QSize( - std::max(static_cast(scale * newSize.width()), 10), - std::max(static_cast(scale * newSize.height()), 10)); - } - - QSize currentSize = _quickWindow->geometry().size(); - if (newSize == currentSize && !forceResize) { + const uint32_t MAX_OFFSCREEN_DIMENSION = 4096; + const QSize newSize = clampSize(newSize_, MAX_OFFSCREEN_DIMENSION); + if (!forceResize && newSize == _quickWindow->geometry().size()) { return; } @@ -465,17 +462,12 @@ void OffscreenQmlSurface::resize(const QSize& newSize_, bool forceResize) { // Qt bug in 5.4 forces this check of pixel ratio, // even though we're rendering offscreen. - qreal pixelRatio = 1.0; - if (_renderControl && _renderControl->_renderWindow) { - pixelRatio = _renderControl->_renderWindow->devicePixelRatio(); - } - - uvec2 newOffscreenSize = toGlm(newSize * pixelRatio); + uvec2 newOffscreenSize = toGlm(newSize); if (newOffscreenSize == _size) { return; } - qCDebug(glLogging) << "Offscreen UI resizing to " << newSize.width() << "x" << newSize.height() << " with pixel ratio " << pixelRatio; + qCDebug(glLogging) << "Offscreen UI resizing to " << newSize.width() << "x" << newSize.height(); _canvas->makeCurrent(); diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index 90e402f236..ef16e3b53f 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -18,22 +18,6 @@ using namespace gpu::gl; std::shared_ptr GLTexture::_textureTransferHelper; -// FIXME placeholder for texture memory over-use -#define DEFAULT_MAX_MEMORY_MB 256 -#define OVER_MEMORY_PRESSURE 2.0f - -// FIXME other apps show things like Oculus home consuming large amounts of GPU memory -// which causes us to blur textures needlessly (since other app GPU memory usage will likely -// be swapped out and not cause any actual impact -//#define CHECK_MIN_FREE_GPU_MEMORY -#ifdef CHECK_MIN_FREE_GPU_MEMORY -#define MIN_FREE_GPU_MEMORY_PERCENTAGE 0.25f -#endif - -// Allow 65% of all available GPU memory to be consumed by textures -// FIXME overly conservative? -#define MAX_CONSUMED_TEXTURE_MEMORY_PERCENTAGE 0.65f - const GLenum GLTexture::CUBE_FACE_LAYOUT[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, @@ -105,37 +89,25 @@ const std::vector& GLTexture::getFaceTargets(GLenum target) { return faceTargets; } +// Default texture memory = GPU total memory - 2GB +#define GPU_MEMORY_RESERVE_BYTES MB_TO_BYTES(2048) +// Minimum texture memory = 1GB +#define TEXTURE_MEMORY_MIN_BYTES MB_TO_BYTES(1024) + float GLTexture::getMemoryPressure() { // Check for an explicit memory limit auto availableTextureMemory = Texture::getAllowedGPUMemoryUsage(); + // If no memory limit has been set, use a percentage of the total dedicated memory if (!availableTextureMemory) { - auto totalGpuMemory = getDedicatedMemory(); - - if (!totalGpuMemory) { - // If we can't query the dedicated memory just use a fallback fixed value of 256 MB - totalGpuMemory = MB_TO_BYTES(DEFAULT_MAX_MEMORY_MB); + auto totalMemory = getDedicatedMemory(); + if ((GPU_MEMORY_RESERVE_BYTES + TEXTURE_MEMORY_MIN_BYTES) > totalMemory) { + availableTextureMemory = TEXTURE_MEMORY_MIN_BYTES; } else { -#ifdef CHECK_MIN_FREE_GPU_MEMORY - // Check the global free GPU memory - auto freeGpuMemory = getFreeDedicatedMemory(); - if (freeGpuMemory) { - static gpu::Size lastFreeGpuMemory = 0; - auto freePercentage = (float)freeGpuMemory / (float)totalGpuMemory; - if (freeGpuMemory != lastFreeGpuMemory) { - lastFreeGpuMemory = freeGpuMemory; - if (freePercentage < MIN_FREE_GPU_MEMORY_PERCENTAGE) { - qCDebug(gpugllogging) << "Exceeded min free GPU memory " << freePercentage; - return OVER_MEMORY_PRESSURE; - } - } - } -#endif + availableTextureMemory = totalMemory - GPU_MEMORY_RESERVE_BYTES; } - - availableTextureMemory = static_cast(totalGpuMemory * MAX_CONSUMED_TEXTURE_MEMORY_PERCENTAGE); } // Return the consumed texture memory divided by the available texture memory. diff --git a/libraries/ui/src/OffscreenQmlElement.h b/libraries/ui/src/OffscreenQmlElement.h index 87b404a4bd..4e07fcccd9 100644 --- a/libraries/ui/src/OffscreenQmlElement.h +++ b/libraries/ui/src/OffscreenQmlElement.h @@ -22,6 +22,7 @@ private: \ public: \ static void registerType(); \ static void show(std::function f = [](QQmlContext*, QObject*) {}); \ + static void hide(); \ static void toggle(std::function f = [](QQmlContext*, QObject*) {}); \ static void load(std::function f = [](QQmlContext*, QObject*) {}); \ private: @@ -33,6 +34,7 @@ protected: \ public: \ static void registerType(); \ static void show(); \ + static void hide(); \ static void toggle(); \ static void load(); \ private: @@ -50,6 +52,11 @@ private: offscreenUi->show(QML, NAME, f); \ } \ \ + void x::hide() { \ + auto offscreenUi = DependencyManager::get(); \ + offscreenUi->hide(NAME); \ + } \ + \ void x::toggle(std::function f) { \ auto offscreenUi = DependencyManager::get(); \ offscreenUi->toggle(QML, NAME, f); \ @@ -70,6 +77,11 @@ private: auto offscreenUi = DependencyManager::get(); \ offscreenUi->show(QML, NAME, f); \ } \ + void x::hide() { \ + auto offscreenUi = DependencyManager::get(); \ + offscreenUi->hide(NAME); \ + } \ + \ void x::toggle() { \ auto offscreenUi = DependencyManager::get(); \ offscreenUi->toggle(QML, NAME, f); \ diff --git a/server-console/package.json b/server-console/package.json index d97f72609b..f72ffc347f 100644 --- a/server-console/package.json +++ b/server-console/package.json @@ -1,6 +1,6 @@ { - "name": "hf-console", - "description": "High Fidelity Console", + "name": "HighFidelitySandbox", + "description": "High Fidelity Sandbox", "author": "High Fidelity", "license": "Apache-2.0", "version": "1.0.0", @@ -33,6 +33,7 @@ "request": "^2.67.0", "request-progress": "1.0.2", "tar-fs": "^1.12.0", - "yargs": "^3.30.0" + "yargs": "^3.30.0", + "electron-log": "1.1.1" } } diff --git a/server-console/src/main.js b/server-console/src/main.js index 72f4520020..12fc9702c9 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -64,7 +64,6 @@ function getBuildInfo() { var buildInfo = DEFAULT_BUILD_INFO; if (buildInfoPath) { - console.log('Build info path:', buildInfoPath); try { buildInfo = JSON.parse(fs.readFileSync(buildInfoPath)); } catch (e) { @@ -74,11 +73,8 @@ function getBuildInfo() { return buildInfo; } - const buildInfo = getBuildInfo(); -console.log("build info", buildInfo); - function getRootHifiDataDirectory() { var organization = "High Fidelity"; if (buildInfo.releaseType != "PRODUCTION") { @@ -105,16 +101,26 @@ function getApplicationDataDirectory() { return path.join(getRootHifiDataDirectory(), '/Server Console'); } -console.log("Root hifi directory is: ", getRootHifiDataDirectory()); +// Configure log +global.log = require('electron-log'); +const logFile = getApplicationDataDirectory() + '/log.txt'; +fs.ensureFileSync(logFile); // Ensure file exists +log.transports.file.maxSize = 5 * 1024 * 1024; +log.transports.file.file = logFile; + +log.debug("build info", buildInfo); +log.debug("Root hifi directory is: ", getRootHifiDataDirectory()); const ipcMain = electron.ipcMain; var isShuttingDown = false; function shutdown() { + log.debug("Normal shutdown (isShuttingDown: " + isShuttingDown + ")"); if (!isShuttingDown) { // if the home server is running, show a prompt before quit to ask if the user is sure if (homeServer.state == ProcessGroupStates.STARTED) { + log.debug("Showing shutdown dialog."); dialog.showMessageBox({ type: 'question', buttons: ['Yes', 'No'], @@ -129,21 +135,26 @@ function shutdown() { } function forcedShutdown() { + log.debug("Forced shutdown (isShuttingDown: " + isShuttingDown + ")"); if (!isShuttingDown) { shutdownCallback(0); } } function shutdownCallback(idx) { + log.debug("Entering shutdown callback."); if (idx == 0 && !isShuttingDown) { isShuttingDown = true; + log.debug("Saving user config"); userConfig.save(configPath); if (logWindow) { + log.debug("Closing log window"); logWindow.close(); } if (homeServer) { + log.debug("Stoping home server"); homeServer.stop(); } @@ -151,14 +162,17 @@ function shutdownCallback(idx) { if (homeServer.state == ProcessGroupStates.STOPPED) { // if the home server is already down, take down the server console now + log.debug("Quitting."); app.quit(); } else { // if the home server is still running, wait until we get a state change or timeout // before quitting the app + log.debug("Server still shutting down. Waiting"); var timeoutID = setTimeout(app.quit, 5000); homeServer.on('state-update', function(processGroup) { if (processGroup.state == ProcessGroupStates.STOPPED) { clearTimeout(timeoutID); + log.debug("Quitting."); app.quit(); } }); @@ -167,36 +181,36 @@ function shutdownCallback(idx) { } function deleteOldFiles(directoryPath, maxAgeInSeconds, filenameRegex) { - console.log("Deleting old log files in " + directoryPath); + log.debug("Deleting old log files in " + directoryPath); var filenames = []; try { filenames = fs.readdirSync(directoryPath); } catch (e) { - console.warn("Error reading contents of log file directory", e); + log.warn("Error reading contents of log file directory", e); return; } for (const filename of filenames) { - console.log("Checking", filename); + log.debug("Checking", filename); const absolutePath = path.join(directoryPath, filename); var stat = null; try { stat = fs.statSync(absolutePath); } catch (e) { - console.log("Error stat'ing file", absolutePath, e); + log.debug("Error stat'ing file", absolutePath, e); continue; } const curTime = Date.now(); if (stat.isFile() && filename.search(filenameRegex) >= 0) { const ageInSeconds = (curTime - stat.mtime.getTime()) / 1000.0; if (ageInSeconds >= maxAgeInSeconds) { - console.log("\tDeleting:", filename, ageInSeconds); + log.debug("\tDeleting:", filename, ageInSeconds); try { fs.unlinkSync(absolutePath); } catch (e) { if (e.code != 'EBUSY') { - console.warn("\tError deleting:", e); + log.warn("\tError deleting:", e); } } } @@ -206,8 +220,8 @@ function deleteOldFiles(directoryPath, maxAgeInSeconds, filenameRegex) { var logPath = path.join(getApplicationDataDirectory(), '/logs'); -console.log("Log directory:", logPath); -console.log("Data directory:", getRootHifiDataDirectory()); +log.debug("Log directory:", logPath); +log.debug("Data directory:", getRootHifiDataDirectory()); const configPath = path.join(getApplicationDataDirectory(), 'config.json'); var userConfig = new Config(); @@ -215,8 +229,8 @@ userConfig.load(configPath); // print out uncaught exceptions in the console process.on('uncaughtException', function(err) { - console.error(err); - console.error(err.stack); + log.error(err); + log.error(err.stack); }); var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { @@ -225,7 +239,7 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) }); if (shouldQuit) { - console.warn("Another instance of the Sandbox is already running - this instance will quit."); + log.warn("Another instance of the Sandbox is already running - this instance will quit."); app.quit(); return; } @@ -506,7 +520,7 @@ const httpStatusPort = 60332; function backupResourceDirectories(folder) { try { fs.mkdirSync(folder); - console.log("Created directory " + folder); + log.debug("Created directory " + folder); var dsBackup = path.join(folder, '/domain-server'); var acBackup = path.join(folder, '/assignment-client'); @@ -519,7 +533,7 @@ function backupResourceDirectories(folder) { return true; } catch (e) { - console.log(e); + log.debug(e); return false; } } @@ -541,7 +555,7 @@ function openBackupInstructions(folder) { window.setSize(obj.width, obj.height); }); electron.ipcMain.on('ready', function() { - console.log("got ready"); + log.debug("got ready"); window.webContents.send('update', folder); }); } @@ -575,9 +589,9 @@ function checkNewContent() { var wantDebug = false; if (wantDebug) { - console.log('Last Modified: ' + response.headers['last-modified']); - console.log(localContent + " " + remoteContent + " " + shouldUpdate + " " + new Date()); - console.log("Remote content is " + (shouldUpdate ? "newer" : "older") + " that local content."); + log.debug('Last Modified: ' + response.headers['last-modified']); + log.debug(localContent + " " + remoteContent + " " + shouldUpdate + " " + new Date()); + log.debug("Remote content is " + (shouldUpdate ? "newer" : "older") + " that local content."); } if (shouldUpdate) { @@ -619,46 +633,46 @@ function maybeInstallDefaultContentSet(onComplete) { // Check for existing data const acResourceDirectory = getAssignmentClientResourcesDirectory(); - console.log("Checking for existence of " + acResourceDirectory); + log.debug("Checking for existence of " + acResourceDirectory); var userHasExistingACData = true; try { fs.accessSync(acResourceDirectory); - console.log("Found directory " + acResourceDirectory); + log.debug("Found directory " + acResourceDirectory); } catch (e) { - console.log(e); + log.debug(e); userHasExistingACData = false; } const dsResourceDirectory = getDomainServerClientResourcesDirectory(); - console.log("checking for existence of " + dsResourceDirectory); + log.debug("checking for existence of " + dsResourceDirectory); var userHasExistingDSData = true; try { fs.accessSync(dsResourceDirectory); - console.log("Found directory " + dsResourceDirectory); + log.debug("Found directory " + dsResourceDirectory); } catch (e) { - console.log(e); + log.debug(e); userHasExistingDSData = false; } if (userHasExistingACData || userHasExistingDSData) { - console.log("User has existing data, suppressing downloader"); + log.debug("User has existing data, suppressing downloader"); onComplete(); checkNewContent(); return; } - console.log("Found contentPath:" + argv.contentPath); + log.debug("Found contentPath:" + argv.contentPath); if (argv.contentPath) { fs.copy(argv.contentPath, getRootHifiDataDirectory(), function (err) { if (err) { - console.log('Could not copy home content: ' + err); - return console.error(err) + log.debug('Could not copy home content: ' + err); + return log.error(err) } - console.log('Copied home content over to: ' + getRootHifiDataDirectory()); + log.debug('Copied home content over to: ' + getRootHifiDataDirectory()); userConfig.set('homeContentLastModified', new Date()); onComplete(); }); @@ -685,11 +699,11 @@ function maybeInstallDefaultContentSet(onComplete) { window.on('closed', onComplete); electron.ipcMain.on('ready', function() { - console.log("got ready"); + log.debug("got ready"); var currentState = ''; function sendStateUpdate(state, args) { - // console.log(state, window, args); + // log.debug(state, window, args); window.webContents.send('update', { state: state, args: args }); currentState = state; } @@ -723,10 +737,10 @@ function maybeInstallDefaultContentSet(onComplete) { }); function extractError(err) { - console.log("Aborting request because gunzip/untar failed"); + log.debug("Aborting request because gunzip/untar failed"); aborted = true; req.abort(); - console.log("ERROR" + err); + log.debug("ERROR" + err); sendStateUpdate('error', { message: "Error installing resources." @@ -738,7 +752,7 @@ function maybeInstallDefaultContentSet(onComplete) { req.pipe(gunzip).pipe(tar.extract(getRootHifiDataDirectory())).on('error', extractError).on('finish', function(){ // response and decompression complete, return - console.log("Finished unarchiving home content set"); + log.debug("Finished unarchiving home content set"); userConfig.set('homeContentLastModified', new Date()); sendStateUpdate('complete'); }); @@ -824,7 +838,7 @@ function onContentLoaded() { } }); notifier.on('click', function(notifierObject, options) { - console.log("Got click", options.url); + log.debug("Got click", options.url); shell.openExternal(options.url); }); } @@ -855,7 +869,7 @@ function onContentLoaded() { // shutting down. The interface app will regularly update a running state file which we will check. // If the file doesn't exist or stops updating for a significant amount of time, we will shut down. if (argv.shutdownWatcher) { - console.log("Shutdown watcher requested... argv.shutdownWatcher:", argv.shutdownWatcher); + log.debug("Shutdown watcher requested... argv.shutdownWatcher:", argv.shutdownWatcher); var MAX_TIME_SINCE_EDIT = 5000; // 5 seconds between updates var firstAttemptToCheck = new Date().getTime(); var shutdownWatchInterval = setInterval(function(){ @@ -863,14 +877,14 @@ function onContentLoaded() { if (err) { var sinceFirstCheck = new Date().getTime() - firstAttemptToCheck; if (sinceFirstCheck > MAX_TIME_SINCE_EDIT) { - console.log("Running state file is missing, assume interface has shutdown... shutting down snadbox."); + log.debug("Running state file is missing, assume interface has shutdown... shutting down snadbox."); forcedShutdown(); clearTimeout(shutdownWatchInterval); } } else { var sinceEdit = new Date().getTime() - stats.mtime.getTime(); if (sinceEdit > MAX_TIME_SINCE_EDIT) { - console.log("Running state of interface hasn't updated in MAX time... shutting down."); + log.debug("Running state of interface hasn't updated in MAX time... shutting down."); forcedShutdown(); clearTimeout(shutdownWatchInterval); } diff --git a/server-console/src/modules/config.js b/server-console/src/modules/config.js index df44dcfafe..438c377154 100644 --- a/server-console/src/modules/config.js +++ b/server-console/src/modules/config.js @@ -10,7 +10,7 @@ Config.prototype = { try { rawData = fs.readFileSync(filePath); } catch(e) { - console.log("Config file not found"); + log.debug("Config file not found"); } var configData = {}; @@ -21,7 +21,7 @@ Config.prototype = { configData = {}; } } catch(e) { - console.error("Error parsing config file", filePath) + log.error("Error parsing config file", filePath) } this.data = {}; @@ -37,7 +37,7 @@ Config.prototype = { return defaultValue; }, set: function(key, value) { - console.log("Setting", key, "to", value); + log.debug("Setting", key, "to", value); this.data[key] = value; } }; diff --git a/server-console/src/modules/hf-process.js b/server-console/src/modules/hf-process.js old mode 100755 new mode 100644 index ce20e385f3..20b8966148 --- a/server-console/src/modules/hf-process.js +++ b/server-console/src/modules/hf-process.js @@ -43,7 +43,7 @@ ProcessGroup.prototype = extend(ProcessGroup.prototype, { }, start: function() { if (this.state != ProcessGroupStates.STOPPED) { - console.warn("Can't start process group that is not stopped."); + log.warn("Can't start process group that is not stopped."); return; } @@ -56,7 +56,7 @@ ProcessGroup.prototype = extend(ProcessGroup.prototype, { }, stop: function() { if (this.state != ProcessGroupStates.STARTED) { - console.warn("Can't stop process group that is not started."); + log.warn("Can't stop process group that is not started."); return; } for (let process of this.processes) { @@ -120,10 +120,10 @@ util.inherits(Process, events.EventEmitter); Process.prototype = extend(Process.prototype, { start: function() { if (this.state != ProcessStates.STOPPED) { - console.warn("Can't start process that is not stopped."); + log.warn("Can't start process that is not stopped."); return; } - console.log("Starting " + this.command + " " + this.commandArgs.join(' ')); + log.debug("Starting " + this.command + " " + this.commandArgs.join(' ')); var logStdout = 'ignore', logStderr = 'ignore'; @@ -138,7 +138,7 @@ Process.prototype = extend(Process.prototype, { if (e.code == 'EEXIST') { logDirectoryCreated = true; } else { - console.error("Error creating log directory"); + log.error("Error creating log directory"); } } @@ -151,13 +151,13 @@ Process.prototype = extend(Process.prototype, { try { logStdout = fs.openSync(tmpLogStdout, 'ax'); } catch(e) { - console.log("Error creating stdout log file", e); + log.debug("Error creating stdout log file", e); logStdout = 'ignore'; } try { logStderr = fs.openSync(tmpLogStderr, 'ax'); } catch(e) { - console.log("Error creating stderr log file", e); + log.debug("Error creating stderr log file", e); logStderr = 'ignore'; } } @@ -169,7 +169,7 @@ Process.prototype = extend(Process.prototype, { stdio: ['ignore', logStdout, logStderr] }); } catch (e) { - console.log("Got error starting child process for " + this.name, e); + log.debug("Got error starting child process for " + this.name, e); this.child = null; this.updateState(ProcessStates.STOPPED); return; @@ -179,7 +179,7 @@ Process.prototype = extend(Process.prototype, { var pidLogStdout = path.resolve(this.logDirectory + '/' + this.name + "-" + this.child.pid + "-" + time + "-stdout.txt"); fs.rename(tmpLogStdout, pidLogStdout, function(e) { if (e !== null) { - console.log("Error renaming log file from " + tmpLogStdout + " to " + pidLogStdout, e); + log.debug("Error renaming log file from " + tmpLogStdout + " to " + pidLogStdout, e); } }); this.logStdout = pidLogStdout; @@ -190,7 +190,7 @@ Process.prototype = extend(Process.prototype, { var pidLogStderr = path.resolve(this.logDirectory + '/' + this.name + "-" + this.child.pid + "-" + time + "-stderr.txt"); fs.rename(tmpLogStderr, pidLogStderr, function(e) { if (e !== null) { - console.log("Error renaming log file from " + tmpLogStdout + " to " + pidLogStdout, e); + log.debug("Error renaming log file from " + tmpLogStdout + " to " + pidLogStdout, e); } }); this.logStderr = pidLogStderr; @@ -201,13 +201,13 @@ Process.prototype = extend(Process.prototype, { this.child.on('error', this.onChildStartError.bind(this)); this.child.on('close', this.onChildClose.bind(this)); - console.log("Child process started"); + log.debug("Child process started"); this.updateState(ProcessStates.STARTED); this.emit('logs-updated'); }, stop: function(force) { if (this.state == ProcessStates.STOPPED) { - console.warn("Can't stop process that is not started or stopping."); + log.warn("Can't stop process that is not started or stopping."); return; } if (os.type() == "Windows_NT") { @@ -217,7 +217,7 @@ Process.prototype = extend(Process.prototype, { } childProcess.exec(command, {}, function(error) { if (error) { - console.error('Error executing taskkill:', error); + log.error('Error executing taskkill:', error); } }); } else { @@ -225,12 +225,12 @@ Process.prototype = extend(Process.prototype, { this.child.kill(signal); } - console.log("Stopping child process:", this.child.pid, this.name); + log.debug("Stopping child process:", this.child.pid, this.name); if (!force) { this.stoppingTimeoutID = setTimeout(function() { if (this.state == ProcessStates.STOPPING) { - console.log("Force killling", this.name, this.child.pid); + log.debug("Force killling", this.name, this.child.pid); this.stop(true); } }.bind(this), 2500); @@ -257,11 +257,11 @@ Process.prototype = extend(Process.prototype, { // Events onChildStartError: function(error) { - console.log("Child process error ", error); + log.debug("Child process error ", error); this.updateState(ProcessStates.STOPPED); }, onChildClose: function(code) { - console.log("Child process closed with code ", code, this.name); + log.debug("Child process closed with code ", code, this.name); if (this.stoppingTimeoutID) { clearTimeout(this.stoppingTimeoutID); this.stoppingTimeoutID = null; @@ -332,7 +332,7 @@ ACMonitorProcess.prototype = extend(ACMonitorProcess.prototype, { this.pendingRequest = null; if (error) { - console.error('ERROR Getting AC Monitor status', error); + log.error('ERROR Getting AC Monitor status', error); } else { this.childServers = body.servers; } diff --git a/server-console/src/modules/hf-updater.js b/server-console/src/modules/hf-updater.js index 38e409b3a2..489364f655 100644 --- a/server-console/src/modules/hf-updater.js +++ b/server-console/src/modules/hf-updater.js @@ -11,7 +11,7 @@ const BUILDS_URL = 'https://highfidelity.com/builds.xml'; function UpdateChecker(currentVersion, checkForUpdatesEveryXSeconds) { this.currentVersion = currentVersion; - console.log('cur', currentVersion); + log.debug('cur', currentVersion); setInterval(this.checkForUpdates.bind(this), checkForUpdatesEveryXSeconds * 1000); this.checkForUpdates(); @@ -19,10 +19,10 @@ function UpdateChecker(currentVersion, checkForUpdatesEveryXSeconds) { util.inherits(UpdateChecker, events.EventEmitter); UpdateChecker.prototype = extend(UpdateChecker.prototype, { checkForUpdates: function() { - console.log("Checking for updates"); + log.debug("Checking for updates"); request(BUILDS_URL, (error, response, body) => { if (error) { - console.log("Error", error); + log.debug("Error", error); return; } if (response.statusCode == 200) { @@ -30,13 +30,13 @@ UpdateChecker.prototype = extend(UpdateChecker.prototype, { var $ = cheerio.load(body, { xmlMode: true }); const latestBuild = $('project[name="interface"] platform[name="' + platform + '"]').children().first(); const latestVersion = parseInt(latestBuild.find('version').text()); - console.log("Latest version is:", latestVersion, this.currentVersion); + log.debug("Latest version is:", latestVersion, this.currentVersion); if (latestVersion > this.currentVersion) { const url = latestBuild.find('url').text(); this.emit('update-available', latestVersion, url); } } catch (e) { - console.warn("Error when checking for updates", e); + log.warn("Error when checking for updates", e); } } }); diff --git a/server-console/src/modules/path-finder.js b/server-console/src/modules/path-finder.js index d0e4639e4a..5ecd2c74ff 100644 --- a/server-console/src/modules/path-finder.js +++ b/server-console/src/modules/path-finder.js @@ -72,11 +72,11 @@ exports.discoveredPath = function (name, binaryType, releaseType) { var extension = platformExtension(name); if (stats.isFile() || (stats.isDirectory() && extension == ".app")) { - console.log("Found " + name + " at " + testPath); + log.debug("Found " + name + " at " + testPath); return testPath; } } catch (e) { - console.log("Executable with name " + name + " not found at path " + testPath); + log.debug("Executable with name " + name + " not found at path " + testPath); } } diff --git a/unpublishedScripts/DomainContent/Home/portal.js b/unpublishedScripts/DomainContent/Home/portal.js new file mode 100644 index 0000000000..0ea090a6f7 --- /dev/null +++ b/unpublishedScripts/DomainContent/Home/portal.js @@ -0,0 +1,45 @@ +(function(){ + var teleport; + var portalDestination; + + function playSound() { + Audio.playSound(teleport, { volume: 0.40, localOnly: true }); + }; + + this.preload = function(entityID) { + teleport = SoundCache.getSound("atp:/sounds/teleport.raw"); + + var properties = Entities.getEntityProperties(entityID); + portalDestination = properties.userData; + + print("portal.js | The portal destination is " + portalDestination); + } + + this.enterEntity = function(entityID) { + print("portal.js | enterEntity"); + + var properties = Entities.getEntityProperties(entityID); // in case the userData/portalURL has changed + portalDestination = properties.userData; + + print("portal.js | enterEntity() .... The portal destination is " + portalDestination); + + if (portalDestination.length > 0) { + if (portalDestination[0] == '/') { + print("Teleporting to " + portalDestination); + Window.location = portalDestination; + } else { + print("Teleporting to hifi://" + portalDestination); + Window.location = "hifi://" + portalDestination; + } + } else { + location.goToEntry(); // going forward: no data means go to appropriate entry point + } + + }; + + this.leaveEntity = function(entityID) { + print("portal.js | leaveEntity"); + + playSound(); + }; +})