Merge pull request #1329 from ctrlaltdavid/dev/webapp-master-update

Update webapp branch to recent master
This commit is contained in:
Kalila 2021-09-02 01:11:46 -04:00 committed by GitHub
commit 1eb36d40c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 394 additions and 173 deletions

View file

@ -337,6 +337,13 @@ if (BUILD_GPU_FRAME_PLAYER_ONLY)
add_subdirectory(tools/gpu-frame-player) add_subdirectory(tools/gpu-frame-player)
else() else()
if (SCREENSHARE)
add_subdirectory(screenshare)
endif()
# BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway
add_subdirectory(tools)
# add subdirectories for all targets # add subdirectories for all targets
if (BUILD_SERVER) if (BUILD_SERVER)
add_subdirectory(assignment-client) add_subdirectory(assignment-client)
@ -363,13 +370,6 @@ if (BUILD_CLIENT OR BUILD_SERVER)
add_subdirectory(server-console) add_subdirectory(server-console)
endif() endif()
if (SCREENSHARE)
add_subdirectory(screenshare)
endif()
# BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway
add_subdirectory(tools)
endif() endif()
if (BUILD_TESTS) if (BUILD_TESTS)

View file

@ -73,8 +73,16 @@ Vircadia consists of many projects and codebases with its unifying structure's g
There are many contributors to Vircadia. Code writers, reviewers, testers, documentation writers, modelers, and general supporters of the project are all integral to its development and success towards its goals. Find out how you can [contribute](CONTRIBUTING.md)! There are many contributors to Vircadia. Code writers, reviewers, testers, documentation writers, modelers, and general supporters of the project are all integral to its development and success towards its goals. Find out how you can [contribute](CONTRIBUTING.md)!
### [Supporters](https://github.com/sponsors/digisomni/) ### Support
| [Karol Suprynowicz - 74hc595](https://github.com/ksuprynowicz) | You can support the Vircadia project financially through [GitHub Sponsors](https://github.com/sponsors/digisomni/).
You can also support individual active contributors by visiting each repository, this is the main Vircadia repository's [list of active contributors](https://vircadia.com/contributors-redirector/?redirect=vircadia/vircadia). Click on a contributor's profile to see if they accept donations!
Keep in mind that Vircadia consists of multiple smaller projects that might have different active contributors. This is a [a non-exhaustive list](https://github.com/vircadia).
#### Supporters of the Vircadia Project
| [Karol Suprynowicz - 74hc595](https://github.com/ksuprynowicz) |
| --- | | --- |
| <p align="center">[![ksuprynowicz](https://avatars.githubusercontent.com/u/11568651?s=64&v=4)](https://github.com/ksuprynowicz)</p> | <p align="center">[<img src="https://vircadia.com/wp-content/uploads/2021/07/74hc595_profile_2-1.png" width="80" alt="ksuprynowicz" />](https://github.com/ksuprynowicz)</p>

View file

@ -46,7 +46,8 @@ const long long ASSIGNMENT_REQUEST_INTERVAL_MSECS = 1 * 1000;
AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool,
quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname, quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname,
quint16 assignmentServerPort, quint16 assignmentMonitorPort) : quint16 assignmentServerPort, quint16 assignmentMonitorPort,
bool disableDomainPortAutoDiscovery) :
_assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME)
{ {
LogUtils::init(); LogUtils::init();
@ -91,6 +92,13 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
_assignmentServerSocket.setObjectName("AssignmentServer"); _assignmentServerSocket.setObjectName("AssignmentServer");
nodeList->setAssignmentServerSocket(_assignmentServerSocket); nodeList->setAssignmentServerSocket(_assignmentServerSocket);
if (disableDomainPortAutoDiscovery) {
_disableDomainPortAutoDiscovery = disableDomainPortAutoDiscovery;
qCDebug(assignment_client) << "Disabling domain port auto discovery by the assignment client due to parsed command line parameter.";
}
nodeList->disableDomainPortAutoDiscovery(_disableDomainPortAutoDiscovery);
qCDebug(assignment_client) << "Assignment server socket is" << _assignmentServerSocket; qCDebug(assignment_client) << "Assignment server socket is" << _assignmentServerSocket;
// call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required
@ -179,7 +187,7 @@ void AssignmentClient::setUpStatusToMonitor() {
void AssignmentClient::sendStatusPacketToACM() { void AssignmentClient::sendStatusPacketToACM() {
// tell the assignment client monitor what this assignment client is doing (if anything) // tell the assignment client monitor what this assignment client is doing (if anything)
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
quint8 assignmentType = Assignment::Type::AllTypes; quint8 assignmentType = Assignment::Type::AllTypes;
if (_currentAssignment) { if (_currentAssignment) {
@ -190,7 +198,7 @@ void AssignmentClient::sendStatusPacketToACM() {
statusPacket->write(_childAssignmentUUID.toRfc4122()); statusPacket->write(_childAssignmentUUID.toRfc4122());
statusPacket->writePrimitive(assignmentType); statusPacket->writePrimitive(assignmentType);
nodeList->sendPacket(std::move(statusPacket), _assignmentClientMonitorSocket); nodeList->sendPacket(std::move(statusPacket), _assignmentClientMonitorSocket);
} }
@ -200,7 +208,7 @@ void AssignmentClient::sendAssignmentRequest() {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
if (_assignmentServerHostname == "localhost") { if (_assignmentServerHostname == "localhost" && !_disableDomainPortAutoDiscovery) {
// we want to check again for the local domain-server port in case the DS has restarted // we want to check again for the local domain-server port in case the DS has restarted
quint16 localAssignmentServerPort; quint16 localAssignmentServerPort;
if (nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, localAssignmentServerPort)) { if (nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, localAssignmentServerPort)) {
@ -285,10 +293,10 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer<ReceivedMessa
void AssignmentClient::handleStopNodePacket(QSharedPointer<ReceivedMessage> message) { void AssignmentClient::handleStopNodePacket(QSharedPointer<ReceivedMessage> message) {
const SockAddr& senderSockAddr = message->getSenderSockAddr(); const SockAddr& senderSockAddr = message->getSenderSockAddr();
if (senderSockAddr.getAddress() == QHostAddress::LocalHost || if (senderSockAddr.getAddress() == QHostAddress::LocalHost ||
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {
qCDebug(assignment_client) << "AssignmentClientMonitor at" << senderSockAddr << "requested stop via PacketType::StopNode."; qCDebug(assignment_client) << "AssignmentClientMonitor at" << senderSockAddr << "requested stop via PacketType::StopNode.";
QCoreApplication::quit(); QCoreApplication::quit();
} else { } else {
@ -322,7 +330,7 @@ void AssignmentClient::handleAuthenticationRequest() {
void AssignmentClient::assignmentCompleted() { void AssignmentClient::assignmentCompleted() {
crash::annotations::setShutdownState(true); crash::annotations::setShutdownState(true);
// we expect that to be here the previous assignment has completely cleaned up // we expect that to be here the previous assignment has completely cleaned up
assert(_currentAssignment.isNull()); assert(_currentAssignment.isNull());
@ -343,7 +351,7 @@ void AssignmentClient::assignmentCompleted() {
nodeList->setOwnerType(NodeType::Unassigned); nodeList->setOwnerType(NodeType::Unassigned);
nodeList->reset("Assignment completed"); nodeList->reset("Assignment completed");
nodeList->resetNodeInterestSet(); nodeList->resetNodeInterestSet();
_isAssigned = false; _isAssigned = false;
} }

View file

@ -26,9 +26,9 @@ class AssignmentClient : public QObject {
Q_OBJECT Q_OBJECT
public: public:
AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool,
quint16 listenPort, quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname,
QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort, quint16 assignmentServerPort, quint16 assignmentMonitorPort,
quint16 assignmentMonitorPort); bool disableDomainPortAutoDiscovery);
~AssignmentClient(); ~AssignmentClient();
public slots: public slots:
@ -63,6 +63,7 @@ private:
QTimer _requestTimer; // timer for requesting and assignment QTimer _requestTimer; // timer for requesting and assignment
QTimer _statsTimerACM; // timer for sending stats to assignment client monitor QTimer _statsTimerACM; // timer for sending stats to assignment client monitor
QUuid _childAssignmentUUID = QUuid::createUuid(); QUuid _childAssignmentUUID = QUuid::createUuid();
bool _disableDomainPortAutoDiscovery { false };
protected: protected:
SockAddr _assignmentClientMonitorSocket; SockAddr _assignmentClientMonitorSocket;

View file

@ -4,6 +4,7 @@
// //
// Created by Seth Alves on 2/19/15. // Created by Seth Alves on 2/19/15.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -44,7 +45,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
// parse command-line // parse command-line
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription("High Fidelity Assignment Client"); parser.setApplicationDescription("Vircadia Assignment Client");
const QCommandLineOption helpOption = parser.addHelpOption(); const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption(); const QCommandLineOption versionOption = parser.addVersionOption();
@ -54,8 +55,8 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
type = static_cast<Assignment::Type>(static_cast<int>(type) + 1)) { type = static_cast<Assignment::Type>(static_cast<int>(type) + 1)) {
typeDescription.append(QStringLiteral("\n%1 | %2").arg(QString::number(type), Assignment::typeToString(type))); typeDescription.append(QStringLiteral("\n%1 | %2").arg(QString::number(type), Assignment::typeToString(type)));
} }
const QCommandLineOption clientTypeOption(ASSIGNMENT_TYPE_OVERRIDE_OPTION, typeDescription, "type");
const QCommandLineOption clientTypeOption(ASSIGNMENT_TYPE_OVERRIDE_OPTION, typeDescription, "type");
parser.addOption(clientTypeOption); parser.addOption(clientTypeOption);
const QCommandLineOption poolOption(ASSIGNMENT_POOL_OPTION, "set assignment pool", "pool-name"); const QCommandLineOption poolOption(ASSIGNMENT_POOL_OPTION, "set assignment pool", "pool-name");
@ -99,6 +100,10 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
const QCommandLineOption logDirectoryOption(ASSIGNMENT_LOG_DIRECTORY, "directory to store logs", "log-directory"); const QCommandLineOption logDirectoryOption(ASSIGNMENT_LOG_DIRECTORY, "directory to store logs", "log-directory");
parser.addOption(logDirectoryOption); parser.addOption(logDirectoryOption);
const QCommandLineOption disableDomainPortAutoDiscoveryOption(ASSIGNMENT_DISABLE_DOMAIN_AUTO_PORT_DISCOVERY,
"assignment clients automatically search for the domain server on the local machine, if networking is being managed, then disable automatic discovery of the domain server port");
parser.addOption(disableDomainPortAutoDiscoveryOption);
const QCommandLineOption parentPIDOption(PARENT_PID_OPTION, "PID of the parent process", "parent-pid"); const QCommandLineOption parentPIDOption(PARENT_PID_OPTION, "PID of the parent process", "parent-pid");
parser.addOption(parentPIDOption); parser.addOption(parentPIDOption);
@ -151,11 +156,14 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
} }
QString logDirectory; QString logDirectory;
if (parser.isSet(logDirectoryOption)) { if (parser.isSet(logDirectoryOption)) {
logDirectory = parser.value(logDirectoryOption); logDirectory = parser.value(logDirectoryOption);
} }
bool disableDomainPortAutoDiscovery = false;
if (parser.isSet(disableDomainPortAutoDiscoveryOption)) {
disableDomainPortAutoDiscovery = true;
}
Assignment::Type requestAssignmentType = Assignment::AllTypes; Assignment::Type requestAssignmentType = Assignment::AllTypes;
if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) { if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) {
@ -250,13 +258,15 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
AssignmentClientMonitor* monitor = new AssignmentClientMonitor(numForks, minForks, maxForks, AssignmentClientMonitor* monitor = new AssignmentClientMonitor(numForks, minForks, maxForks,
requestAssignmentType, assignmentPool, listenPort, requestAssignmentType, assignmentPool, listenPort,
childMinListenPort, walletUUID, assignmentServerHostname, childMinListenPort, walletUUID, assignmentServerHostname,
assignmentServerPort, httpStatusPort, logDirectory); assignmentServerPort, httpStatusPort, logDirectory,
disableDomainPortAutoDiscovery);
monitor->setParent(this); monitor->setParent(this);
connect(this, &QCoreApplication::aboutToQuit, monitor, &AssignmentClientMonitor::aboutToQuit); connect(this, &QCoreApplication::aboutToQuit, monitor, &AssignmentClientMonitor::aboutToQuit);
} else { } else {
AssignmentClient* client = new AssignmentClient(requestAssignmentType, assignmentPool, listenPort, AssignmentClient* client = new AssignmentClient(requestAssignmentType, assignmentPool, listenPort,
walletUUID, assignmentServerHostname, walletUUID, assignmentServerHostname,
assignmentServerPort, monitorPort); assignmentServerPort, monitorPort,
disableDomainPortAutoDiscovery);
client->setParent(this); client->setParent(this);
connect(this, &QCoreApplication::aboutToQuit, client, &AssignmentClient::aboutToQuit); connect(this, &QCoreApplication::aboutToQuit, client, &AssignmentClient::aboutToQuit);
} }

View file

@ -4,6 +4,7 @@
// //
// Created by Seth Alves on 2/19/15. // Created by Seth Alves on 2/19/15.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -28,6 +29,7 @@ const QString ASSIGNMENT_MAX_FORKS_OPTION = "max";
const QString ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION = "monitor-port"; const QString ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION = "monitor-port";
const QString ASSIGNMENT_HTTP_STATUS_PORT = "http-status-port"; const QString ASSIGNMENT_HTTP_STATUS_PORT = "http-status-port";
const QString ASSIGNMENT_LOG_DIRECTORY = "log-directory"; const QString ASSIGNMENT_LOG_DIRECTORY = "log-directory";
const QString ASSIGNMENT_DISABLE_DOMAIN_AUTO_PORT_DISCOVERY = "disable-domain-port-auto-discovery";
class AssignmentClientApp : public QCoreApplication { class AssignmentClientApp : public QCoreApplication {
Q_OBJECT Q_OBJECT

View file

@ -42,7 +42,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
const unsigned int maxAssignmentClientForks, const unsigned int maxAssignmentClientForks,
Assignment::Type requestAssignmentType, QString assignmentPool, Assignment::Type requestAssignmentType, QString assignmentPool,
quint16 listenPort, quint16 childMinListenPort, QUuid walletUUID, QString assignmentServerHostname, quint16 listenPort, quint16 childMinListenPort, QUuid walletUUID, QString assignmentServerHostname,
quint16 assignmentServerPort, quint16 httpStatusServerPort, QString logDirectory) : quint16 assignmentServerPort, quint16 httpStatusServerPort, QString logDirectory,
bool disableDomainPortAutoDiscovery) :
_httpManager(QHostAddress::LocalHost, httpStatusServerPort, "", this), _httpManager(QHostAddress::LocalHost, httpStatusServerPort, "", this),
_numAssignmentClientForks(numAssignmentClientForks), _numAssignmentClientForks(numAssignmentClientForks),
_minAssignmentClientForks(minAssignmentClientForks), _minAssignmentClientForks(minAssignmentClientForks),
@ -52,7 +53,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
_walletUUID(walletUUID), _walletUUID(walletUUID),
_assignmentServerHostname(assignmentServerHostname), _assignmentServerHostname(assignmentServerHostname),
_assignmentServerPort(assignmentServerPort), _assignmentServerPort(assignmentServerPort),
_childMinListenPort(childMinListenPort) _childMinListenPort(childMinListenPort),
_disableDomainPortAutoDiscovery(disableDomainPortAutoDiscovery)
{ {
qDebug() << "_requestAssignmentType =" << _requestAssignmentType; qDebug() << "_requestAssignmentType =" << _requestAssignmentType;
@ -199,6 +201,9 @@ void AssignmentClientMonitor::spawnChildClient() {
_childArguments.append("--" + ASSIGNMENT_TYPE_OVERRIDE_OPTION); _childArguments.append("--" + ASSIGNMENT_TYPE_OVERRIDE_OPTION);
_childArguments.append(QString::number(_requestAssignmentType)); _childArguments.append(QString::number(_requestAssignmentType));
} }
if (_disableDomainPortAutoDiscovery) {
_childArguments.append("--" + ASSIGNMENT_DISABLE_DOMAIN_AUTO_PORT_DISCOVERY);
}
if (listenPort) { if (listenPort) {
_childArguments.append("-" + ASSIGNMENT_CLIENT_LISTEN_PORT_OPTION); _childArguments.append("-" + ASSIGNMENT_CLIENT_LISTEN_PORT_OPTION);
@ -267,7 +272,7 @@ void AssignmentClientMonitor::spawnChildClient() {
stderrPath = stderrPathTemp; stderrPath = stderrPathTemp;
stderrFilename = stderrFilenameTemp; stderrFilename = stderrFilenameTemp;
} }
qDebug() << "Child stdout being written to: " << stdoutFilename; qDebug() << "Child stdout being written to: " << stdoutFilename;
qDebug() << "Child stderr being written to: " << stderrFilename; qDebug() << "Child stderr being written to: " << stderrFilename;
} }

View file

@ -4,6 +4,7 @@
// //
// Created by Stephen Birarda on 1/10/2014. // Created by Stephen Birarda on 1/10/2014.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -27,7 +28,7 @@
extern const char* NUM_FORKS_PARAMETER; extern const char* NUM_FORKS_PARAMETER;
struct ACProcess { struct ACProcess {
QProcess* process; // looks like a dangling pointer, but is parented by the AssignmentClientMonitor QProcess* process; // looks like a dangling pointer, but is parented by the AssignmentClientMonitor
QString logStdoutPath; QString logStdoutPath;
QString logStderrPath; QString logStderrPath;
}; };
@ -39,7 +40,7 @@ public:
const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType, const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType,
QString assignmentPool, quint16 listenPort, quint16 childMinListenPort, QUuid walletUUID, QString assignmentPool, quint16 listenPort, quint16 childMinListenPort, QUuid walletUUID,
QString assignmentServerHostname, quint16 assignmentServerPort, quint16 httpStatusServerPort, QString assignmentServerHostname, quint16 assignmentServerPort, quint16 httpStatusServerPort,
QString logDirectory); QString logDirectory, bool disableDomainPortAutoDiscovery);
~AssignmentClientMonitor(); ~AssignmentClientMonitor();
void stopChildProcesses(); void stopChildProcesses();
@ -80,6 +81,7 @@ private:
QSet<quint16> _childListenPorts; QSet<quint16> _childListenPorts;
bool _wantsChildFileLogging { false }; bool _wantsChildFileLogging { false };
bool _disableDomainPortAutoDiscovery { false };
}; };
#endif // hifi_AssignmentClientMonitor_h #endif // hifi_AssignmentClientMonitor_h

View file

@ -196,7 +196,7 @@ endif()
print("https://github.com/vircadia/vircadia/tree/master/tools/qt-builder") print("https://github.com/vircadia/vircadia/tree/master/tools/qt-builder")
print("") print("")
print("Alternatively, you can try building against the system Qt by setting the VIRCADIA_USE_SYSTEM_QT environment variable.") print("Alternatively, you can try building against the system Qt by setting the VIRCADIA_USE_SYSTEM_QT environment variable.")
print("You'll need to install the development packages, and to have Qt 5.15.0 or newer. ") print("You'll need to install the development packages, and to have Qt 5.15.0 or later.")
def writeConfig(self): def writeConfig(self):
print("Writing cmake config to {}".format(self.configFilePath)) print("Writing cmake config to {}".format(self.configFilePath))

View file

@ -19,35 +19,35 @@ endfunction()
set(CUSTOM_INTERFACE_QRC_PATHS "") set(CUSTOM_INTERFACE_QRC_PATHS "")
find_npm() find_package(
Qt5 COMPONENTS
Gui Widgets Multimedia Network Qml Quick Script Svg
${PLATFORM_QT_COMPONENTS}
WebChannel WebSockets
)
if (BUILD_TOOLS AND NPM_EXECUTABLE)
add_custom_qrc_path(CUSTOM_INTERFACE_QRC_PATHS "${CMAKE_SOURCE_DIR}/tools/jsdoc/out/hifiJSDoc.json" "auto-complete/hifiJSDoc.json") if (BUILD_TOOLS AND JSDOC_ENABLED)
message(STATUS "JSDoc enabled, depending on jsdoc")
add_custom_qrc_path(CUSTOM_INTERFACE_QRC_PATHS "${CMAKE_BINARY_DIR}/tools/jsdoc/out/hifiJSDoc.json" "auto-complete/hifiJSDoc.json")
endif () endif ()
set(RESOURCES_QRC ${CMAKE_CURRENT_BINARY_DIR}/resources.qrc) set(RESOURCES_QRC ${CMAKE_CURRENT_BINARY_DIR}/resources.qrc)
set(RESOURCES_RCC ${CMAKE_CURRENT_SOURCE_DIR}/compiledResources/resources.rcc) set(RESOURCES_RCC ${CMAKE_CURRENT_BINARY_DIR}/resources.rcc)
generate_qrc(OUTPUT ${RESOURCES_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources CUSTOM_PATHS ${CUSTOM_INTERFACE_QRC_PATHS} GLOBS *) generate_qrc(OUTPUT ${RESOURCES_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources CUSTOM_PATHS ${CUSTOM_INTERFACE_QRC_PATHS} GLOBS *)
if (ANDROID) if (ANDROID)
# on Android, don't compress the rcc binary # on Android, don't compress the rcc binary
add_custom_command( qt5_add_binary_resources(resources "${RESOURCES_QRC}" DESTINATION "${RESOURCES_RCC}" OPTIONS -no-compress)
OUTPUT ${RESOURCES_RCC}
DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS}
COMMAND "${RCC_BINARY}"
ARGS ${RESOURCES_QRC} -no-compress -binary -o ${RESOURCES_RCC}
)
else () else ()
add_custom_command( qt5_add_binary_resources(resources "${RESOURCES_QRC}" DESTINATION "${RESOURCES_RCC}")
OUTPUT ${RESOURCES_RCC} endif()
DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS}
COMMAND "${RCC_BINARY}" if (BUILD_TOOLS AND JSDOC_ENABLED)
ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC} add_dependencies(resources jsdoc)
)
endif() endif()
list(APPEND GENERATE_QRC_DEPENDS ${RESOURCES_RCC}) list(APPEND GENERATE_QRC_DEPENDS ${RESOURCES_RCC})
add_custom_target(resources ALL DEPENDS ${GENERATE_QRC_DEPENDS})
# set a default root dir for each of our optional externals if it was not passed # set a default root dir for each of our optional externals if it was not passed
set(OPTIONAL_EXTERNALS "LeapMotion") set(OPTIONAL_EXTERNALS "LeapMotion")
@ -96,13 +96,6 @@ else ()
list(REMOVE_ITEM INTERFACE_SRCS ${SPEECHRECOGNIZER_CPP}) list(REMOVE_ITEM INTERFACE_SRCS ${SPEECHRECOGNIZER_CPP})
endif () endif ()
find_package(
Qt5 COMPONENTS
Gui Widgets Multimedia Network Qml Quick Script Svg
${PLATFORM_QT_COMPONENTS}
WebChannel WebSockets
)
# grab the ui files in resources/ui # grab the ui files in resources/ui
file (GLOB_RECURSE QT_UI_FILES ui/*.ui) file (GLOB_RECURSE QT_UI_FILES ui/*.ui)
source_group("UI Files" FILES ${QT_UI_FILES}) source_group("UI Files" FILES ${QT_UI_FILES})
@ -191,13 +184,7 @@ else ()
add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM}) add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM})
endif () endif ()
if (NOT ANDROID)
if (BUILD_TOOLS AND NPM_EXECUTABLE)
# require JSDoc to be build before interface is deployed
add_dependencies(resources jsdoc)
endif()
if (WIN32 OR APPLE)
add_dependencies(${TARGET_NAME} resources) add_dependencies(${TARGET_NAME} resources)
endif() endif()
@ -343,10 +330,6 @@ if (APPLE)
COMMAND "${CMAKE_COMMAND}" -E copy_directory COMMAND "${CMAKE_COMMAND}" -E copy_directory
"${CMAKE_SOURCE_DIR}/scripts" "${CMAKE_SOURCE_DIR}/scripts"
"${RESOURCES_DEV_DIR}/scripts" "${RESOURCES_DEV_DIR}/scripts"
# copy JSDoc files beside the executable
COMMAND "${CMAKE_COMMAND}" -E copy_directory
"${CMAKE_SOURCE_DIR}/tools/jsdoc/out"
"${RESOURCES_DEV_DIR}/jsdoc"
# copy the resources files beside the executable # copy the resources files beside the executable
COMMAND "${CMAKE_COMMAND}" -E copy_if_different COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${RESOURCES_RCC}" "${RESOURCES_RCC}"
@ -378,6 +361,13 @@ if (APPLE)
) )
endif() endif()
if (JSDOC_ENABLED)
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
# copy JSDoc files beside the executable
COMMAND "${CMAKE_COMMAND}" -E copy_directory
"${JSDOC_OUTPUT_PATH}"
"${RESOURCES_DEV_DIR}/jsdoc")
endif()
# call the fixup_interface macro to add required bundling commands for installation # call the fixup_interface macro to add required bundling commands for installation
fixup_interface() fixup_interface()
@ -387,9 +377,6 @@ else()
# copy the resources files beside the executable # copy the resources files beside the executable
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${RESOURCES_RCC}"
"${INTERFACE_EXEC_DIR}"
# FIXME, the edit script code loads HTML from the scripts folder # FIXME, the edit script code loads HTML from the scripts folder
# which in turn relies on CSS that refers to the fonts. In theory # which in turn relies on CSS that refers to the fonts. In theory
# we should be able to modify the CSS to reference the QRC path to # we should be able to modify the CSS to reference the QRC path to
@ -407,11 +394,18 @@ else()
COMMAND "${CMAKE_COMMAND}" -E copy_if_different COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${PROJECT_SOURCE_DIR}/resources/serverless/redirect.json" "${PROJECT_SOURCE_DIR}/resources/serverless/redirect.json"
"${RESOURCES_DEV_DIR}/serverless/redirect.json" "${RESOURCES_DEV_DIR}/serverless/redirect.json"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${RESOURCES_RCC}"
"${INTERFACE_EXEC_DIR}/resources.rcc"
)
if (JSDOC_ENABLED)
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
# copy JSDoc files beside the executable # copy JSDoc files beside the executable
COMMAND "${CMAKE_COMMAND}" -E copy_directory COMMAND "${CMAKE_COMMAND}" -E copy_directory
"${CMAKE_SOURCE_DIR}/tools/jsdoc/out" "${JSDOC_OUTPUT_PATH}"
"${INTERFACE_EXEC_DIR}/jsdoc" "${INTERFACE_EXEC_DIR}/jsdoc")
) endif()
# link target to external libraries # link target to external libraries
if (WIN32) if (WIN32)

View file

@ -805,11 +805,13 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
{ {
const QString resourcesBinaryFile = PathUtils::getRccPath(); const QString resourcesBinaryFile = PathUtils::getRccPath();
qCInfo(interfaceapp) << "Loading primary resources from" << resourcesBinaryFile;
if (!QFile::exists(resourcesBinaryFile)) { if (!QFile::exists(resourcesBinaryFile)) {
throw std::runtime_error("Unable to find primary resources"); throw std::runtime_error(QString("Unable to find primary resources from '%1'").arg(resourcesBinaryFile).toStdString());
} }
if (!QResource::registerResource(resourcesBinaryFile)) { if (!QResource::registerResource(resourcesBinaryFile)) {
throw std::runtime_error("Unable to load primary resources"); throw std::runtime_error(QString("Unable to load primary resources from '%1'").arg(resourcesBinaryFile).toStdString());
} }
} }
@ -1965,7 +1967,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
} }
QString scriptsSwitch = QString("--").append(SCRIPTS_SWITCH); QString scriptsSwitch = QString("--").append(SCRIPTS_SWITCH);
_defaultScriptsLocation = getCmdOption(argc, constArgv, scriptsSwitch.toStdString().c_str()); _defaultScriptsLocation.setPath(getCmdOption(argc, constArgv, scriptsSwitch.toStdString().c_str()));
// Make sure we don't time out during slow operations at startup // Make sure we don't time out during slow operations at startup
updateHeartbeat(); updateHeartbeat();
@ -3264,12 +3266,12 @@ void Application::initializeUi() {
auto newValidator = [=](const QUrl& url) -> bool { auto newValidator = [=](const QUrl& url) -> bool {
QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]"; QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]";
QList<QString> safeURLS = { "" }; QList<QString> safeURLS = { "" };
safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), Qt::SkipEmptyParts);
// PULL SAFEURLS FROM INTERFACE.JSON Settings // PULL SAFEURLS FROM INTERFACE.JSON Settings
QVariant raw = Setting::Handle<QVariant>("private/settingsSafeURLS").get(); QVariant raw = Setting::Handle<QVariant>("private/settingsSafeURLS").get();
QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts); QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), Qt::SkipEmptyParts);
safeURLS += settingsSafeURLS; safeURLS += settingsSafeURLS;
// END PULL SAFEURLS FROM INTERFACE.JSON Settings // END PULL SAFEURLS FROM INTERFACE.JSON Settings
@ -8846,19 +8848,19 @@ void Application::initPlugins(const QStringList& arguments) {
parser.parse(arguments); parser.parse(arguments);
if (parser.isSet(display)) { if (parser.isSet(display)) {
auto preferredDisplays = parser.value(display).split(',', QString::SkipEmptyParts); auto preferredDisplays = parser.value(display).split(',', Qt::SkipEmptyParts);
qInfo() << "Setting prefered display plugins:" << preferredDisplays; qInfo() << "Setting prefered display plugins:" << preferredDisplays;
PluginManager::getInstance()->setPreferredDisplayPlugins(preferredDisplays); PluginManager::getInstance()->setPreferredDisplayPlugins(preferredDisplays);
} }
if (parser.isSet(disableDisplays)) { if (parser.isSet(disableDisplays)) {
auto disabledDisplays = parser.value(disableDisplays).split(',', QString::SkipEmptyParts); auto disabledDisplays = parser.value(disableDisplays).split(',', Qt::SkipEmptyParts);
qInfo() << "Disabling following display plugins:" << disabledDisplays; qInfo() << "Disabling following display plugins:" << disabledDisplays;
PluginManager::getInstance()->disableDisplays(disabledDisplays); PluginManager::getInstance()->disableDisplays(disabledDisplays);
} }
if (parser.isSet(disableInputs)) { if (parser.isSet(disableInputs)) {
auto disabledInputs = parser.value(disableInputs).split(',', QString::SkipEmptyParts); auto disabledInputs = parser.value(disableInputs).split(',', Qt::SkipEmptyParts);
qInfo() << "Disabling following input plugins:" << disabledInputs; qInfo() << "Disabling following input plugins:" << disabledInputs;
PluginManager::getInstance()->disableInputs(disabledInputs); PluginManager::getInstance()->disableInputs(disabledInputs);
} }

View file

@ -827,10 +827,10 @@ Menu::Menu() {
}); });
// Help > Vircadia Forum // Help > Vircadia Forum
/* action = addActionToQMenuAndActionHash(helpMenu, "Online Forums"); action = addActionToQMenuAndActionHash(helpMenu, "Community Support");
connect(action, &QAction::triggered, qApp, [] { connect(action, &QAction::triggered, qApp, [] {
QDesktopServices::openUrl(NetworkingConstants::HELP_FORUM_URL)); QDesktopServices::openUrl(NetworkingConstants::HELP_COMMUNITY_URL);
}); */ });
// Help > Scripting Reference // Help > Scripting Reference
action = addActionToQMenuAndActionHash(helpMenu, "Online Script Reference"); action = addActionToQMenuAndActionHash(helpMenu, "Online Script Reference");

View file

@ -7,3 +7,7 @@ include_hifi_library_headers(hfm)
include_hifi_library_headers(image) include_hifi_library_headers(image)
target_nsight() target_nsight()
if (WIN32)
add_compile_definitions(_USE_MATH_DEFINES)
endif()

View file

@ -124,9 +124,9 @@ HTTPConnection::HTTPConnection(QTcpSocket* socket, HTTPManager* parentManager) :
_socket->setParent(this); _socket->setParent(this);
// connect initial slots // connect initial slots
connect(socket, SIGNAL(readyRead()), SLOT(readRequest())); connect(socket, &QAbstractSocket::readyRead, this, &HTTPConnection::readRequest);
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(deleteLater())); connect(socket, &QAbstractSocket::errorOccurred, this, &HTTPConnection::deleteLater);
connect(socket, SIGNAL(disconnected()), SLOT(deleteLater())); connect(socket, &QAbstractSocket::disconnected, this, &HTTPConnection::deleteLater);
} }
HTTPConnection::~HTTPConnection() { HTTPConnection::~HTTPConnection() {

View file

@ -19,3 +19,6 @@ include_hifi_library_headers(graphics-scripting) # for Forward.h
target_bullet() target_bullet()
target_polyvox() target_polyvox()
if (WIN32)
add_compile_definitions(_USE_MATH_DEFINES)
endif()

View file

@ -9,3 +9,7 @@ include_hifi_library_headers(ktx)
include_hifi_library_headers(material-networking) include_hifi_library_headers(material-networking)
include_hifi_library_headers(procedural) include_hifi_library_headers(procedural)
link_hifi_libraries(shared shaders networking octree avatars graphics model-networking) link_hifi_libraries(shared shaders networking octree avatars graphics model-networking)
if (WIN32)
add_compile_definitions(_USE_MATH_DEFINES)
endif()

View file

@ -68,7 +68,7 @@ EntityTree::~EntityTree() {
} }
void EntityTree::setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist) { void EntityTree::setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist) {
_entityScriptSourceWhitelist = entityScriptSourceWhitelist.split(',', QString::SkipEmptyParts); _entityScriptSourceWhitelist = entityScriptSourceWhitelist.split(',', Qt::SkipEmptyParts);
} }

View file

@ -11,3 +11,7 @@ if (UNIX AND NOT APPLE)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
target_link_libraries(image Threads::Threads) target_link_libraries(image Threads::Threads)
endif() endif()
if (WIN32)
add_compile_definitions(_USE_MATH_DEFINES)
endif()

View file

@ -59,7 +59,7 @@ void AssetResourceRequest::doSend() {
// We'll either have a hash or an ATP path to a file (that maps to a hash) // We'll either have a hash or an ATP path to a file (that maps to a hash)
if (urlIsAssetHash(_url)) { if (urlIsAssetHash(_url)) {
// We've detected that this is a hash - simply use AssetClient to request that asset // We've detected that this is a hash - simply use AssetClient to request that asset
auto parts = _url.path().split(".", QString::SkipEmptyParts); auto parts = _url.path().split(".", Qt::SkipEmptyParts);
auto hash = parts.length() > 0 ? parts[0] : ""; auto hash = parts.length() > 0 ? parts[0] : "";
requestHash(hash); requestHash(hash);

View file

@ -1237,8 +1237,7 @@ void LimitedNodeList::updateLocalSocket() {
QTcpSocket* localIPTestSocket = new QTcpSocket; QTcpSocket* localIPTestSocket = new QTcpSocket;
connect(localIPTestSocket, &QTcpSocket::connected, this, &LimitedNodeList::connectedForLocalSocketTest); connect(localIPTestSocket, &QTcpSocket::connected, this, &LimitedNodeList::connectedForLocalSocketTest);
connect(localIPTestSocket, static_cast<void(QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), connect(localIPTestSocket, &QTcpSocket::errorOccurred, this, &LimitedNodeList::errorTestingLocalSocket);
this, &LimitedNodeList::errorTestingLocalSocket);
// attempt to connect to our reliable host // attempt to connect to our reliable host
localIPTestSocket->connectToHost(RELIABLE_LOCAL_IP_CHECK_HOST, RELIABLE_LOCAL_IP_CHECK_PORT); localIPTestSocket->connectToHost(RELIABLE_LOCAL_IP_CHECK_HOST, RELIABLE_LOCAL_IP_CHECK_PORT);

View file

@ -71,8 +71,9 @@ namespace NetworkingConstants {
const unsigned short STUN_SERVER_DEFAULT_PORT = 19302; const unsigned short STUN_SERVER_DEFAULT_PORT = 19302;
#endif #endif
const QUrl HELP_DOCS_URL { "https://docs.vircadia.com" }; const QUrl HELP_COMMUNITY_URL{ "https://vircadia.com/#community" };
const QUrl HELP_FORUM_URL { "https://forum.vircadia.com" }; const QUrl HELP_DOCS_URL{ "https://docs.vircadia.com" };
const QUrl HELP_FORUM_URL{ "https://forum.vircadia.com" };
const QUrl HELP_SCRIPTING_REFERENCE_URL{ "https://apidocs.vircadia.dev/" }; const QUrl HELP_SCRIPTING_REFERENCE_URL{ "https://apidocs.vircadia.dev/" };
const QUrl HELP_RELEASE_NOTES_URL{ "https://docs.vircadia.com/release-notes.html" }; const QUrl HELP_RELEASE_NOTES_URL{ "https://docs.vircadia.com/release-notes.html" };
const QUrl HELP_BUG_REPORT_URL{ "https://github.com/vircadia/vircadia/issues" }; const QUrl HELP_BUG_REPORT_URL{ "https://github.com/vircadia/vircadia/issues" };

View file

@ -376,8 +376,8 @@ void NodeList::sendDomainServerCheckIn() {
// is this our localhost domain-server? // is this our localhost domain-server?
// if so we need to make sure we have an up-to-date local port in case it restarted // if so we need to make sure we have an up-to-date local port in case it restarted
if (domainSockAddr.getAddress() == QHostAddress::LocalHost if ((domainSockAddr.getAddress() == QHostAddress::LocalHost || hostname == "localhost")
|| hostname == "localhost") { && _domainPortAutoDiscovery) {
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT; quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, domainPort); getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, domainPort);
@ -534,7 +534,7 @@ void NodeList::sendDomainServerCheckIn() {
sendPacket(std::move(packetCopy), domainSockAddr); sendPacket(std::move(packetCopy), domainSockAddr);
} }
sendPacket(std::move(domainPacket), domainSockAddr); sendPacket(std::move(domainPacket), domainSockAddr);
} }
} }
@ -661,7 +661,7 @@ void NodeList::handleICEConnectionToDomainServer() {
_domainHandler.getICEClientID(), _domainHandler.getICEClientID(),
_domainHandler.getPendingDomainID()); _domainHandler.getPendingDomainID());
} }
} }
void NodeList::pingPunchForDomainServer() { void NodeList::pingPunchForDomainServer() {
// make sure if we're here that we actually still need to ping the domain-server // make sure if we're here that we actually still need to ping the domain-server
@ -715,7 +715,7 @@ void NodeList::processDomainList(QSharedPointer<ReceivedMessage> message) {
// WEBRTC TODO: Move code into packet library. And update reference in DomainServerList.js. // WEBRTC TODO: Move code into packet library. And update reference in DomainServerList.js.
// parse header information // parse header information
QDataStream packetStream(message->getMessage()); QDataStream packetStream(message->getMessage());
// grab the domain's ID from the beginning of the packet // grab the domain's ID from the beginning of the packet
@ -796,7 +796,7 @@ void NodeList::processDomainList(QSharedPointer<ReceivedMessage> message) {
if (_domainHandler.isConnected() && _domainHandler.getUUID() != domainUUID) { if (_domainHandler.isConnected() && _domainHandler.getUUID() != domainUUID) {
// Received packet from different domain. // Received packet from different domain.
qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to" qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to"
<< _domainHandler.getUUID() << ": sent " << pingLagTime << " msec ago."; << _domainHandler.getUUID() << ": sent " << pingLagTime << " msec ago.";
qWarning(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec"; qWarning(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec";
qWarning(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec"; qWarning(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec";
@ -823,7 +823,7 @@ void NodeList::processDomainList(QSharedPointer<ReceivedMessage> message) {
setSessionLocalID(newLocalID); setSessionLocalID(newLocalID);
setSessionUUID(newUUID); setSessionUUID(newUUID);
// FIXME: Remove this call to requestDomainSettings() and reinstate the one in DomainHandler::setIsConnected(), in version // FIXME: Remove this call to requestDomainSettings() and reinstate the one in DomainHandler::setIsConnected(), in version
// 2021.2.0. (New protocol version implies a domain server upgrade.) // 2021.2.0. (New protocol version implies a domain server upgrade.)
if (!_domainHandler.isConnected() if (!_domainHandler.isConnected()
&& _domainHandler.getScheme() == URL_SCHEME_VIRCADIA && !_domainHandler.getHostname().isEmpty()) { && _domainHandler.getScheme() == URL_SCHEME_VIRCADIA && !_domainHandler.getHostname().isEmpty()) {
@ -833,7 +833,7 @@ void NodeList::processDomainList(QSharedPointer<ReceivedMessage> message) {
_domainHandler.requestDomainSettings(); _domainHandler.requestDomainSettings();
} }
// Don't continue login to the domain if have avatar entities and don't have permissions to rez them, unless user has OKed // Don't continue login to the domain if have avatar entities and don't have permissions to rez them, unless user has OKed
// continuing login. // continuing login.
if (!newPermissions.can(NodePermissions::Permission::canRezAvatarEntities) if (!newPermissions.can(NodePermissions::Permission::canRezAvatarEntities)
&& (!adjustedPermissions || !_domainHandler.canConnectWithoutAvatarEntities())) { && (!adjustedPermissions || !_domainHandler.canConnectWithoutAvatarEntities())) {
@ -926,7 +926,7 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) {
if (node->getConnectionAttempts() > 0 && node->getConnectionAttempts() % NUM_DEBUG_CONNECTION_ATTEMPTS == 0) { if (node->getConnectionAttempts() > 0 && node->getConnectionAttempts() % NUM_DEBUG_CONNECTION_ATTEMPTS == 0) {
qCDebug(networking) << "No response to UDP hole punch pings for node" << node->getUUID() << "in last 2 s."; qCDebug(networking) << "No response to UDP hole punch pings for node" << node->getUUID() << "in last 2 s.";
} }
auto nodeID = node->getUUID(); auto nodeID = node->getUUID();
// send the ping packet to the local and public sockets for this node // send the ping packet to the local and public sockets for this node

View file

@ -71,6 +71,8 @@ public:
void setAssignmentServerSocket(const SockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } void setAssignmentServerSocket(const SockAddr& serverSocket) { _assignmentServerSocket = serverSocket; }
void sendAssignment(Assignment& assignment); void sendAssignment(Assignment& assignment);
void disableDomainPortAutoDiscovery(bool disabled = false) { _domainPortAutoDiscovery = !disabled; };
void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; } void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; }
void ignoreNodesInRadius(bool enabled = true); void ignoreNodesInRadius(bool enabled = true);
@ -106,7 +108,7 @@ public:
public slots: public slots:
void reset(QString reason, bool skipDomainHandlerReset = false); void reset(QString reason, bool skipDomainHandlerReset = false);
void resetFromDomainHandler() { reset("Reset from Domain Handler", true); } void resetFromDomainHandler() { reset("Reset from Domain Handler", true); }
void sendDomainServerCheckIn(); void sendDomainServerCheckIn();
void handleDSPathQuery(const QString& newPath); void handleDSPathQuery(const QString& newPath);
@ -183,6 +185,7 @@ private:
bool _requestsDomainListData { false }; bool _requestsDomainListData { false };
bool _sendDomainServerCheckInEnabled { true }; bool _sendDomainServerCheckInEnabled { true };
bool _domainPortAutoDiscovery { true };
mutable QReadWriteLock _ignoredSetLock; mutable QReadWriteLock _ignoredSetLock;
tbb::concurrent_unordered_set<QUuid, UUIDHasher> _ignoredNodeIDs; tbb::concurrent_unordered_set<QUuid, UUIDHasher> _ignoredNodeIDs;

View file

@ -16,3 +16,6 @@ if (NOT ANDROID)
target_nsight() target_nsight()
endif () endif ()
if (WIN32)
add_compile_definitions(_USE_MATH_DEFINES)
endif()

View file

@ -1624,7 +1624,7 @@ std::set<unsigned int> Model::getMeshIDsFromMaterialID(QString parentMaterialNam
}; };
if (parentMaterialName.length() > 2 && parentMaterialName.startsWith("[") && parentMaterialName.endsWith("]")) { if (parentMaterialName.length() > 2 && parentMaterialName.startsWith("[") && parentMaterialName.endsWith("]")) {
QStringList list = parentMaterialName.split(",", QString::SkipEmptyParts); QStringList list = parentMaterialName.split(",", Qt::SkipEmptyParts);
for (int i = 0; i < list.length(); i++) { for (int i = 0; i < list.length(); i++) {
auto& target = list[i]; auto& target = list[i];
if (i == 0) { if (i == 0) {

View file

@ -187,7 +187,7 @@ void inputControllerFromScriptValue(const QScriptValue &object, controller::Inpu
// //
// Extract the url portion of a url that has been encoded with encodeEntityIdIntoEntityUrl(...) // Extract the url portion of a url that has been encoded with encodeEntityIdIntoEntityUrl(...)
QString extractUrlFromEntityUrl(const QString& url) { QString extractUrlFromEntityUrl(const QString& url) {
auto parts = url.split(' ', QString::SkipEmptyParts); auto parts = url.split(' ', Qt::SkipEmptyParts);
if (parts.length() > 0) { if (parts.length() > 0) {
return parts[0]; return parts[0];
} else { } else {
@ -2386,7 +2386,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
bool passList = false; // assume unsafe bool passList = false; // assume unsafe
QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]"; QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]";
QList<QString> safeURLPrefixes = { "file:///", "atp:", "cache:" }; QList<QString> safeURLPrefixes = { "file:///", "atp:", "cache:" };
safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), Qt::SkipEmptyParts);
// Entity Script Whitelist toggle check. // Entity Script Whitelist toggle check.
Setting::Handle<bool> whitelistEnabled {"private/whitelistEnabled", false }; Setting::Handle<bool> whitelistEnabled {"private/whitelistEnabled", false };
@ -2397,7 +2397,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
// Pull SAFEURLS from the Interface.JSON settings. // Pull SAFEURLS from the Interface.JSON settings.
QVariant raw = Setting::Handle<QVariant>("private/settingsSafeURLS").get(); QVariant raw = Setting::Handle<QVariant>("private/settingsSafeURLS").get();
QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts); QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), Qt::SkipEmptyParts);
safeURLPrefixes += settingsSafeURLS; safeURLPrefixes += settingsSafeURLS;
// END Pull SAFEURLS from the Interface.JSON settings. // END Pull SAFEURLS from the Interface.JSON settings.

View file

@ -7,6 +7,7 @@ setup_hifi_library(Gui Network Script)
if (WIN32) if (WIN32)
target_link_libraries(${TARGET_NAME} Wbemuuid.lib) target_link_libraries(${TARGET_NAME} Wbemuuid.lib)
add_compile_definitions(_USE_MATH_DEFINES)
endif() endif()
if (ANDROID) if (ANDROID)

View file

@ -68,7 +68,7 @@ QString FileUtils::readFile(const QString& filename) {
} }
QStringList FileUtils::readLines(const QString& filename, QString::SplitBehavior splitBehavior) { QStringList FileUtils::readLines(const QString& filename, QString::SplitBehavior splitBehavior) {
return readFile(filename).split(QRegularExpression("[\\r\\n]"), QString::SkipEmptyParts); return readFile(filename).split(QRegularExpression("[\\r\\n]"), Qt::SkipEmptyParts);
} }
void FileUtils::locateFile(const QString& filePath) { void FileUtils::locateFile(const QString& filePath) {

View file

@ -1,5 +1,5 @@
[Unit] [Unit]
Description=Assignment client service for Vircadia server Description=Assignment client service for the Vircadia server
After=network.target After=network.target
PartOf=vircadia-server.target PartOf=vircadia-server.target

View file

@ -1,5 +1,5 @@
[Unit] [Unit]
Description=Assignment client service for Vircadia server Description=Assignment client service for the Vircadia server
After=network.target After=network.target
PartOf=vircadia-server@%i.target PartOf=vircadia-server@%i.target
@ -14,7 +14,7 @@ User=vircadia
Group=vircadia Group=vircadia
#LimitCORE=infinity #LimitCORE=infinity
#ExecStart=/opt/vircadia/assignment-client -n 6 #ExecStart=/opt/vircadia/assignment-client -n 6
ExecStart=/opt/vircadia/assignment-client --min 6 --max 20 --server-port $HIFI_DOMAIN_SERVER_PORT ExecStart=/opt/vircadia/assignment-client --min 6 --max 20 --server-port $HIFI_DOMAIN_SERVER_PORT --disable-domain-port-auto-discovery
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View file

@ -1014,9 +1014,9 @@
"dev": true "dev": true
}, },
"path-parse": { "path-parse": {
"version": "1.0.6", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true "dev": true
}, },
"pend": { "pend": {

View file

@ -13,8 +13,18 @@
#component-templates { #component-templates {
display: none; display: none;
} }
.thumbnailItem .d-flex {
background: rgba(0, 0, 0, 0.2);
backdrop-filter: blur(5px);
text-shadow: 1px 1px 2px black, 0 0 25px black, 0 0 5px black;
}
.thumbnailItemHover .d-flex {
background: rgba(100, 100, 100, 0.2);
}
</style> </style>
<!--<script src="js/TestEventBridge.js"></script>--> <!--<script src="../Explore/js/TestEventBridge.js"></script>-->
</head> </head>
<body> <body>
<div id="component-templates"> <div id="component-templates">
@ -22,7 +32,7 @@
<v-dialog v-model="dialog" fullscreen hide-overlay transition="dialog-bottom-transition"> <v-dialog v-model="dialog" fullscreen hide-overlay transition="dialog-bottom-transition">
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn color="grey darken-3" class="ml-5" v-show="permission" value="animations" v-bind="attrs" v-on="on" fab small> <v-btn color="grey darken-3" class="ml-5" v-show="permission" value="animations" v-bind="attrs" v-on="on" fab small>
<v-icon color="purple">mdi-map-plus</v-icon> <v-icon color="purple lighten-2">mdi-map-plus</v-icon>
</v-btn> </v-btn>
</template> </template>
<v-card> <v-card>
@ -30,7 +40,7 @@
<v-btn icon dark @click="closeDialog();"> <v-btn icon dark @click="closeDialog();">
<v-icon>mdi-close</v-icon> <v-icon>mdi-close</v-icon>
</v-btn> </v-btn>
<v-toolbar-title>Add Location</v-toolbar-title> <v-toolbar-title>Add Location Beacon</v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-toolbar-items> <v-toolbar-items>
<v-btn dark text @click="addLocation()">Save</v-btn> <v-btn dark text @click="addLocation()">Save</v-btn>
@ -101,30 +111,28 @@
<template v-slot:default="props"> <template v-slot:default="props">
<v-row dense> <v-row dense>
<v-col v-for="item in props.items" <v-col v-for="item in props.items"
:key="item.name" :key="item.index"
cols="12" cols="12"
sm="6" sm="6"
md="4" md="4"
lg="3"> lg="3">
<v-hover <v-hover v-slot:default="{ hover }">
v-slot:default="{ hover }" <v-card @click.native="openLocation(item['location'])"
> :color="hover ? 'grey darken-3' : 'grey darken-4'"
<v-card :style="item.thumbnail ? 'background-size: cover; background-position: center; background-image: url(' + item.thumbnail +');' : '' "
@click.native="openLocation(item['Visit'])" :class="item.thumbnail ? (hover ? 'thumbnailItem thumbnailItemHover' : 'thumbnailItem') : '' "
:color="hover ? 'grey darken-3' : 'grey darken-4'" >
>
<!--<v-card-title class="headline">{{ item["Domain Name"] }}</v-card-title>-->
<div class="d-flex flex-no-wrap justify-space-between"> <div class="d-flex flex-no-wrap justify-space-between">
<div> <div>
<v-card-title class="text-h6 d-block text-truncate pa-2" v-text="item['Domain Name']" style="max-width: 400px;"></v-card-title> <v-card-title class="text-h6 d-block text-truncate pa-2" v-text="item['name']" style="max-width: 400px;"></v-card-title>
<v-card-subtitle class="pa-2 d-block text-truncate" style="max-width: 400px;" v-text="item.Owner"></v-card-subtitle> <v-card-subtitle class="pa-2 d-block text-truncate" style="max-width: 400px;" v-text="item.owner"></v-card-subtitle>
</div> </div>
<div style="text-align: right;"> <div style="text-align: right;">
<v-card-title align-right class="align-right" v-text="item['People']"></v-card-title> <v-card-title align-right class="align-right" v-text="item['userCount']"></v-card-title>
</div> </div>
</div> </div>
</v-card> </v-card>
</hover> </v-hover>
</v-col> </v-col>
</v-row> </v-row>
</template> </template>
@ -230,7 +238,7 @@
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" color="grey darken-3" class="mx-1" v-show="isHomeSet" value="animations" fab small @click="navigateHome()"> <v-btn v-bind="attrs" v-on="on" color="grey darken-3" class="mx-1" v-show="isHomeSet" value="animations" fab small @click="navigateHome()">
<v-icon color="purple">mdi-home</v-icon> <v-icon color="purple lighten-2">mdi-home</v-icon>
</v-btn> </v-btn>
</template> </template>
<span>Go Home</span> <span>Go Home</span>
@ -238,7 +246,7 @@
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" color="grey darken-3" class="mx-1" value="animations" fab small @click="navigateBack()"> <v-btn v-bind="attrs" v-on="on" color="grey darken-3" class="mx-1" value="animations" fab small @click="navigateBack()">
<v-icon color="purple">mdi-arrow-left-bold</v-icon> <v-icon color="purple lighten-2">mdi-arrow-left-bold</v-icon>
</v-btn> </v-btn>
</template> </template>
<span>Go Back</span> <span>Go Back</span>
@ -246,14 +254,14 @@
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" color="grey darken-3" class="mx-1" value="animations" fab small @click="navigateForward()"> <v-btn v-bind="attrs" v-on="on" color="grey darken-3" class="mx-1" value="animations" fab small @click="navigateForward()">
<v-icon color="purple">mdi-arrow-right-bold</v-icon> <v-icon color="purple lighten-2">mdi-arrow-right-bold</v-icon>
</v-btn> </v-btn>
</template> </template>
<span>Go Forward</span> <span>Go Forward</span>
</v-tooltip> </v-tooltip>
<!--<v-btn value="animations" fab small> <!--<v-btn value="animations" fab small>
<v-icon color="purple">mdi-map-marker-plus</v-icon> <v-icon color="purple">mdi-map-marker-plus</v-icon>
</v-btn>--> </v-btn>-->
<add-location ref="addLocation" :permission="permission"></add-location> <add-location ref="addLocation" :permission="permission"></add-location>
</v-app-bar> </v-app-bar>
</div> </div>
@ -286,22 +294,75 @@
<script src="../libraries/vue/vue.min.js"></script> <script src="../libraries/vue/vue.min.js"></script>
<script src="../libraries/vue-router/vue-router.js"></script> <script src="../libraries/vue-router/vue-router.js"></script>
<script src="../libraries/vuetify/vuetify-v2.3.9.js"></script> <script src="../libraries/vuetify/vuetify-v2.3.9.js"></script>
<script src="../libraries/axios/axios.min.js"></script>
<script> <script>
var exploreComponent = null; var exploreComponent = null;
var locationData = null; var locationData = null;
var placesData = null;
function blendedData() {
var joinedData = [];
if (locationData != null) {
for (var i = 0; i < locationData.length; i++) {
joinedData.push({
"index": joinedData.length,
"location": locationData[i].Visit,
"name": locationData[i]['Domain Name'],
"owner": locationData[i].Owner,
"userCount": locationData[i].People,
"description": "",
"thumbnail": ""
});
}
}
if (placesData != null) {
var activeThresholdTime = new Date();
activeThresholdTime.setMinutes(activeThresholdTime.getMinutes() - 15);
// while blending metaverse data ensure it is cleaned for active domains
for (var i = 0; i < placesData.length; i++) {
if (placesData[i].domain.active && placesData[i].visibility == "open" && new Date(placesData[i].last_activity_update) > activeThresholdTime) {
joinedData.push({
"index": joinedData.length,
"location": placesData[i].address,
"name": placesData[i].name,
"owner": placesData[i].managers[0],
"userCount": placesData[i].current_attendance,
"description": placesData[i].description,
"thumbnail": placesData[i].thumbnail
});
}
}
}
return joinedData;
}
function getAddressListData(component) { function getAddressListData(component) {
exploreComponent = component; exploreComponent = component;
if (locationData != null) { // if json data not loaded fire emti event for it
exploreComponent.updateData(locationData); if (locationData == null) {
return; var readyEvent = {
"action": "requestAddressList",
};
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
} }
var readyEvent = { // if metaverse data not loaded fire a request for it
"action": "requestAddressList", if (placesData == null) {
}; // fire off data get against the metaverse
EventBridge.emitWebEvent(JSON.stringify(readyEvent)); axios.get("https://metaverse.vircadia.com/live/api/v1/places")
.then((response) => {
placesData = response.data.data.places;
exploreComponent.updateData(blendedData());
})
.catch(function (error) {
console.log(error);
});
}
} }
var bookmarksComponent = null; var bookmarksComponent = null;
@ -346,8 +407,8 @@
page: 1, page: 1,
pageCount: 0, pageCount: 0,
itemsPerPage: 6, itemsPerPage: 6,
sortBy: 'People', sortBy: 'userCount',
items: [], items: [],
} }
}, },
template: document.getElementById("explore-template").innerHTML, template: document.getElementById("explore-template").innerHTML,
@ -544,7 +605,7 @@
if (messageData.action == "addressListv2") { if (messageData.action == "addressListv2") {
self.permission = messageData.permission; self.permission = messageData.permission;
locationData = messageData.myAddress; locationData = messageData.myAddress;
exploreComponent.updateData(locationData); exploreComponent.updateData(blendedData());
self.isHomeSet = messageData.isHomeSet; self.isHomeSet = messageData.isHomeSet;
} }
if (messageData.action == "bookmarksList") { if (messageData.action == "bookmarksList") {
@ -553,9 +614,9 @@
} }
if (messageData.action == "retrievePortInformationResponse") { if (messageData.action == "retrievePortInformationResponse") {
addLocationData = messageData.goToAddresses; addLocationData = messageData.goToAddresses;
for (let i = 0; i < addLocationData.length; i++) { for (let i = 0; i < addLocationData.length; i++) {
var metaverseProvider = addLocationData[i].split("/")[2].split(":")[0]; var metaverseProvider = addLocationData[i].split("/")[2].split(":")[0];
addLocationData[i] = "https://" + metaverseProvider + "/interim/d-goto/app/decentralizedGoToServerScript.js"; addLocationData[i] = "https://" + metaverseProvider + "/interim/d-goto/app/decentralizedGoToServerScript.js";
} }
addLocationComponent.updateData(addLocationData); addLocationComponent.updateData(addLocationData);
} }

View file

@ -0,0 +1,19 @@
Copyright (c) 2014-present Matt Zabriskie
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because one or more lines are too long

View file

@ -46,6 +46,27 @@
}); });
} }
//create a menu item in "Setings" to toggle the bubble/shield HUD button
var menuItemName = "HUD Shield Button";
Menu.addMenuItem({
menuName: "Settings",
menuItemName: menuItemName,
isCheckable: true,
isChecked: AvatarInputs.showBubbleTools
});
Menu.menuItemEvent.connect(onToggleHudShieldButton);
AvatarInputs.showBubbleToolsChanged.connect(showBubbleToolsChanged);
function onToggleHudShieldButton(menuItem) {
if (menuItem === menuItemName) {
AvatarInputs.setShowBubbleTools(Menu.isOptionChecked(menuItem));
};
}
function showBubbleToolsChanged(show) {
Menu.setIsOptionChecked(menuItemName, show);
}
// Make the bubble overlay visible, set its position, and play the sound // Make the bubble overlay visible, set its position, and play the sound
function createOverlays() { function createOverlays() {
var nowTimestamp = Date.now(); var nowTimestamp = Date.now();
@ -191,6 +212,9 @@
// Cleanup the tablet button and overlays when script is stopped // Cleanup the tablet button and overlays when script is stopped
Script.scriptEnding.connect(function () { Script.scriptEnding.connect(function () {
Menu.menuItemEvent.disconnect(onToggleHudShieldButton);
AvatarInputs.showBubbleToolsChanged.disconnect(showBubbleToolsChanged);
Menu.removeMenuItem("Settings", menuItemName);
button.clicked.disconnect(Users.toggleIgnoreRadius); button.clicked.disconnect(Users.toggleIgnoreRadius);
if (tablet) { if (tablet) {
tablet.removeButton(button); tablet.removeButton(button);

View file

@ -2656,6 +2656,24 @@ var PropertiesTool = function (opts) {
} else { } else {
audioFeedback.rejection(); audioFeedback.rejection();
} }
} else if (data.action === "setRotationToZero") {
if (selectionManager.selections.length === 1 && SelectionManager.hasUnlockedSelection()) {
selectionManager.saveProperties();
var parentState = getParentState(selectionManager.selections[0]);
if ((parentState === "PARENT_CHILDREN" || parentState === "CHILDREN") && selectionDisplay.getSpaceMode() === "local" ) {
Entities.editEntity(selectionManager.selections[0], {
localRotation: Quat.IDENTITY
});
} else {
Entities.editEntity(selectionManager.selections[0], {
rotation: Quat.IDENTITY
});
}
pushCommandForSelections();
selectionManager._update(false, this);
} else {
audioFeedback.rejection();
}
} }
} else if (data.type === "propertiesPageReady") { } else if (data.type === "propertiesPageReady") {
updateSelections(true); updateSelections(true);

View file

@ -1383,7 +1383,8 @@ const GROUPS = [
{ {
type: "buttons", type: "buttons",
buttons: [ { id: "copyRotation", label: "Copy Rotation", className: "secondary", onClick: copyRotationProperty }, buttons: [ { id: "copyRotation", label: "Copy Rotation", className: "secondary", onClick: copyRotationProperty },
{ id: "pasteRotation", label: "Paste Rotation", className: "secondary", onClick: pasteRotationProperty } ], { id: "pasteRotation", label: "Paste Rotation", className: "secondary", onClick: pasteRotationProperty },
{ id: "setRotationToZero", label: "Reset Rotation", className: "secondary_red red", onClick: setRotationToZeroProperty }],
propertyID: "copyPasteRotation" propertyID: "copyPasteRotation"
}, },
{ {
@ -1874,10 +1875,16 @@ function setCopyPastePositionAndRotationAvailability (selectionLength, islocked)
if (selectionLength > 0 && !islocked) { if (selectionLength > 0 && !islocked) {
$('#property-copyPastePosition-button-pastePosition').attr('disabled', false); $('#property-copyPastePosition-button-pastePosition').attr('disabled', false);
$('#property-copyPasteRotation-button-pasteRotation').attr('disabled', false); $('#property-copyPasteRotation-button-pasteRotation').attr('disabled', false);
if (selectionLength === 1) {
$('#property-copyPasteRotation-button-setRotationToZero').attr('disabled', false);
} else {
$('#property-copyPasteRotation-button-setRotationToZero').attr('disabled', true);
}
} else { } else {
$('#property-copyPastePosition-button-pastePosition').attr('disabled', true); $('#property-copyPastePosition-button-pastePosition').attr('disabled', true);
$('#property-copyPasteRotation-button-pasteRotation').attr('disabled', true); $('#property-copyPasteRotation-button-pasteRotation').attr('disabled', true);
$('#property-copyPasteRotation-button-setRotationToZero').attr('disabled', true);
} }
} }
@ -3273,7 +3280,12 @@ function pasteRotationProperty() {
action: "pasteRotation" action: "pasteRotation"
})); }));
} }
function setRotationToZeroProperty() {
EventBridge.emitWebEvent(JSON.stringify({
type: "action",
action: "setRotationToZero"
}));
}
/** /**
* USER DATA FUNCTIONS * USER DATA FUNCTIONS
*/ */

View file

@ -479,7 +479,22 @@ input[type=button].secondary, button.hifi-edit-button.secondary {
background: linear-gradient(#343434 20%, #000 100%); background: linear-gradient(#343434 20%, #000 100%);
cursor: pointer; cursor: pointer;
} }
input[type=button].secondary_red, button.hifi-edit-button.secondary_red {
font-family: Raleway-Bold;
font-size: 10px;
text-transform: uppercase;
vertical-align: top;
height: 18px;
min-width: 60px;
padding: 0 14px;
margin-right: 6px;
border-radius: 4px;
border: none;
color: #fff;
background-color: #94132e;
background: linear-gradient(#d42043 20%, #94132e 100%);
cursor: pointer;
}
input[type=button]:enabled:hover, button.hifi-edit-button:enabled:hover { input[type=button]:enabled:hover, button.hifi-edit-button:enabled:hover {
background: linear-gradient(#000, #000); background: linear-gradient(#000, #000);
border: none; border: none;

View file

@ -1,9 +1,13 @@
# add the tool directories # add the tool directories
message(STATUS "Checking for npm")
find_npm() find_npm()
if (NPM_EXECUTABLE) if (NPM_EXECUTABLE)
add_subdirectory(jsdoc) message(STATUS "Checking for npm - found ${NPM_EXECUTABLE}, will build jsdoc")
set_target_properties(jsdoc PROPERTIES FOLDER "Tools") add_subdirectory(jsdoc)
set_target_properties(jsdoc PROPERTIES FOLDER "Tools")
else()
message(NOTICE "Checking for npm - not found, jsdoc won't be genereated. Tab completion in the js console won't work!")
endif() endif()
function(check_test name) function(check_test name)

View file

@ -5,11 +5,15 @@ add_custom_target(${TARGET_NAME})
find_npm() find_npm()
set(JSDOC_WORKING_DIR ${CMAKE_SOURCE_DIR}/tools/jsdoc) set(JSDOC_WORKING_DIR ${CMAKE_SOURCE_DIR}/tools/jsdoc)
set(JSDOC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
file(TO_NATIVE_PATH ${JSDOC_WORKING_DIR}/node_modules/.bin/jsdoc JSDOC_PATH) file(TO_NATIVE_PATH ${JSDOC_WORKING_DIR}/node_modules/.bin/jsdoc JSDOC_PATH)
file(TO_NATIVE_PATH ${JSDOC_WORKING_DIR}/config.json JSDOC_CONFIG_PATH) file(TO_NATIVE_PATH ${JSDOC_WORKING_DIR}/config.json JSDOC_CONFIG_PATH)
file(TO_NATIVE_PATH ${JSDOC_WORKING_DIR}/out OUTPUT_DIR) file(TO_NATIVE_PATH ${JSDOC_OUTPUT_DIR}/out OUTPUT_DIR)
file(TO_NATIVE_PATH ${JSDOC_WORKING_DIR}/root.js NATIVE_JSDOC_WORKING_DIR) file(TO_NATIVE_PATH ${JSDOC_WORKING_DIR}/root.js NATIVE_JSDOC_WORKING_DIR)
set(JSDOC_OUTPUT_PATH ${OUTPUT_DIR} CACHE INTERNAL "${PROJECT_NAME}: JSDoc output directory")
add_custom_command(TARGET ${TARGET_NAME} add_custom_command(TARGET ${TARGET_NAME}
COMMAND ${NPM_EXECUTABLE} --no-progress install && ${JSDOC_PATH} ${NATIVE_JSDOC_WORKING_DIR} -c ${JSDOC_CONFIG_PATH} -d ${OUTPUT_DIR} COMMAND ${NPM_EXECUTABLE} --no-progress install && ${JSDOC_PATH} ${NATIVE_JSDOC_WORKING_DIR} -c ${JSDOC_CONFIG_PATH} -d ${OUTPUT_DIR}
WORKING_DIRECTORY ${JSDOC_WORKING_DIR} WORKING_DIRECTORY ${JSDOC_WORKING_DIR}

View file

@ -1,8 +1,22 @@
exports.handlers = { exports.handlers = {
processingComplete: function(e) { processingComplete: function(e) {
const pathTools = require('path'); const pathTools = require('path');
var outputFolder = pathTools.join(__dirname, '../out'); var outputFolder;
var doclets = e.doclets.map(doclet => Object.assign({}, doclet)); var doclets = e.doclets.map(doclet => Object.assign({}, doclet));
var argv = process.argv;
for (var i = 0; i < argv.length; i++) {
if (argv[i] === '-d') {
outputFolder = argv[i+1];
break;
}
}
if (!outputFolder) {
console.log("Output folder not found, specify it with -d");
process.exit(1);
}
const fs = require('fs'); const fs = require('fs');
if (!fs.existsSync(outputFolder)) { if (!fs.existsSync(outputFolder)) {
fs.mkdirSync(outputFolder); fs.mkdirSync(outputFolder);
@ -13,7 +27,7 @@ exports.handlers = {
return console.log(err); return console.log(err);
} }
console.log("The Vircadia JSDoc JSON was saved!"); console.log("The Vircadia JSDoc JSON was saved into " + outputFolder + "!");
}); });
} }
}; };

View file

@ -4,24 +4,19 @@ project(${TARGET_NAME})
set(CUSTOM_NITPICK_QRC_PATHS "") set(CUSTOM_NITPICK_QRC_PATHS "")
find_npm() find_npm()
find_package(Qt5 COMPONENTS Widgets)
set(RESOURCES_QRC ${CMAKE_CURRENT_BINARY_DIR}/resources.qrc) set(RESOURCES_QRC ${CMAKE_CURRENT_BINARY_DIR}/resources.qrc)
set(RESOURCES_RCC ${CMAKE_CURRENT_SOURCE_DIR}/compiledResources/resources.rcc) set(RESOURCES_RCC ${CMAKE_CURRENT_BINARY_DIR}/resources.rcc)
generate_qrc(OUTPUT ${RESOURCES_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources CUSTOM_PATHS ${CUSTOM_NITPICK_QRC_PATHS} GLOBS *) generate_qrc(OUTPUT ${RESOURCES_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources CUSTOM_PATHS ${CUSTOM_NITPICK_QRC_PATHS} GLOBS *)
add_custom_command( qt5_add_binary_resources(nitpick_resources "${RESOURCES_QRC}" DESTINATION "${RESOURCES_RCC}" OPTIONS -no-compress)
OUTPUT ${RESOURCES_RCC}
DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS}
COMMAND "${RCC_BINARY}"
ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC}
)
# grab the implementation and header files from src dirs # grab the implementation and header files from src dirs
file(GLOB_RECURSE NITPICK_SRCS "src/*.cpp" "src/*.h") file(GLOB_RECURSE NITPICK_SRCS "src/*.cpp" "src/*.h")
GroupSources("src") GroupSources("src")
list(APPEND NITPICK_SRCS ${RESOURCES_RCC}) list(APPEND NITPICK_SRCS ${RESOURCES_RCC})
find_package(Qt5 COMPONENTS Widgets)
# grab the ui files in ui # grab the ui files in ui
file (GLOB_RECURSE QT_UI_FILES ui/*.ui) file (GLOB_RECURSE QT_UI_FILES ui/*.ui)
@ -83,9 +78,7 @@ else ()
add_executable(${TARGET_NAME} ${NITPICK_SRCS} ${QM}) add_executable(${TARGET_NAME} ${NITPICK_SRCS} ${QM})
endif () endif ()
if (NOT UNIX) add_dependencies(${TARGET_NAME} nitpick_resources)
add_dependencies(${TARGET_NAME} resources)
endif()
# disable /OPT:REF and /OPT:ICF for the Debug builds # disable /OPT:REF and /OPT:ICF for the Debug builds
# This will prevent the following linker warnings # This will prevent the following linker warnings