// // SandboxUtils.cpp // libraries/networking/src // // Created by Brad Hefta-Gaub on 2016-10-15. // Copyright 2016 High Fidelity, Inc. // Copyright 2023 Overte e.V. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "SandboxUtils.h" #include #include #include #include #if !defined(Q_OS_WIN) #include #include #endif #include #include #include #include "NetworkAccessManager.h" #include "NetworkLogging.h" #include "NetworkingConstants.h" namespace SandboxUtils { QNetworkReply* getStatus() { auto& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest sandboxStatus(SANDBOX_STATUS_URL); sandboxStatus.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); sandboxStatus.setHeader(QNetworkRequest::UserAgentHeader, NetworkingConstants::OVERTE_USER_AGENT); return networkAccessManager.get(sandboxStatus); } bool readStatus(QByteArray statusData) { auto statusJson = QJsonDocument::fromJson(statusData); if (!statusJson.isEmpty()) { auto statusObject = statusJson.object(); auto serversValue = statusObject.value("servers"); if (!serversValue.isUndefined() && serversValue.isObject()) { auto serversObject = serversValue.toObject(); auto serversCount = serversObject.size(); const int MINIMUM_EXPECTED_SERVER_COUNT = 5; if (serversCount >= MINIMUM_EXPECTED_SERVER_COUNT) { return true; } } } return false; } void runLocalSandbox(QString contentPath, bool autoShutdown, bool noUpdater) { // use the current behavior on windows to not break anyone's setup #if defined (Q_OS_WIN) QString serverPath = "./server-console/server-console.exe"; qCDebug(networking) << "Server path is: " << serverPath; qCDebug(networking) << "autoShutdown: " << autoShutdown; qCDebug(networking) << "noUpdater: " << noUpdater; bool hasContentPath = !contentPath.isEmpty(); bool passArgs = autoShutdown || hasContentPath || noUpdater; QStringList args; if (passArgs) { args << "--"; } if (hasContentPath) { QString serverContentPath = "./" + contentPath; args << "--contentPath" << serverContentPath; } if (autoShutdown) { auto pid = QCoreApplication::applicationPid(); args << "--shutdownWith" << QString::number(pid); } if (noUpdater) { args << "--noUpdater"; } qCDebug(networking) << "Launching sandbox with:" << args; qCDebug(networking) << QProcess::startDetached(serverPath, args); #else auto myPid = QCoreApplication::applicationPid(); QStringList domainArgs, assignmentArgs; qint64 domainPid = 0, assignmentPid = 0; qCDebug(networking) << "Launching sandbox"; domainArgs << "--parent-pid" << QString::number(myPid); domainArgs << "--get-temp-name"; auto domainSuccess = QProcess::startDetached( "./domain-server/domain-server", domainArgs, QString(), &domainPid ); if (domainSuccess) { qCDebug(networking) << "Sandbox domain-server started"; } else { qCCritical(networking) << "Sandbox domain-server couldn't be started"; // safe to use QMessageBox because SandboxUtils is only used by interface QMessageBox::critical(nullptr, "Sandbox Server Error", "The domain-server executable couldn't be started. Overte will continue running without the sandbox server."); return; } assignmentArgs << "--parent-pid" << QString::number(myPid); assignmentArgs << "-n7"; auto assignmentSuccess = QProcess::startDetached( "./assignment-client/assignment-client", assignmentArgs, QString(), &assignmentPid ); if (assignmentSuccess) { qCDebug(networking) << "Sandbox assignment-client started"; } else { qCCritical(networking) << "Sandbox assignment-client failed to start"; // kill the domain server if we can't start the assignment client if (domainPid) { kill(domainPid, SIGINT); } // safe to use QMessageBox because SandboxUtils is only used by interface QMessageBox::critical(nullptr, "Sandbox Server Error", "The assignment-client executable couldn't be started. Overte will continue running without the sandbox server."); } #endif } }