From 2e5244663ebf7e1e1cb1ededd2f89d557cd81f06 Mon Sep 17 00:00:00 2001 From: Heather Anderson Date: Sun, 9 Aug 2020 14:57:00 -0700 Subject: [PATCH 01/74] transition listener registration from member string name to member string pointer --- assignment-client/src/Agent.cpp | 7 +- assignment-client/src/AssignmentClient.cpp | 6 +- .../src/AssignmentClientMonitor.cpp | 3 +- assignment-client/src/assets/AssetServer.cpp | 15 +- assignment-client/src/audio/AudioMixer.cpp | 17 +- assignment-client/src/avatars/AvatarMixer.cpp | 40 ++-- .../src/entities/EntityServer.cpp | 3 +- .../src/messages/MessagesMixer.cpp | 9 +- assignment-client/src/octree/OctreeServer.cpp | 6 +- .../src/scripts/EntityScriptServer.cpp | 17 +- domain-server/src/DomainGatekeeper.cpp | 3 +- domain-server/src/DomainServer.cpp | 57 ++++-- .../src/DomainServerSettingsManager.h | 2 + interface/src/commerce/Wallet.cpp | 6 +- .../src/octree/OctreePacketProcessor.cpp | 3 +- .../ScreenshareScriptingInterface.cpp | 3 +- interface/src/ui/DomainConnectionModel.cpp | 3 +- .../ui/overlays/ContextOverlayInterface.cpp | 3 +- libraries/audio-client/src/AudioClient.cpp | 21 +- libraries/avatars/src/AvatarHashMap.cpp | 12 +- libraries/avatars/src/ClientTraitsHandler.cpp | 3 +- .../entities/src/EntityEditPacketSender.cpp | 3 +- .../src/EntityScriptServerLogClient.cpp | 3 +- .../entities/src/EntityScriptingInterface.cpp | 3 +- libraries/networking/src/AssetClient.cpp | 12 +- .../networking/src/EntityScriptClient.cpp | 3 +- libraries/networking/src/MessagesClient.cpp | 3 +- libraries/networking/src/NodeList.cpp | 42 ++-- libraries/networking/src/PacketReceiver.cpp | 180 +++++------------- libraries/networking/src/PacketReceiver.h | 98 +++++++++- libraries/networking/src/ResourceCache.cpp | 5 +- libraries/octree/src/OctreePersistThread.cpp | 3 +- 32 files changed, 343 insertions(+), 251 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 59e53bb2cb..a8ce7e30e5 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -112,11 +112,12 @@ Agent::Agent(ReceivedMessage& message) : packetReceiver.registerListenerForTypes( { PacketType::MixedAudio, PacketType::SilentAudioFrame }, - this, "handleAudioPacket"); + PacketReceiver::makeUnsourcedListenerReference(this, &Agent::handleAudioPacket)); packetReceiver.registerListenerForTypes( { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, - this, "handleOctreePacket"); - packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); + PacketReceiver::makeSourcedListenerReference(this, &Agent::handleOctreePacket)); + packetReceiver.registerListener(PacketType::SelectedAudioFormat, + PacketReceiver::makeUnsourcedListenerReference(this, &Agent::handleSelectedAudioFormat)); // 100Hz timer for audio const int TARGET_INTERVAL_MSEC = 10; // 10ms diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index ce724d7368..50eee258ab 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -118,8 +118,10 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri setUpStatusToMonitor(); } auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); - packetReceiver.registerListener(PacketType::StopNode, this, "handleStopNodePacket"); + packetReceiver.registerListener(PacketType::CreateAssignment, + PacketReceiver::makeUnsourcedListenerReference(this, &AssignmentClient::handleCreateAssignmentPacket)); + packetReceiver.registerListener(PacketType::StopNode, + PacketReceiver::makeUnsourcedListenerReference(this, &AssignmentClient::handleStopNodePacket)); } void AssignmentClient::stopAssignmentClient() { diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 4c7f71a7aa..68c0dfc9fd 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -72,7 +72,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen auto nodeList = DependencyManager::set(listenPort); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AssignmentClientStatus, this, "handleChildStatusPacket"); + packetReceiver.registerListener(PacketType::AssignmentClientStatus, + PacketReceiver::makeUnsourcedListenerReference(this, &AssignmentClientMonitor::handleChildStatusPacket)); adjustOSResources(std::max(_numAssignmentClientForks, _maxAssignmentClientForks)); // use QProcess to fork off a process for each of the child assignment clients diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index b3344e3832..ffb6747fd7 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -308,7 +308,8 @@ AssetServer::AssetServer(ReceivedMessage& message) : // Queue all requests until the Asset Server is fully setup auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation }, this, "queueRequests"); + packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation }, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::queueRequests)); #ifdef Q_OS_WIN updateConsumedCores(); @@ -464,10 +465,14 @@ void AssetServer::completeSetup() { qCDebug(asset_server) << "Overriding temporary queuing packet handler."; // We're fully setup, override the request queueing handler and replay all requests auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet"); - packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo"); - packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload"); - packetReceiver.registerListener(PacketType::AssetMappingOperation, this, "handleAssetMappingOperation"); + packetReceiver.registerListener(PacketType::AssetGet, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::handleAssetGet)); + packetReceiver.registerListener(PacketType::AssetGetInfo, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::handleAssetGetInfo)); + packetReceiver.registerListener(PacketType::AssetUpload, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::handleAssetUpload)); + packetReceiver.registerListener(PacketType::AssetMappingOperation, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::handleAssetMappingOperation)); replayRequests(); } diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 161a6f4285..42a269c544 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -101,20 +101,23 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : PacketType::InjectorGainSet, PacketType::AudioSoloRequest, PacketType::StopInjector }, - this, "queueAudioPacket"); + PacketReceiver::makeSourcedListenerReference(this, &AudioMixer::queueAudioPacket) + ); // packets whose consequences are global should be processed on the main thread - packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); - packetReceiver.registerListener(PacketType::NodeMuteRequest, this, "handleNodeMuteRequestPacket"); - packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); + packetReceiver.registerListener(PacketType::MuteEnvironment, + PacketReceiver::makeSourcedListenerReference(this, &AudioMixer::handleMuteEnvironmentPacket)); + packetReceiver.registerListener(PacketType::NodeMuteRequest, + PacketReceiver::makeSourcedListenerReference(this, &AudioMixer::handleNodeMuteRequestPacket)); + packetReceiver.registerListener(PacketType::KillAvatar, + PacketReceiver::makeSourcedListenerReference(this, &AudioMixer::handleKillAvatarPacket)); packetReceiver.registerListenerForTypes({ PacketType::ReplicatedMicrophoneAudioNoEcho, PacketType::ReplicatedMicrophoneAudioWithEcho, PacketType::ReplicatedInjectAudio, - PacketType::ReplicatedSilentAudioFrame - }, - this, "queueReplicatedAudioPacket" + PacketType::ReplicatedSilentAudioFrame }, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioMixer::queueReplicatedAudioPacket) ); connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled); diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 807f54953e..27b7d0d302 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -71,26 +71,38 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) : connect(DependencyManager::get().data(), &NodeList::nodeKilled, this, &AvatarMixer::handleAvatarKilled); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AvatarData, this, "queueIncomingPacket"); - packetReceiver.registerListener(PacketType::AdjustAvatarSorting, this, "handleAdjustAvatarSorting"); - packetReceiver.registerListener(PacketType::AvatarQuery, this, "handleAvatarQueryPacket"); - packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket"); - packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); - packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); - packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket"); - packetReceiver.registerListener(PacketType::RequestsDomainListData, this, "handleRequestsDomainListDataPacket"); - packetReceiver.registerListener(PacketType::SetAvatarTraits, this, "queueIncomingPacket"); - packetReceiver.registerListener(PacketType::BulkAvatarTraitsAck, this, "queueIncomingPacket"); + packetReceiver.registerListener(PacketType::AvatarData, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::queueIncomingPacket)); + packetReceiver.registerListener(PacketType::AdjustAvatarSorting, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleAdjustAvatarSorting)); + packetReceiver.registerListener(PacketType::AvatarQuery, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleAvatarQueryPacket)); + packetReceiver.registerListener(PacketType::AvatarIdentity, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleAvatarIdentityPacket)); + packetReceiver.registerListener(PacketType::KillAvatar, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleKillAvatarPacket)); + packetReceiver.registerListener(PacketType::NodeIgnoreRequest, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleNodeIgnoreRequestPacket)); + packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleRadiusIgnoreRequestPacket)); + packetReceiver.registerListener(PacketType::RequestsDomainListData, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleRequestsDomainListDataPacket)); + packetReceiver.registerListener(PacketType::SetAvatarTraits, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::queueIncomingPacket)); + packetReceiver.registerListener(PacketType::BulkAvatarTraitsAck, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::queueIncomingPacket)); packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, - this, "handleOctreePacket"); - packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "queueIncomingPacket"); + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleOctreePacket)); + packetReceiver.registerListener(PacketType::ChallengeOwnership, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::queueIncomingPacket)); packetReceiver.registerListenerForTypes({ PacketType::ReplicatedAvatarIdentity, PacketType::ReplicatedKillAvatar - }, this, "handleReplicatedPacket"); + }, PacketReceiver::makeUnsourcedListenerReference(this, &AvatarMixer::handleReplicatedPacket)); - packetReceiver.registerListener(PacketType::ReplicatedBulkAvatarData, this, "handleReplicatedBulkAvatarPacket"); + packetReceiver.registerListener(PacketType::ReplicatedBulkAvatarData, + PacketReceiver::makeUnsourcedListenerReference(this, &AvatarMixer::handleReplicatedBulkAvatarPacket)); auto nodeList = DependencyManager::get(); connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &AvatarMixer::handlePacketVersionMismatch); diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 4c4fcbf2dd..e68f95bda0 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -59,8 +59,7 @@ EntityServer::EntityServer(ReceivedMessage& message) : PacketType::ChallengeOwnership, PacketType::ChallengeOwnershipRequest, PacketType::ChallengeOwnershipReply }, - this, - "handleEntityPacket"); + PacketReceiver::makeSourcedListenerReference(this, &EntityServer::handleEntityPacket)); connect(&_dynamicDomainVerificationTimer, &QTimer::timeout, this, &EntityServer::startDynamicDomainVerification); _dynamicDomainVerificationTimer.setSingleShot(true); diff --git a/assignment-client/src/messages/MessagesMixer.cpp b/assignment-client/src/messages/MessagesMixer.cpp index d2127835f9..bcf4881fcf 100644 --- a/assignment-client/src/messages/MessagesMixer.cpp +++ b/assignment-client/src/messages/MessagesMixer.cpp @@ -25,9 +25,12 @@ MessagesMixer::MessagesMixer(ReceivedMessage& message) : ThreadedAssignment(mess { connect(DependencyManager::get().data(), &NodeList::nodeKilled, this, &MessagesMixer::nodeKilled); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::MessagesData, this, "handleMessages"); - packetReceiver.registerListener(PacketType::MessagesSubscribe, this, "handleMessagesSubscribe"); - packetReceiver.registerListener(PacketType::MessagesUnsubscribe, this, "handleMessagesUnsubscribe"); + packetReceiver.registerListener(PacketType::MessagesData, + PacketReceiver::makeSourcedListenerReference(this, &MessagesMixer::handleMessages)); + packetReceiver.registerListener(PacketType::MessagesSubscribe, + PacketReceiver::makeSourcedListenerReference(this, &MessagesMixer::handleMessagesSubscribe)); + packetReceiver.registerListener(PacketType::MessagesUnsubscribe, + PacketReceiver::makeSourcedListenerReference(this, &MessagesMixer::handleMessagesUnsubscribe)); } void MessagesMixer::nodeKilled(SharedNodePointer killedNode) { diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 63520262cd..f72ab0ac05 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1122,8 +1122,10 @@ void OctreeServer::run() { void OctreeServer::domainSettingsRequestComplete() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); - packetReceiver.registerListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); + packetReceiver.registerListener(PacketType::OctreeDataNack, + PacketReceiver::makeSourcedListenerReference(this, &OctreeServer::handleOctreeDataNackPacket)); + packetReceiver.registerListener(getMyQueryMessageType(), + PacketReceiver::makeSourcedListenerReference(this, &OctreeServer::handleOctreeQueryPacket)); qDebug(octree_server) << "Received domain settings"; diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 7c3d491470..065ab12abc 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -83,13 +83,18 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, - this, "handleOctreePacket"); - packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleOctreePacket)); + packetReceiver.registerListener(PacketType::SelectedAudioFormat, + PacketReceiver::makeUnsourcedListenerReference(this, &EntityScriptServer::handleSelectedAudioFormat)); - packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket"); - packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket"); - packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket"); - packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket"); + packetReceiver.registerListener(PacketType::ReloadEntityServerScript, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleReloadEntityServerScriptPacket)); + packetReceiver.registerListener(PacketType::EntityScriptGetStatus, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleEntityScriptGetStatusPacket)); + packetReceiver.registerListener(PacketType::EntityServerScriptLog, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleEntityServerScriptLogPacket)); + packetReceiver.registerListener(PacketType::EntityScriptCallMethod, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleEntityScriptCallMethodPacket)); static const int LOG_INTERVAL = MSECS_PER_SECOND / 10; auto timer = new QTimer(this); diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index ead4002334..ef37b80d1b 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -17,7 +17,8 @@ #include #include -#include +#include +#include #include #include diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 41b0e98ec5..455a425330 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -765,32 +765,51 @@ void DomainServer::setupNodeListAndAssignments() { // register as the packet receiver for the types we want PacketReceiver& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::RequestAssignment, this, "processRequestAssignmentPacket"); - packetReceiver.registerListener(PacketType::DomainListRequest, this, "processListRequestPacket"); - packetReceiver.registerListener(PacketType::DomainServerPathQuery, this, "processPathQueryPacket"); - packetReceiver.registerListener(PacketType::NodeJsonStats, this, "processNodeJSONStatsPacket"); - packetReceiver.registerListener(PacketType::DomainDisconnectRequest, this, "processNodeDisconnectRequestPacket"); - packetReceiver.registerListener(PacketType::AvatarZonePresence, this, "processAvatarZonePresencePacket"); + packetReceiver.registerListener(PacketType::RequestAssignment, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processRequestAssignmentPacket)); + packetReceiver.registerListener(PacketType::DomainListRequest, + PacketReceiver::makeSourcedListenerReference(this, &DomainServer::processListRequestPacket)); + packetReceiver.registerListener(PacketType::DomainServerPathQuery, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processPathQueryPacket)); + packetReceiver.registerListener(PacketType::NodeJsonStats, + PacketReceiver::makeSourcedListenerReference(this, &DomainServer::processNodeJSONStatsPacket)); + packetReceiver.registerListener(PacketType::DomainDisconnectRequest, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processNodeDisconnectRequestPacket)); + packetReceiver.registerListener(PacketType::AvatarZonePresence, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processAvatarZonePresencePacket)); // NodeList won't be available to the settings manager when it is created, so call registerListener here - packetReceiver.registerListener(PacketType::DomainSettingsRequest, &_settingsManager, "processSettingsRequestPacket"); - packetReceiver.registerListener(PacketType::NodeKickRequest, &_settingsManager, "processNodeKickRequestPacket"); - packetReceiver.registerListener(PacketType::UsernameFromIDRequest, &_settingsManager, "processUsernameFromIDRequestPacket"); + packetReceiver.registerListener(PacketType::DomainSettingsRequest, + PacketReceiver::makeUnsourcedListenerReference(&_settingsManager, &DomainServerSettingsManager::processSettingsRequestPacket)); + packetReceiver.registerListener(PacketType::NodeKickRequest, + PacketReceiver::makeSourcedListenerReference(&_settingsManager, &DomainServerSettingsManager::processNodeKickRequestPacket)); + packetReceiver.registerListener(PacketType::UsernameFromIDRequest, + PacketReceiver::makeSourcedListenerReference(&_settingsManager, &DomainServerSettingsManager::processUsernameFromIDRequestPacket)); // register the gatekeeper for the packets it needs to receive - packetReceiver.registerListener(PacketType::DomainConnectRequest, &_gatekeeper, "processConnectRequestPacket"); - packetReceiver.registerListener(PacketType::ICEPing, &_gatekeeper, "processICEPingPacket"); - packetReceiver.registerListener(PacketType::ICEPingReply, &_gatekeeper, "processICEPingReplyPacket"); - packetReceiver.registerListener(PacketType::ICEServerPeerInformation, &_gatekeeper, "processICEPeerInformationPacket"); + packetReceiver.registerListener(PacketType::DomainConnectRequest, + PacketReceiver::makeUnsourcedListenerReference(&_gatekeeper, &DomainGatekeeper::processConnectRequestPacket)); + packetReceiver.registerListener(PacketType::ICEPing, + PacketReceiver::makeUnsourcedListenerReference(&_gatekeeper, &DomainGatekeeper::processICEPingPacket)); + packetReceiver.registerListener(PacketType::ICEPingReply, + PacketReceiver::makeUnsourcedListenerReference(&_gatekeeper, &DomainGatekeeper::processICEPingReplyPacket)); + packetReceiver.registerListener(PacketType::ICEServerPeerInformation, + PacketReceiver::makeUnsourcedListenerReference(&_gatekeeper, &DomainGatekeeper::processICEPeerInformationPacket)); - packetReceiver.registerListener(PacketType::ICEServerHeartbeatDenied, this, "processICEServerHeartbeatDenialPacket"); - packetReceiver.registerListener(PacketType::ICEServerHeartbeatACK, this, "processICEServerHeartbeatACK"); + packetReceiver.registerListener(PacketType::ICEServerHeartbeatDenied, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processICEServerHeartbeatDenialPacket)); + packetReceiver.registerListener(PacketType::ICEServerHeartbeatACK, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processICEServerHeartbeatACK)); - packetReceiver.registerListener(PacketType::OctreeDataFileRequest, this, "processOctreeDataRequestMessage"); - packetReceiver.registerListener(PacketType::OctreeDataPersist, this, "processOctreeDataPersistMessage"); + packetReceiver.registerListener(PacketType::OctreeDataFileRequest, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processOctreeDataRequestMessage)); + packetReceiver.registerListener(PacketType::OctreeDataPersist, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processOctreeDataPersistMessage)); - packetReceiver.registerListener(PacketType::OctreeFileReplacement, this, "handleOctreeFileReplacementRequest"); - packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl, this, "handleDomainContentReplacementFromURLRequest"); + packetReceiver.registerListener(PacketType::OctreeFileReplacement, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::handleOctreeFileReplacementRequest)); + packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::handleDomainContentReplacementFromURLRequest)); // set a custom packetVersionMatch as the verify packet operator for the udt::Socket nodeList->setPacketFilterOperator(&DomainServer::isPacketVerified); diff --git a/domain-server/src/DomainServerSettingsManager.h b/domain-server/src/DomainServerSettingsManager.h index 294e441ba4..d0c7812a99 100644 --- a/domain-server/src/DomainServerSettingsManager.h +++ b/domain-server/src/DomainServerSettingsManager.h @@ -211,6 +211,8 @@ private: /// guard read/write access from multiple threads to settings QReadWriteLock _settingsLock { QReadWriteLock::Recursive }; + + friend class DomainServer; }; #endif // hifi_DomainServerSettingsManager_h diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index c449874117..95533b0fb9 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -288,8 +288,10 @@ Wallet::Wallet() { auto& packetReceiver = nodeList->getPacketReceiver(); _passphrase = new QString(""); - packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "handleChallengeOwnershipPacket"); - packetReceiver.registerListener(PacketType::ChallengeOwnershipRequest, this, "handleChallengeOwnershipPacket"); + packetReceiver.registerListener(PacketType::ChallengeOwnership, + PacketReceiver::makeSourcedListenerReference(this, &Wallet::handleChallengeOwnershipPacket)); + packetReceiver.registerListener(PacketType::ChallengeOwnershipRequest, + PacketReceiver::makeSourcedListenerReference(this, &Wallet::handleChallengeOwnershipPacket)); connect(ledger.data(), &Ledger::accountResult, this, [](QJsonObject result) { auto wallet = DependencyManager::get(); diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index bc3c1afdd5..c2823e364f 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -25,7 +25,8 @@ OctreePacketProcessor::OctreePacketProcessor(): auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); const PacketReceiver::PacketTypeList octreePackets = { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase, PacketType::EntityQueryInitialResultsComplete }; - packetReceiver.registerDirectListenerForTypes(octreePackets, this, "handleOctreePacket"); + packetReceiver.registerDirectListenerForTypes(octreePackets, + PacketReceiver::makeSourcedListenerReference(this, &OctreePacketProcessor::handleOctreePacket)); } OctreePacketProcessor::~OctreePacketProcessor() { } diff --git a/interface/src/scripting/ScreenshareScriptingInterface.cpp b/interface/src/scripting/ScreenshareScriptingInterface.cpp index 3bf8336fe4..54f3e195ee 100644 --- a/interface/src/scripting/ScreenshareScriptingInterface.cpp +++ b/interface/src/scripting/ScreenshareScriptingInterface.cpp @@ -42,7 +42,8 @@ ScreenshareScriptingInterface::ScreenshareScriptingInterface() { // This packet listener handles the packet containing information about the latest zone ID in which we are allowed to share. auto nodeList = DependencyManager::get(); PacketReceiver& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AvatarZonePresence, this, "processAvatarZonePresencePacketOnClient"); + packetReceiver.registerListener(PacketType::AvatarZonePresence, + PacketReceiver::makeUnsourcedListenerReference(this, &ScreenshareScriptingInterface::processAvatarZonePresencePacketOnClient)); }; ScreenshareScriptingInterface::~ScreenshareScriptingInterface() { diff --git a/interface/src/ui/DomainConnectionModel.cpp b/interface/src/ui/DomainConnectionModel.cpp index 83aa18420c..596662a664 100644 --- a/interface/src/ui/DomainConnectionModel.cpp +++ b/interface/src/ui/DomainConnectionModel.cpp @@ -9,7 +9,8 @@ // #include "DomainConnectionModel.h" -#include +#include +#include #include #include diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 0f1c8978f0..807eed89ba 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -81,7 +81,8 @@ ContextOverlayInterface::ContextOverlayInterface() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::ChallengeOwnershipReply, this, "handleChallengeOwnershipReplyPacket"); + packetReceiver.registerListener(PacketType::ChallengeOwnershipReply, + PacketReceiver::makeSourcedListenerReference(this, &ContextOverlayInterface::handleChallengeOwnershipReplyPacket)); _challengeOwnershipTimeoutTimer.setSingleShot(true); } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 4e8c88560b..5a255ffb82 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -369,13 +369,20 @@ AudioClient::AudioClient() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AudioStreamStats, &_stats, "processStreamStatsPacket"); - packetReceiver.registerListener(PacketType::AudioEnvironment, this, "handleAudioEnvironmentDataPacket"); - packetReceiver.registerListener(PacketType::SilentAudioFrame, this, "handleAudioDataPacket"); - packetReceiver.registerListener(PacketType::MixedAudio, this, "handleAudioDataPacket"); - packetReceiver.registerListener(PacketType::NoisyMute, this, "handleNoisyMutePacket"); - packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); - packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); + packetReceiver.registerListener(PacketType::AudioStreamStats, + PacketReceiver::makeSourcedListenerReference(&_stats, &AudioIOStats::processStreamStatsPacket)); + packetReceiver.registerListener(PacketType::AudioEnvironment, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleAudioEnvironmentDataPacket)); + packetReceiver.registerListener(PacketType::SilentAudioFrame, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleAudioDataPacket)); + packetReceiver.registerListener(PacketType::MixedAudio, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleAudioDataPacket)); + packetReceiver.registerListener(PacketType::NoisyMute, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleNoisyMutePacket)); + packetReceiver.registerListener(PacketType::MuteEnvironment, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleMuteEnvironmentPacket)); + packetReceiver.registerListener(PacketType::SelectedAudioFormat, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleSelectedAudioFormat)); auto& domainHandler = nodeList->getDomainHandler(); connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index d0b315b524..7ed93f346d 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -123,10 +123,14 @@ AvatarHashMap::AvatarHashMap() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket"); - packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar"); - packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket"); - packetReceiver.registerListener(PacketType::BulkAvatarTraits, this, "processBulkAvatarTraits"); + packetReceiver.registerListener(PacketType::BulkAvatarData, + PacketReceiver::makeSourcedListenerReference(this, &AvatarHashMap::processAvatarDataPacket)); + packetReceiver.registerListener(PacketType::KillAvatar, + PacketReceiver::makeSourcedListenerReference(this, &AvatarHashMap::processKillAvatar)); + packetReceiver.registerListener(PacketType::AvatarIdentity, + PacketReceiver::makeSourcedListenerReference(this, &AvatarHashMap::processAvatarIdentityPacket)); + packetReceiver.registerListener(PacketType::BulkAvatarTraits, + PacketReceiver::makeSourcedListenerReference(this, &AvatarHashMap::processBulkAvatarTraits)); connect(nodeList.data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); diff --git a/libraries/avatars/src/ClientTraitsHandler.cpp b/libraries/avatars/src/ClientTraitsHandler.cpp index e133f178df..c2576bea2e 100644 --- a/libraries/avatars/src/ClientTraitsHandler.cpp +++ b/libraries/avatars/src/ClientTraitsHandler.cpp @@ -28,7 +28,8 @@ ClientTraitsHandler::ClientTraitsHandler(AvatarData* owningAvatar) : } }); - nodeList->getPacketReceiver().registerListener(PacketType::SetAvatarTraits, this, "processTraitOverride"); + nodeList->getPacketReceiver().registerListener(PacketType::SetAvatarTraits, + PacketReceiver::makeSourcedListenerReference(this, &ClientTraitsHandler::processTraitOverride)); } void ClientTraitsHandler::markTraitUpdated(AvatarTraits::TraitType updatedTrait) { diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index aaaf7d645a..3da019ce06 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -26,7 +26,8 @@ EntityEditPacketSender::EntityEditPacketSender() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerDirectListener(PacketType::EntityEditNack, this, "processEntityEditNackPacket"); + packetReceiver.registerDirectListener(PacketType::EntityEditNack, + PacketReceiver::makeSourcedListenerReference(this, &EntityEditPacketSender::processEntityEditNackPacket)); } void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer message, SharedNodePointer sendingNode) { diff --git a/libraries/entities/src/EntityScriptServerLogClient.cpp b/libraries/entities/src/EntityScriptServerLogClient.cpp index 5853c9585e..5d7d4017cd 100644 --- a/libraries/entities/src/EntityScriptServerLogClient.cpp +++ b/libraries/entities/src/EntityScriptServerLogClient.cpp @@ -14,7 +14,8 @@ EntityScriptServerLogClient::EntityScriptServerLogClient() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket"); + packetReceiver.registerListener(PacketType::EntityServerScriptLog, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServerLogClient::handleEntityServerScriptLogPacket)); QObject::connect(nodeList.data(), &NodeList::nodeActivated, this, &EntityScriptServerLogClient::nodeActivated); QObject::connect(nodeList.data(), &NodeList::nodeKilled, this, &EntityScriptServerLogClient::nodeKilled); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index fd83c99ca5..05947551ba 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -59,7 +59,8 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership connect(nodeList.data(), &NodeList::canGetAndSetPrivateUserDataChanged, this, &EntityScriptingInterface::canGetAndSetPrivateUserDataChanged); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket"); + packetReceiver.registerListener(PacketType::EntityScriptCallMethod, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptingInterface::handleEntityScriptCallMethodPacket)); } void EntityScriptingInterface::queueEntityMessage(PacketType packetType, diff --git a/libraries/networking/src/AssetClient.cpp b/libraries/networking/src/AssetClient.cpp index 44f42caec2..bbd743cf95 100644 --- a/libraries/networking/src/AssetClient.cpp +++ b/libraries/networking/src/AssetClient.cpp @@ -43,10 +43,14 @@ AssetClient::AssetClient() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AssetMappingOperationReply, this, "handleAssetMappingOperationReply"); - packetReceiver.registerListener(PacketType::AssetGetInfoReply, this, "handleAssetGetInfoReply"); - packetReceiver.registerListener(PacketType::AssetGetReply, this, "handleAssetGetReply", true); - packetReceiver.registerListener(PacketType::AssetUploadReply, this, "handleAssetUploadReply"); + packetReceiver.registerListener(PacketType::AssetMappingOperationReply, + PacketReceiver::makeSourcedListenerReference(this, &AssetClient::handleAssetMappingOperationReply)); + packetReceiver.registerListener(PacketType::AssetGetInfoReply, + PacketReceiver::makeSourcedListenerReference(this, &AssetClient::handleAssetGetInfoReply)); + packetReceiver.registerListener(PacketType::AssetGetReply, + PacketReceiver::makeSourcedListenerReference(this, &AssetClient::handleAssetGetReply), true); + packetReceiver.registerListener(PacketType::AssetUploadReply, + PacketReceiver::makeSourcedListenerReference(this, &AssetClient::handleAssetUploadReply)); connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &AssetClient::handleNodeKilled); connect(nodeList.data(), &LimitedNodeList::clientConnectionToNodeReset, diff --git a/libraries/networking/src/EntityScriptClient.cpp b/libraries/networking/src/EntityScriptClient.cpp index 1eab5bf2d7..fb98e8042b 100644 --- a/libraries/networking/src/EntityScriptClient.cpp +++ b/libraries/networking/src/EntityScriptClient.cpp @@ -34,7 +34,8 @@ EntityScriptClient::EntityScriptClient() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::EntityScriptGetStatusReply, this, "handleGetScriptStatusReply"); + packetReceiver.registerListener(PacketType::EntityScriptGetStatusReply, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptClient::handleGetScriptStatusReply)); connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &EntityScriptClient::handleNodeKilled); connect(nodeList.data(), &LimitedNodeList::clientConnectionToNodeReset, diff --git a/libraries/networking/src/MessagesClient.cpp b/libraries/networking/src/MessagesClient.cpp index d6f9d041ea..c883935cb4 100644 --- a/libraries/networking/src/MessagesClient.cpp +++ b/libraries/networking/src/MessagesClient.cpp @@ -28,7 +28,8 @@ MessagesClient::MessagesClient() { }); auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::MessagesData, this, "handleMessagesPacket"); + packetReceiver.registerListener(PacketType::MessagesData, + PacketReceiver::makeSourcedListenerReference(this, &MessagesClient::handleMessagesPacket)); connect(nodeList.data(), &LimitedNodeList::nodeActivated, this, &MessagesClient::handleNodeActivated); } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index e02a8dd56e..076e94522f 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -139,20 +139,34 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) startSTUNPublicSocketUpdate(); auto& packetReceiver = getPacketReceiver(); - packetReceiver.registerListener(PacketType::DomainList, this, "processDomainServerList"); - packetReceiver.registerListener(PacketType::Ping, this, "processPingPacket"); - packetReceiver.registerListener(PacketType::PingReply, this, "processPingReplyPacket"); - packetReceiver.registerListener(PacketType::ICEPing, this, "processICEPingPacket"); - packetReceiver.registerListener(PacketType::DomainServerAddedNode, this, "processDomainServerAddedNode"); - packetReceiver.registerListener(PacketType::DomainServerConnectionToken, this, "processDomainServerConnectionTokenPacket"); - packetReceiver.registerListener(PacketType::DomainConnectionDenied, &_domainHandler, "processDomainServerConnectionDeniedPacket"); - packetReceiver.registerListener(PacketType::DomainSettings, &_domainHandler, "processSettingsPacketList"); - packetReceiver.registerListener(PacketType::ICEServerPeerInformation, &_domainHandler, "processICEResponsePacket"); - packetReceiver.registerListener(PacketType::DomainServerRequireDTLS, &_domainHandler, "processDTLSRequirementPacket"); - packetReceiver.registerListener(PacketType::ICEPingReply, &_domainHandler, "processICEPingReplyPacket"); - packetReceiver.registerListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathResponse"); - packetReceiver.registerListener(PacketType::DomainServerRemovedNode, this, "processDomainServerRemovedNode"); - packetReceiver.registerListener(PacketType::UsernameFromIDReply, this, "processUsernameFromIDReply"); + packetReceiver.registerListener(PacketType::DomainList, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerList)); + packetReceiver.registerListener(PacketType::Ping, + PacketReceiver::makeSourcedListenerReference(this, &NodeList::processPingPacket)); + packetReceiver.registerListener(PacketType::PingReply, + PacketReceiver::makeSourcedListenerReference(this, &NodeList::processPingReplyPacket)); + packetReceiver.registerListener(PacketType::ICEPing, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processICEPingPacket)); + packetReceiver.registerListener(PacketType::DomainServerAddedNode, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerAddedNode)); + packetReceiver.registerListener(PacketType::DomainServerConnectionToken, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerConnectionTokenPacket)); + packetReceiver.registerListener(PacketType::DomainConnectionDenied, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processDomainServerConnectionDeniedPacket)); + packetReceiver.registerListener(PacketType::DomainSettings, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processSettingsPacketList)); + packetReceiver.registerListener(PacketType::ICEServerPeerInformation, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processICEResponsePacket)); + packetReceiver.registerListener(PacketType::DomainServerRequireDTLS, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processDTLSRequirementPacket)); + packetReceiver.registerListener(PacketType::ICEPingReply, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processICEPingReplyPacket)); + packetReceiver.registerListener(PacketType::DomainServerPathResponse, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerPathResponse)); + packetReceiver.registerListener(PacketType::DomainServerRemovedNode, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerRemovedNode)); + packetReceiver.registerListener(PacketType::UsernameFromIDReply, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processUsernameFromIDReply)); } qint64 NodeList::sendStats(QJsonObject statsObject, HifiSockAddr destination) { diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 962ceab00f..80222d38a9 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -12,7 +12,8 @@ #include "PacketReceiver.h" -#include +#include +#include #include "DependencyManager.h" #include "NetworkLogging.h" @@ -25,85 +26,56 @@ PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent) { qRegisterMetaType>(); } -bool PacketReceiver::registerListenerForTypes(PacketTypeList types, QObject* listener, const char* slot) { +bool PacketReceiver::ListenerReference::invokeWithQt(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) { + return QMetaObject::invokeMethod(getObject(), [=]() { + this->invokeDirectly(receivedMessagePointer, sourceNode); + }); +} + +bool PacketReceiver::registerListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener) { Q_ASSERT_X(!types.empty(), "PacketReceiver::registerListenerForTypes", "No types to register"); - Q_ASSERT_X(listener, "PacketReceiver::registerListenerForTypes", "No object to register"); - Q_ASSERT_X(slot, "PacketReceiver::registerListenerForTypes", "No slot to register"); + Q_ASSERT_X(listener, "PacketReceiver::registerListenerForTypes", "No listener to register"); - // Partition types based on whether they are sourced or not (non sourced in front) - auto middle = std::partition(std::begin(types), std::end(types), [](PacketType type) { - return PacketTypeEnum::getNonSourcedPackets().contains(type); - }); - - QMetaMethod nonSourcedMethod, sourcedMethod; - - // Check we have a valid method for non sourced types if any - if (middle != std::begin(types)) { - nonSourcedMethod = matchingMethodForListener(*std::begin(types), listener, slot); - if (!nonSourcedMethod.isValid()) { - return false; - } - } - - // Check we have a valid method for sourced types if any - if (middle != std::end(types)) { - sourcedMethod = matchingMethodForListener(*middle, listener, slot); - if (!sourcedMethod.isValid()) { - return false; - } - } - - // Register non sourced types - std::for_each(std::begin(types), middle, [this, &listener, &nonSourcedMethod](PacketType type) { - registerVerifiedListener(type, listener, nonSourcedMethod); - }); - - // Register sourced types - std::for_each(middle, std::end(types), [this, &listener, &sourcedMethod](PacketType type) { - registerVerifiedListener(type, listener, sourcedMethod); + std::for_each(std::begin(types), std::end(types), [this, &listener](PacketType type) { + registerVerifiedListener(type, listener); }); return true; } -void PacketReceiver::registerDirectListener(PacketType type, QObject* listener, const char* slot) { - Q_ASSERT_X(listener, "PacketReceiver::registerDirectListener", "No object to register"); - Q_ASSERT_X(slot, "PacketReceiver::registerDirectListener", "No slot to register"); +void PacketReceiver::registerDirectListener(PacketType type, const ListenerReferencePointer& listener) { + Q_ASSERT_X(listener, "PacketReceiver::registerDirectListener", "No listener to register"); - bool success = registerListener(type, listener, slot); + bool success = registerListener(type, listener); if (success) { QMutexLocker locker(&_directConnectSetMutex); // if we successfully registered, add this object to the set of objects that are directly connected - _directlyConnectedObjects.insert(listener); + _directlyConnectedObjects.insert(listener->getObject()); } } -void PacketReceiver::registerDirectListenerForTypes(PacketTypeList types, - QObject* listener, const char* slot) { - Q_ASSERT_X(listener, "PacketReceiver::registerDirectListenerForTypes", "No object to register"); - Q_ASSERT_X(slot, "PacketReceiver::registerDirectListenerForTypes", "No slot to register"); +void PacketReceiver::registerDirectListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener) { + Q_ASSERT_X(listener, "PacketReceiver::registerDirectListenerForTypes", "No listener to register"); // just call register listener for types to start - bool success = registerListenerForTypes(std::move(types), listener, slot); + bool success = registerListenerForTypes(std::move(types), listener); if (success) { QMutexLocker locker(&_directConnectSetMutex); // if we successfully registered, add this object to the set of objects that are directly connected - _directlyConnectedObjects.insert(listener); + _directlyConnectedObjects.insert(listener->getObject()); } } -bool PacketReceiver::registerListener(PacketType type, QObject* listener, const char* slot, - bool deliverPending) { - Q_ASSERT_X(listener, "PacketReceiver::registerListener", "No object to register"); - Q_ASSERT_X(slot, "PacketReceiver::registerListener", "No slot to register"); +bool PacketReceiver::registerListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending) { + Q_ASSERT_X(listener, "PacketReceiver::registerListener", "No listener to register"); - QMetaMethod matchingMethod = matchingMethodForListener(type, listener, slot); + bool matchingMethod = matchingMethodForListener(type, listener); - if (matchingMethod.isValid()) { + if (matchingMethod) { qCDebug(networking) << "Registering a packet listener for packet list type" << type; - registerVerifiedListener(type, listener, matchingMethod, deliverPending); + registerVerifiedListener(type, listener, deliverPending); return true; } else { qCWarning(networking) << "FAILED to Register a packet listener for packet list type" << type; @@ -111,62 +83,23 @@ bool PacketReceiver::registerListener(PacketType type, QObject* listener, const } } -QMetaMethod PacketReceiver::matchingMethodForListener(PacketType type, QObject* object, const char* slot) const { - Q_ASSERT_X(object, "PacketReceiver::matchingMethodForListener", "No object to call"); - Q_ASSERT_X(slot, "PacketReceiver::matchingMethodForListener", "No slot to call"); +bool PacketReceiver::matchingMethodForListener(PacketType type, const ListenerReferencePointer& listener) const { + Q_ASSERT_X(listener, "PacketReceiver::matchingMethodForListener", "No listener to call"); - // normalize the slot with the expected parameters - static const QString SIGNATURE_TEMPLATE("%1(%2)"); - static const QString NON_SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer"; + bool isSourced = listener->isSourced(); + bool isNonSourcedPacket = PacketTypeEnum::getNonSourcedPackets().contains(type); - QSet possibleSignatures { - SIGNATURE_TEMPLATE.arg(slot, NON_SOURCED_MESSAGE_LISTENER_PARAMETERS) - }; - - if (!PacketTypeEnum::getNonSourcedPackets().contains(type)) { - static const QString SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer,QSharedPointer"; - static const QString TYPEDEF_SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer,SharedNodePointer"; - - // a sourced packet must take the shared pointer to the ReceivedMessage but optionally could include - // a shared pointer to the node - possibleSignatures << SIGNATURE_TEMPLATE.arg(slot, TYPEDEF_SOURCED_MESSAGE_LISTENER_PARAMETERS); - possibleSignatures << SIGNATURE_TEMPLATE.arg(slot, SOURCED_MESSAGE_LISTENER_PARAMETERS); + assert(!isSourced || !isNonSourcedPacket); + if (isSourced && isNonSourcedPacket) { + qCDebug(networking) << "PacketReceiver::registerListener cannot support a sourced listener for type" << type; + return false; } - int methodIndex = -1; - - foreach(const QString& signature, possibleSignatures) { - QByteArray normalizedSlot = - QMetaObject::normalizedSignature(signature.toStdString().c_str()); - - // does the constructed normalized method exist? - methodIndex = object->metaObject()->indexOfSlot(normalizedSlot.toStdString().c_str()); - - if (methodIndex >= 0) { - break; - } - } - - if (methodIndex < 0) { - qCDebug(networking) << "PacketReceiver::registerListener expected a slot with one of the following signatures:" - << possibleSignatures.toList() << "- but such a slot was not found." - << "Could not complete listener registration for type" << type; - } - - Q_ASSERT(methodIndex >= 0); - - // return the converted QMetaMethod - if (methodIndex >= 0) { - return object->metaObject()->method(methodIndex); - } else { - // if somehow (scripting?) something bad gets in here at runtime that doesn't hit the asserts above - // return a non-valid QMetaMethod - return QMetaMethod(); - } + return true; } -void PacketReceiver::registerVerifiedListener(PacketType type, QObject* object, const QMetaMethod& slot, bool deliverPending) { - Q_ASSERT_X(object, "PacketReceiver::registerVerifiedListener", "No object to register"); +void PacketReceiver::registerVerifiedListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending) { + Q_ASSERT_X(listener, "PacketReceiver::registerVerifiedListener", "No listener to register"); QMutexLocker locker(&_packetListenerLock); if (_messageListenerMap.contains(type)) { @@ -175,7 +108,7 @@ void PacketReceiver::registerVerifiedListener(PacketType type, QObject* object, } // add the mapping - _messageListenerMap[type] = { QPointer(object), slot, deliverPending }; + _messageListenerMap[type] = { listener, deliverPending }; } void PacketReceiver::unregisterListener(QObject* listener) { @@ -188,7 +121,7 @@ void PacketReceiver::unregisterListener(QObject* listener) { auto it = _messageListenerMap.begin(); while (it != _messageListenerMap.end()) { - if (it.value().object == listener) { + if (it.value().listener->getObject() == listener) { it = _messageListenerMap.erase(it); } else { ++it; @@ -261,7 +194,7 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei QMutexLocker packetListenerLocker(&_packetListenerLock); auto it = _messageListenerMap.find(receivedMessage->getType()); - if (it != _messageListenerMap.end() && it->method.isValid()) { + if (it != _messageListenerMap.end() && !it->listener.isNull()) { auto listener = it.value(); @@ -271,36 +204,19 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei bool success = false; - Qt::ConnectionType connectionType; + bool isDirectConnect = false; // check if this is a directly connected listener { QMutexLocker directConnectLocker(&_directConnectSetMutex); - connectionType = _directlyConnectedObjects.contains(listener.object) ? Qt::DirectConnection : Qt::AutoConnection; + isDirectConnect = _directlyConnectedObjects.contains(listener.listener->getObject()); } - QMetaMethod metaMethod = listener.method; - - static const QByteArray QSHAREDPOINTER_NODE_NORMALIZED = QMetaObject::normalizedType("QSharedPointer"); - static const QByteArray SHARED_NODE_NORMALIZED = QMetaObject::normalizedType("SharedNodePointer"); - // one final check on the QPointer before we go to invoke - if (listener.object) { - if (metaMethod.parameterTypes().contains(SHARED_NODE_NORMALIZED)) { - success = metaMethod.invoke(listener.object, - connectionType, - Q_ARG(QSharedPointer, receivedMessage), - Q_ARG(SharedNodePointer, matchingNode)); - - } else if (metaMethod.parameterTypes().contains(QSHAREDPOINTER_NODE_NORMALIZED)) { - success = metaMethod.invoke(listener.object, - connectionType, - Q_ARG(QSharedPointer, receivedMessage), - Q_ARG(QSharedPointer, matchingNode)); - + if (listener.listener->getObject()) { + if (isDirectConnect) { + success = listener.listener->invokeDirectly(receivedMessage, matchingNode); } else { - success = metaMethod.invoke(listener.object, - connectionType, - Q_ARG(QSharedPointer, receivedMessage)); + success = listener.listener->invokeWithQt(receivedMessage, matchingNode); } } else { qCDebug(networking).nospace() << "Listener for packet " << receivedMessage->getType() @@ -310,19 +226,19 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei // if it exists, remove the listener from _directlyConnectedObjects { QMutexLocker directConnectLocker(&_directConnectSetMutex); - _directlyConnectedObjects.remove(listener.object); + _directlyConnectedObjects.remove(listener.listener->getObject()); } } if (!success) { qCDebug(networking).nospace() << "Error delivering packet " << receivedMessage->getType() << " to listener " - << listener.object << "::" << qPrintable(listener.method.methodSignature()); + << listener.listener->getObject(); } } else if (it == _messageListenerMap.end()) { qCWarning(networking) << "No listener found for packet type" << receivedMessage->getType(); // insert a dummy listener so we don't print this again - _messageListenerMap.insert(receivedMessage->getType(), { nullptr, QMetaMethod(), false }); + _messageListenerMap.insert(receivedMessage->getType(), { ListenerReferencePointer(), false }); } } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index e29a0d6e5a..0bed88cff9 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -16,8 +16,6 @@ #include #include -#include -#include #include #include #include @@ -29,6 +27,7 @@ #include "udt/PacketHeaders.h" class EntityEditPacketSender; +class Node; class OctreePacketProcessor; namespace std { @@ -42,6 +41,22 @@ namespace std { class PacketReceiver : public QObject { Q_OBJECT +public: + class ListenerReference { + public: + virtual bool invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) = 0; + bool invokeWithQt(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode); + virtual bool isSourced() const = 0; + virtual QObject* getObject() const = 0; + }; + typedef QSharedPointer ListenerReferencePointer; + + template + static ListenerReferencePointer makeUnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer)); + + template + static ListenerReferencePointer makeSourcedListenerReference(T* target, void (T::*slot)(QSharedPointer, QSharedPointer)); + public: using PacketTypeList = std::vector; @@ -55,8 +70,8 @@ public: // If deliverPending is false, ReceivedMessage will only be delivered once all packets for the message have // been received. If deliverPending is true, ReceivedMessage will be delivered as soon as the first packet // for the message is received. - bool registerListener(PacketType type, QObject* listener, const char* slot, bool deliverPending = false); - bool registerListenerForTypes(PacketTypeList types, QObject* listener, const char* slot); + bool registerListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending = false); + bool registerListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener); void unregisterListener(QObject* listener); void handleVerifiedPacket(std::unique_ptr packet); @@ -64,9 +79,34 @@ public: void handleMessageFailure(HifiSockAddr from, udt::Packet::MessageNumber messageNumber); private: + template + class UnsourcedListenerReference : public ListenerReference { + public: + inline UnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer)); + virtual bool invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode); + virtual bool isSourced() const { return false; } + virtual QObject* getObject() const { return _target; } + + private: + QPointer _target; + void (T::*_slot)(QSharedPointer); + }; + + template + class SourcedListenerReference : public ListenerReference { + public: + inline SourcedListenerReference(T* target, void (T::*slot)(QSharedPointer, QSharedPointer)); + virtual bool invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode); + virtual bool isSourced() const { return true; } + virtual QObject* getObject() const { return _target; } + + private: + QPointer _target; + void (T::*_slot)(QSharedPointer, QSharedPointer); + }; + struct Listener { - QPointer object; - QMetaMethod method; + ListenerReferencePointer listener; bool deliverPending; }; @@ -74,11 +114,11 @@ private: // these are brutal hacks for now - ideally GenericThread / ReceivedPacketProcessor // should be changed to have a true event loop and be able to handle our QMetaMethod::invoke - void registerDirectListenerForTypes(PacketTypeList types, QObject* listener, const char* slot); - void registerDirectListener(PacketType type, QObject* listener, const char* slot); + void registerDirectListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener); + void registerDirectListener(PacketType type, const ListenerReferencePointer& listener); - QMetaMethod matchingMethodForListener(PacketType type, QObject* object, const char* slot) const; - void registerVerifiedListener(PacketType type, QObject* listener, const QMetaMethod& slot, bool deliverPending = false); + bool matchingMethodForListener(PacketType type, const ListenerReferencePointer& listener) const; + void registerVerifiedListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending = false); QMutex _packetListenerLock; QHash _messageListenerMap; @@ -93,4 +133,42 @@ private: friend class OctreePacketProcessor; }; +template +PacketReceiver::ListenerReferencePointer PacketReceiver::makeUnsourcedListenerReference(T* target, void (T::* slot)(QSharedPointer)) { + return QSharedPointer>::create(target, slot); +} + +template +PacketReceiver::ListenerReferencePointer PacketReceiver::makeSourcedListenerReference(T* target, void (T::* slot)(QSharedPointer, QSharedPointer)) { + return QSharedPointer>::create(target, slot); +} + +template +PacketReceiver::UnsourcedListenerReference::UnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer)) : + _target(target),_slot(slot) { +} + +template +bool PacketReceiver::UnsourcedListenerReference::invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer&) { + if (_target.isNull()) { + return false; + } + (_target->*_slot)(receivedMessagePointer); + return true; +} + +template +PacketReceiver::SourcedListenerReference::SourcedListenerReference(T* target, void (T::*slot)(QSharedPointer, QSharedPointer)) : + _target(target),_slot(slot) { +} + +template +bool PacketReceiver::SourcedListenerReference::invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) { + if (_target.isNull()) { + return false; + } + (_target->*_slot)(receivedMessagePointer, sourceNode); + return true; +} + #endif // hifi_PacketReceiver_h diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 88a4f5bf32..4ba456d859 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -16,8 +16,9 @@ #include #include -#include -#include +#include +#include +#include #include #include diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index dd2cc12d50..c4f24c552b 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -64,7 +64,8 @@ void OctreePersistThread::start() { cleanupOldReplacementBackups(); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::OctreeDataFileReply, this, "handleOctreeDataFileReply"); + packetReceiver.registerListener(PacketType::OctreeDataFileReply, + PacketReceiver::makeUnsourcedListenerReference(this, &OctreePersistThread::handleOctreeDataFileReply)); auto nodeList = DependencyManager::get(); const DomainHandler& domainHandler = nodeList->getDomainHandler(); From 34e3d9dd2b9b96a8a809e87a4d70a542c8738d08 Mon Sep 17 00:00:00 2001 From: Heather Anderson Date: Sun, 9 Aug 2020 15:44:41 -0700 Subject: [PATCH 02/74] improved listener lifetime controls (in case a deferred invoke takes longer than expected) --- libraries/networking/src/PacketReceiver.cpp | 3 ++- libraries/networking/src/PacketReceiver.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 80222d38a9..c13fb8566b 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -27,8 +27,9 @@ PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent) { } bool PacketReceiver::ListenerReference::invokeWithQt(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) { + ListenerReferencePointer thisPointer = sharedFromThis(); return QMetaObject::invokeMethod(getObject(), [=]() { - this->invokeDirectly(receivedMessagePointer, sourceNode); + thisPointer->invokeDirectly(receivedMessagePointer, sourceNode); }); } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 0bed88cff9..071638cda9 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "NLPacket.h" #include "NLPacketList.h" @@ -42,7 +44,7 @@ namespace std { class PacketReceiver : public QObject { Q_OBJECT public: - class ListenerReference { + class ListenerReference : public QEnableSharedFromThis { public: virtual bool invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) = 0; bool invokeWithQt(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode); From 9395caa7d0f812a1fabb3b4bdb8da9d1b5900f9c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2020 09:01:27 +1200 Subject: [PATCH 03/74] Rework GitHub Actions builds for merges to master --- .github/workflows/master_build.yml | 308 +++++++++++++---------------- tools/ci-scripts/upload.py | 3 +- 2 files changed, 137 insertions(+), 174 deletions(-) diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index 9ef4728cb0..824c279845 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -3,114 +3,60 @@ name: Master CI Build on: push: branches: - - master + - gha-master-ci +# FIXME: Change target branch to "master" before merging into "master" branch. env: - #APP_NAME: gpu-frame-player APP_NAME: interface BUILD_TYPE: Release - BUCKET_NAME: hifi-gh-builds + BUILD_NUMBER: ${{ github.run_number }} CI_BUILD: Github - CMAKE_BACKTRACE_URL: https://highfidelity.sp.backtrace.io:6098 - CMAKE_BACKTRACE_TOKEN: ${{ secrets.backtrace_token }} - CMAKE_BACKTRACE_SYMBOLS_TOKEN: ${{ secrets.backtrace_symbols_token }} GIT_COMMIT: ${{ github.sha }} - HIFI_VCPKG_BOOTSTRAP: true - LAUNCHER_HMAC_SECRET: ${{ secrets.launcher_hmac_secret }} - OCULUS_APP_ID: '${{ secrets.oculus_app_id }}' + # VCPKG did not build well on OSX disabling HIFI_VCPKG_BOOTSTRAP, which invokes a download to a working version of vcpkg + # HIFI_VCPKG_BOOTSTRAP: true RELEASE_TYPE: PRODUCTION - RELEASE_DYNAMODB_V2: ReleaseManager2-ReleaseQueue-prod + RELEASE_NUMBER: ${{ github.run_number }} STABLE_BUILD: 0 + UPLOAD_BUCKET: athena-public - - # OSX specific variables + # OSX-specific variables DEVELOPER_DIR: /Applications/Xcode_11.2.app/Contents/Developer MACOSX_DEPLOYMENT_TARGET: '10.11' - # WIN32 specific variables + # WIN-specific variables PreferredToolArchitecture: X64 -# Mac OS -#PLATFORM_CMAKE_GENERATOR=Xcode -#PLATFORM_BUILD_ARGUMENTS=--config Release --target package -#ARTIFACT_EXPRESSION=build/*.dmg,build/*.zip - -# Windows -#PLATFORM_CMAKE_GENERATOR=Visual Studio 15 2017 Win64 -#PLATFORM_BUILD_ARGUMENTS=--target package --config release -#ARTIFACT_EXPRESSION=build/*.exe,build/*.zip,*-symbols.zip - -# Ubuntu -#PLATFORM_CMAKE_GENERATOR=Unix Makefiles -#PLATFORM_BUILD_ARGUMENTS=--target all -- -j4 -#ARTIFACT_EXPRESSION=build/assignment-client/**,build/domain-server/**,build/ice-server/ice-server,build/tools/ice-client/ice-client,build/tools/ac-client/ac-client,build/tools/oven,build/ext/makefiles/nvtt/project/lib/**,build/ext/makefiles/quazip/project/lib/** - -# Android -# branch: master -# GA_TRACKING_ID: ${{ secrets.ga_tracking_id }} -# ANDROID_OAUTH_CLIENT_SECRET=${MASKED_ANDROID_OAUTH_CLIENT_SECRET_NIGHTLY} -# ANDROID_OAUTH_CLIENT_ID=6c7d2349c0614640150db37457a1f75dce98a28ffe8f14d47f6cfae4de5b262a -# ANDROID_OAUTH_REDIRECT_URI=https://dev-android-interface.highfidelity.com/auth -# branch: !master -# GA_TRACKING_ID=UA-39558647-11 -# ANDROID_OAUTH_CLIENT_SECRET=${MASKED_ANDROID_OAUTH_CLIENT_SECRET_RELEASE} -# ANDROID_OAUTH_CLIENT_ID= c1063ea5d0b0c405e0c9cd77351328e211a91496a3f25985a99e861f1661db1d -# ANDROID_OAUTH_REDIRECT_URI=https://android-interface.highfidelity.com/auth -# ARTIFACT_EXPRESSION=android/*.apk -# ANDROID_APK_NAME=HighFidelity-Beta-PR${RELEASE_NUMBER}-${GIT_COMMIT_SHORT}.apk -# ANDROID_BUILT_APK_NAME=interface-debug.apk -# ANDROID_APP=interface -# ANDROID_BUILD_DIR=debug -# ANDROID_BUILD_TARGET=assembleDebug -# STABLE_BUILD=0 - - - jobs: - generate_build_number: - runs-on: ubuntu-latest - steps: - - name: Generate build number - id: buildnumber - uses: highfidelity/build-number@v3 - with: - token: ${{secrets.github_token}} - - name: Upload build number - uses: actions/upload-artifact@v1 - with: - name: BUILD_NUMBER - path: BUILD_NUMBER - build: strategy: matrix: - os: [windows-latest, macOS-latest] - build_type: [full, client] - #os: [windows-latest, macOS-latest, ubuntu-latest] - # exclude: - # - os: ubuntu-latest - # build_type: client + os: [windows-latest, macOS-latest, ubuntu-18.04] + # build_type: [full, client] + build_type: [full] + include: + - os: ubuntu-18.04 + build_type: full + apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0 + fail-fast: false runs-on: ${{matrix.os}} - needs: generate_build_number steps: - - name: Download build number - uses: actions/download-artifact@v1 - with: - name: BUILD_NUMBER - - name: Restore build number - id: buildnumber - uses: highfidelity/build-number@v3 - with: - output_name: RELEASE_NUMBER - - name: Configure Build Environment 1 + - name: Report Build Number + shell: bash + run: | + echo "Build number: $BUILD_NUMBER" + - name: Configure build environment 1 shell: bash id: buildenv1 run: | echo ::set-env name=UPLOAD_PREFIX::master echo ::set-env name=GIT_COMMIT_SHORT::`echo $GIT_COMMIT | cut -c1-7` + echo ::set-env name=JOB_NAME::"build (${{matrix.os}}, ${{matrix.build_type}})" # Linux build variables - if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then + if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then + echo ::set-env name=PYTHON_EXEC::python3 echo ::set-env name=INSTALLER_EXT::tgz + echo ::set-env name=CMAKE_BUILD_EXTRA::"-- -j3" + echo ::set-env name=CMAKE_EXTRA::"-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" fi # Mac build variables if [ "${{ matrix.os }}" = "macOS-latest" ]; then @@ -118,8 +64,8 @@ jobs: echo ::set-env name=ZIP_COMMAND::zip echo ::set-env name=ZIP_ARGS::-r echo ::set-env name=INSTALLER_EXT::dmg - echo ::set-env name=SYMBOL_REGEX::dSYM - echo "::set-output name=symbols_archive::${{ steps.buildnumber.outputs.build_number }}-${{ matrix.build_type }}-mac-symbols.zip" + echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" + echo "::set-output name=symbols_archive::${BUILD_NUMBER}-${{ matrix.build_type }}-mac-symbols.zip" fi # Windows build variables if [ "${{ matrix.os }}" = "windows-latest" ]; then @@ -127,40 +73,28 @@ jobs: echo ::set-env name=ZIP_COMMAND::7z echo ::set-env name=ZIP_ARGS::a echo ::set-env name=INSTALLER_EXT::exe + echo ::set-env name=CMAKE_EXTRA::"-A x64" echo "::set-env name=SYMBOL_REGEX::\(exe\|dll\|pdb\)" - echo "::set-output name=symbols_archive::${{ steps.buildnumber.outputs.build_number }}-${{ matrix.build_type }}-win-symbols.zip" + echo "::set-output name=symbols_archive::${BUILD_NUMBER}-${{ matrix.build_type }}-win-symbols.zip" + # echo ::set-env name=HF_PFX_PASSPHRASE::${{secrets.pfx_key}} + # echo "::set-env name=HF_PFX_FILE::${{runner.workspace}}\build\codesign.pfx" fi # Configuration is broken into two steps because you can't set an env var and also reference it in the same step - - name: Configure Build Environment 2 + - name: Configure build environment 2 shell: bash run: | echo "${{ steps.buildenv1.outputs.symbols_archive }}" - echo ::set-env name=ARTIFACT_PATTERN::HighFidelity-Beta-*.$INSTALLER_EXT + echo ::set-env name=ARTIFACT_PATTERN::Vircadia-Alpha-*.$INSTALLER_EXT # Build type variables if [ "${{ matrix.build_type }}" = "full" ]; then echo ::set-env name=CLIENT_ONLY::FALSE - echo ::set-env name=INSTALLER::HighFidelity-Beta-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + echo ::set-env name=INSTALLER::Vircadia-Alpha-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT else echo ::set-env name=CLIENT_ONLY::TRUE - echo ::set-env name=INSTALLER::HighFidelity-Beta-Interface-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + echo ::set-env name=INSTALLER::Vircadia-Alpha-Interface-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT fi - # Linux build variables - if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then - echo ::set-env name=PYTHON_EXEC::python3 - echo ::set-env name=CMAKE_EXTRA::"" - fi - # Mac build variables - if [ "${{ matrix.os }}" = "macOS-latest" ]; then - echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" - fi - # Windows build variables - if [ "${{ matrix.os }}" = "windows-latest" ]; then - echo ::set-env name=CMAKE_EXTRA::"-A x64" - echo ::set-env name=HF_PFX_PASSPHRASE::${{secrets.pfx_key}} - echo "::set-env name=HF_PFX_FILE::${{runner.workspace}}\build\codesign.pfx" - fi - - name: Clear Working Directory - if: matrix.os == 'windows-latest' + - name: Clear working directory + if: startsWith(matrix.os, 'windows') shell: bash working-directory: ${{runner.workspace}} run: rm -rf ./* @@ -168,89 +102,119 @@ jobs: with: submodules: true fetch-depth: 1 - - name: Create Build Directory - run: cmake -E make_directory ${{runner.workspace}}/build - - name: Decrypt Signing Key (Windows) - if: matrix.os == 'windows-latest' - working-directory: ${{runner.workspace}}/build + - name: Install dependencies + if: startsWith(matrix.os, 'ubuntu') shell: bash - run: gpg --batch --yes -o codesign.pfx --passphrase "${{secrets.gpg_symmetric_key}}" --decrypt $GITHUB_WORKSPACE/tools/ci-scripts/codesign.pfx.gpg - - name: Import Signing Key (Windows) - if: matrix.os == 'windows-latest' - working-directory: ${{runner.workspace}}/build - shell: powershell - run: | - $mypwd=ConvertTo-SecureString -String ${{ secrets.pfx_key }} -Force -AsPlainText - Import-PfxCertificate -Password $mypwd -CertStoreLocation Cert:\CurrentUser\My -FilePath ${{runner.workspace}}\build\codesign.pfx - Import-PfxCertificate -Password $mypwd -CertStoreLocation Cert:\LocalMachine\My -FilePath ${{runner.workspace}}\build\codesign.pfx + run: | + echo "Installing Python Modules:" + pip3 install distro || exit 1 + echo "Updating apt repository index" + sudo apt update || exit 1 + echo "Installing apt packages" + sudo apt install -y ${{ matrix.apt-dependencies }} || exit 1 - name: Install Python modules - if: matrix.os != 'ubuntu-latest' + if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') shell: bash run: $PYTHON_EXEC -m pip install boto3 PyGithub + - name: Create build environment + shell: bash + run: cmake -E make_directory "${{runner.workspace}}/build" - name: Configure CMake working-directory: ${{runner.workspace}}/build shell: bash - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCLIENT_ONLY:BOOLEAN=$CLIENT_ONLY $CMAKE_EXTRA - - name: Build Application + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DVCPKG_BUILD_TYPE=release -DCLIENT_ONLY:BOOLEAN=$CLIENT_ONLY -DBYPASS_SIGNING:BOOLEAN=TRUE $CMAKE_EXTRA + - name: Build application working-directory: ${{runner.workspace}}/build shell: bash - run: cmake --build . --config $BUILD_TYPE --target $APP_NAME - - name: Build Console + run: cmake --build . --config $BUILD_TYPE --target $APP_NAME $CMAKE_BUILD_EXTRA + - name: Build domain server working-directory: ${{runner.workspace}}/build shell: bash - run: cmake --build . --config $BUILD_TYPE --target packaged-server-console - - name: Build Domain Server (FullBuild) - if: matrix.build_type == 'full' - shell: bash - working-directory: ${{runner.workspace}}/build - run: cmake --build . --config $BUILD_TYPE --target domain-server - - name: Build Assignment Client (FullBuild) - if: matrix.build_type == 'full' - shell: bash - working-directory: ${{runner.workspace}}/build - run: cmake --build . --config $BUILD_TYPE --target assignment-client - - name: Build Installer + run: cmake --build . --config $BUILD_TYPE --target domain-server $CMAKE_BUILD_EXTRA + - name: Build assignment client working-directory: ${{runner.workspace}}/build shell: bash - run: cmake --build . --config $BUILD_TYPE --target package - - name: Sign Installer (Windows) - if: matrix.os == 'windows-latest' - shell: powershell - working-directory: C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64 - run: .\signtool.exe sign /fd sha256 /f ${{runner.workspace}}\build\codesign.pfx /p ${{secrets.pfx_key}} /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 ${{runner.workspace}}\build\${env:INSTALLER} - - name: Upload Artifact - if: matrix.os != 'ubuntu-latest' + run: cmake --build . --config $BUILD_TYPE --target assignment-client $CMAKE_BUILD_EXTRA + - name: Build console + working-directory: ${{runner.workspace}}/build + shell: bash + run: cmake --build . --config $BUILD_TYPE --target packaged-server-console $CMAKE_BUILD_EXTRA + - name: Build installer + working-directory: ${{runner.workspace}}/build + shell: bash + run: | + echo "Retry code from https://unix.stackexchange.com/a/137639" + function fail { + echo $1 >&2 + exit 1 + } + function retry { + local n=1 + local max=5 + local delay=15 + while true; do + "$@" && break || { + if [[ $n -lt $max ]]; then + ((n++)) + echo "Command failed. Attempt $n/$max:" + sleep $delay; + else + fail "The command has failed after $n attempts." + fi + } + done + } + retry cmake --build . --config $BUILD_TYPE --target package $CMAKE_BUILD_EXTRA + #- name: Sign installer (Windows) + # if: startsWith(matrix.os, 'windows') + # shell: powershell + # working-directory: C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64 + # run: .\signtool.exe sign /fd sha256 /f ${{runner.workspace}}\build\codesign.pfx /p ${{secrets.pfx_key}} /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 ${{runner.workspace}}\build\${env:INSTALLER} + - name: Output system stats + if: ${{ always() }} + working-directory: ${{runner.workspace}}/build + shell: bash + run: | + echo "Disk usage:" + df -h + - name: Output installer logs + if: failure() && startsWith(matrix.os, 'windows') + shell: bash + working-directory: ${{runner.workspace}}/build + run: cat ./_CPack_Packages/win64/NSIS/NSISOutput.log + - name: Upload artifact + if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') shell: bash working-directory: ${{runner.workspace}}/build env: AWS_ACCESS_KEY_ID: ${{ secrets.aws_access_key_id }} AWS_SECRET_ACCESS_KEY: ${{ secrets.aws_secret_access_key }} run: $PYTHON_EXEC $GITHUB_WORKSPACE/tools/ci-scripts/upload.py - - name: Archive Symbols - if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') - working-directory: ${{runner.workspace}} - shell: bash - run: | - SYMBOLS_TEMP="symbols-temp" - mkdir $SYMBOLS_TEMP - find "./build" \( -path '*/tools/gpu-frame-player/*' -or -path '*/interface/*' -or -path '*/plugins/*' \) -regex ".*\.$SYMBOL_REGEX" -exec cp -r {} $SYMBOLS_TEMP \; - cd $SYMBOLS_TEMP - $ZIP_COMMAND $ZIP_ARGS ../${{ steps.buildenv1.outputs.symbols_archive }} . - - name: Upload Symbols - if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') - working-directory: ${{runner.workspace}} - shell: bash - run: | - curl --data-binary @${{ steps.buildenv1.outputs.symbols_archive }} "$CMAKE_BACKTRACE_URL/post?format=symbols&token=$CMAKE_BACKTRACE_SYMBOLS_TOKEN&upload_file=${{steps.buildenv1.outputs.symbols_archive}}&tag=$RELEASE_NUMBER" - # - name: Debug List Symbols - # if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') - # working-directory: ${{runner.workspace}} - # shell: bash - # run: | - # unzip -v "${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}" - # - name: Debug Upload Symbols Artifact - # if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') - # uses: actions/upload-artifact@v1 - # with: - # name: symbols - # path: ${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }} + #- name: Archive symbols + # if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') + # working-directory: ${{runner.workspace}} + # shell: bash + # run: | + # SYMBOLS_TEMP="symbols-temp" + # mkdir $SYMBOLS_TEMP + # find "./build" \( -path '*/tools/gpu-frame-player/*' -or -path '*/interface/*' -or -path '*/plugins/*' \) -regex ".*\.$SYMBOL_REGEX" -exec cp -r {} $SYMBOLS_TEMP \; + # cd $SYMBOLS_TEMP + # $ZIP_COMMAND $ZIP_ARGS ../${{ steps.buildenv1.outputs.symbols_archive }} . + #- name: Upload symbols + # if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') + # working-directory: ${{runner.workspace}} + # shell: bash + # run: | + # curl --data-binary @${{ steps.buildenv1.outputs.symbols_archive }} "$CMAKE_BACKTRACE_URL/post?format=symbols&token=$CMAKE_BACKTRACE_SYMBOLS_TOKEN&upload_file=${{steps.buildenv1.outputs.symbols_archive}}&tag=$BUILD_NUMBER" + #- name: Debug list symbols + # if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') + # working-directory: ${{runner.workspace}} + # shell: bash + # run: | + # unzip -v "${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}" + #- name: Upload debug list symbols + # if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') + # uses: actions/upload-artifact@v1 + # with: + # name: symbols + # path: ${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }} diff --git a/tools/ci-scripts/upload.py b/tools/ci-scripts/upload.py index f43fbfd574..90d5d9be06 100644 --- a/tools/ci-scripts/upload.py +++ b/tools/ci-scripts/upload.py @@ -6,9 +6,8 @@ import boto3 import glob from github import Github - def main(): - bucket_name = os.environ['BUCKET_NAME'] + bucket_name = os.environ['UPLOAD_BUCKET'] upload_prefix = os.environ['UPLOAD_PREFIX'] release_number = os.environ['RELEASE_NUMBER'] full_prefix = upload_prefix + '/' + release_number[0:-2] + '/' + release_number From 0f1c5f895ffbfd978589868e4a44d1502f27b460 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2020 09:01:43 +1200 Subject: [PATCH 04/74] Fix bypassing signing installer --- cmake/templates/NSIS.template.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index f40141be32..2a8052e735 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -202,9 +202,9 @@ ; The Inner invocation has written an uninstaller binary for us. ; We need to sign it if it's a production or PR build. !if @PRODUCTION_BUILD@ == 1 - !if @BYPASS_SIGNING@ == 1 + !if @BYPASS_SIGNING@ == TRUE !warning "BYPASS_SIGNING set - installer will not be signed" - !else + !else !system '"@SIGNTOOL_EXECUTABLE@" sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://timestamp.comodoca.com?td=sha256 /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0 !endif !endif From 2ed37d0c4701e9ee842669b439be8a347ffe8e21 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2020 09:02:00 +1200 Subject: [PATCH 05/74] Fix upload target location and path --- tools/ci-scripts/upload.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ci-scripts/upload.py b/tools/ci-scripts/upload.py index 90d5d9be06..ab96e4ba24 100644 --- a/tools/ci-scripts/upload.py +++ b/tools/ci-scripts/upload.py @@ -10,14 +10,14 @@ def main(): bucket_name = os.environ['UPLOAD_BUCKET'] upload_prefix = os.environ['UPLOAD_PREFIX'] release_number = os.environ['RELEASE_NUMBER'] - full_prefix = upload_prefix + '/' + release_number[0:-2] + '/' + release_number + full_prefix = upload_prefix + '/' + release_number S3 = boto3.client('s3') path = os.path.join(os.getcwd(), os.environ['ARTIFACT_PATTERN']) files = glob.glob(path, recursive=False) for archiveFile in files: filePath, fileName = os.path.split(archiveFile) S3.upload_file(os.path.join(filePath, fileName), bucket_name, full_prefix + '/' + fileName) - print("Uploaded Artifact to S3: https://{}.s3-us-west-2.amazonaws.com/{}/{}".format(bucket_name, full_prefix, fileName)) + print("Uploaded Artifact to S3: https://{}.s3-eu-west-3.amazonaws.com/{}/{}".format(bucket_name, full_prefix, fileName)) print("Finished") main() From 2e75166e0de4c08c8b30a6463a3e62fa8c2c4365 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sun, 11 Oct 2020 21:10:24 -0400 Subject: [PATCH 06/74] Hide temp place name button, hide places table, hide places wizard step. --- domain-server/resources/web/settings/js/settings.js | 13 ++++++++----- domain-server/resources/web/wizard/index.shtml | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 8a9971d520..18d07fa6ef 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -40,6 +40,8 @@ $(document).ready(function(){ // call our method to setup the place names table setupPlacesTable(); + // hide the places table for now because we do not want that interacted with from the domain-server + $('#' + Settings.PLACES_TABLE_ID).hide(); setupDomainNetworkingSettings(); // setupDomainLabelSetting(); @@ -711,8 +713,8 @@ $(document).ready(function(){ name: 'places', label: 'Places', html_id: Settings.PLACES_TABLE_ID, - help: "The following places currently point to this domain.
To point places to this domain, " - + " go to the My Places " + help: "To point places to this domain, " + + " go to the Places " + "page in your Metaverse account.", read_only: true, can_add_new_rows: false, @@ -745,9 +747,10 @@ $(document).ready(function(){ var errorEl = createDomainLoadingError("There was an error retrieving your places."); $("#" + Settings.PLACES_TABLE_ID).after(errorEl); - var temporaryPlaceButton = dynamicButton(Settings.GET_TEMPORARY_NAME_BTN_ID, 'Get a temporary place name'); - temporaryPlaceButton.hide(); - $('#' + Settings.PLACES_TABLE_ID).after(temporaryPlaceButton); + // DISABLE TEMP PLACE NAME BUTTON... + // var temporaryPlaceButton = dynamicButton(Settings.GET_TEMPORARY_NAME_BTN_ID, 'Get a temporary place name'); + // temporaryPlaceButton.hide(); + // $('#' + Settings.PLACES_TABLE_ID).after(temporaryPlaceButton); if (accessTokenIsSet()) { appendAddButtonToPlacesTable(); } diff --git a/domain-server/resources/web/wizard/index.shtml b/domain-server/resources/web/wizard/index.shtml index 4093eda39a..c15b4169ed 100644 --- a/domain-server/resources/web/wizard/index.shtml +++ b/domain-server/resources/web/wizard/index.shtml @@ -19,7 +19,7 @@ -
@@ -102,5 +91,97 @@
+
+ + + + + + + + + + + +
+
+ + + + + + +
+ From 9004251bcffbfdd83828bfe559d2b8a8c9b793a9 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 21:59:14 -0400 Subject: [PATCH 24/74] Add "Actions" and "Selection" menu Add "Actions" and "Selection" menu in the Create App. (HMD/Desktop compliant) --- .../create/entityList/html/js/entityList.js | 128 ++++++++++++++++-- 1 file changed, 115 insertions(+), 13 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index aa40d5286f..949b8684c8 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -200,7 +200,10 @@ let elEntityTable, elRefresh, elToggleLocked, elToggleVisible, - elHmdMultiSelect, + elActionsMenu, + elSelectionMenu, + elMenuBackgroundOverlay, + elHmdMultiSelect, elHmdCopy, elHmdCut, elHmdPaste, @@ -210,6 +213,11 @@ let elEntityTable, elParent, elUnparent, elDelete, + elSelectAll, + elSelectInverse, + elSelectNone, + elSelectAllInBox, + elSelectAllTouchingBox, elFilterTypeMultiselectBox, elFilterTypeText, elFilterTypeOptions, @@ -252,8 +260,11 @@ function loaded() { elEntityTableScroll = document.getElementById("entity-table-scroll"); elRefresh = document.getElementById("refresh"); elToggleLocked = document.getElementById("locked"); - elToggleVisible = document.getElementById("visible"); + elToggleVisible = document.getElementById("visible"); elHmdMultiSelect = document.getElementById("hmdmultiselect"); + elActionsMenu = document.getElementById("actions"); + elSelectionMenu = document.getElementById("selection"); + elMenuBackgroundOverlay = document.getElementById("menuBackgroundOverlay"); elHmdCopy = document.getElementById("hmdcopy"); elHmdCut = document.getElementById("hmdcut"); elHmdPaste = document.getElementById("hmdpaste"); @@ -263,6 +274,11 @@ function loaded() { elParent = document.getElementById("parent"); elUnparent = document.getElementById("unparent"); elDelete = document.getElementById("delete"); + elSelectAll = document.getElementById("selectall"); + elSelectInverse = document.getElementById("selectinverse"); + elSelectNone = document.getElementById("selectnone"); + elSelectAllInBox = document.getElementById("selectallinbox"); + elSelectAllTouchingBox = document.getElementById("selectalltouchingbox"); elFilterTypeMultiselectBox = document.getElementById("filter-type-multiselect-box"); elFilterTypeText = document.getElementById("filter-type-text"); elFilterTypeOptions = document.getElementById("filter-type-options"); @@ -300,32 +316,119 @@ function loaded() { } EventBridge.emitWebEvent(JSON.stringify({ type: 'hmdMultiSelectMode', value: hmdMultiSelectMode })); }; + elActionsMenu.onclick = function() { + + document.getElementById("menuBackgroundOverlay").style.display = "block"; + document.getElementById("actions-menu").style.display = "block"; + }; + elSelectionMenu.onclick = function() { + document.getElementById("menuBackgroundOverlay").style.display = "block"; + document.getElementById("selection-menu").style.display = "block"; + }; + elMenuBackgroundOverlay.onclick = function() { + closeAllEntityListMenu(); + }; elHmdCopy.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'copy' })); + closeAllEntityListMenu(); }; elHmdCut.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'cut' })); + closeAllEntityListMenu(); }; elHmdPaste.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'paste' })); + closeAllEntityListMenu(); }; elHmdDuplicate.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'duplicate' })); + closeAllEntityListMenu(); }; elParent.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + closeAllEntityListMenu(); }; elUnparent.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + closeAllEntityListMenu(); }; elUndo.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'undo' })); + closeAllEntityListMenu(); }; elRedo.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'redo' })); + closeAllEntityListMenu(); }; elDelete.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); + closeAllEntityListMenu(); + }; + elSelectAll.onclick = function() { + + let visibleEntityIDs = visibleEntities.map(visibleEntity => visibleEntity.id); + let selectionIncludesAllVisibleEntityIDs = visibleEntityIDs.every(visibleEntityID => { + return selectedEntities.includes(visibleEntityID); + }); + + let selection = []; + + if (!selectionIncludesAllVisibleEntityIDs) { + selection = visibleEntityIDs; + } + + updateSelectedEntities(selection, false); + + EventBridge.emitWebEvent(JSON.stringify({ + "type": "selectionUpdate", + "focus": false, + "entityIds": selection + })); + + closeAllEntityListMenu(); + }; + elSelectInverse.onclick = function() { + let visibleEntityIDs = visibleEntities.map(visibleEntity => visibleEntity.id); + let selectionIncludesAllVisibleEntityIDs = visibleEntityIDs.every(visibleEntityID => { + return selectedEntities.includes(visibleEntityID); + }); + + let selection = []; + + if (!selectionIncludesAllVisibleEntityIDs) { + visibleEntityIDs.forEach(function(id) { + if (!selectedEntities.includes(id)) { + selection.push(id); + } + }); + } + + updateSelectedEntities(selection, false); + + EventBridge.emitWebEvent(JSON.stringify({ + "type": "selectionUpdate", + "focus": false, + "entityIds": selection + })); + + closeAllEntityListMenu(); + }; + elSelectNone.onclick = function() { + updateSelectedEntities([], false); + EventBridge.emitWebEvent(JSON.stringify({ + "type": "selectionUpdate", + "focus": false, + "entityIds": [] + })); + closeAllEntityListMenu(); + }; + elSelectAllInBox.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'selectAllInBox' })); + closeAllEntityListMenu(); + }; + elSelectAllTouchingBox.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'selectAllTouchingBox' })); + closeAllEntityListMenu(); }; elToggleSpaceMode.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' })); @@ -871,7 +974,7 @@ function loaded() { function updateSelectedEntities(selectedIDs, autoScroll) { let notFound = false; - + // reset all currently selected entities and their rows first selectedEntities.forEach(function(id) { let entity = entitiesByID[id]; @@ -882,7 +985,7 @@ function loaded() { } } }); - + // then reset selected entities list with newly selected entities and set them selected selectedEntities = []; selectedIDs.forEach(function(id) { @@ -1454,16 +1557,8 @@ function loaded() { } else if (data.type === "confirmHMDstate") { if (data.isHmd) { document.getElementById("hmdmultiselect").style.display = "inline"; - document.getElementById("hmdcopy").style.display = "inline"; - document.getElementById("hmdcut").style.display = "inline"; - document.getElementById("hmdpaste").style.display = "inline"; - document.getElementById("hmdduplicate").style.display = "inline"; } else { - document.getElementById("hmdmultiselect").style.display = "none"; - document.getElementById("hmdcopy").style.display = "none"; - document.getElementById("hmdcut").style.display = "none"; - document.getElementById("hmdpaste").style.display = "none"; - document.getElementById("hmdduplicate").style.display = "none"; + document.getElementById("hmdmultiselect").style.display = "none"; } } }); @@ -1489,4 +1584,11 @@ function loaded() { $(window).blur(function() { entityListContextMenu.close(); }); + + function closeAllEntityListMenu() { + document.getElementById("menuBackgroundOverlay").style.display = "none"; + document.getElementById("selection-menu").style.display = "none"; + document.getElementById("actions-menu").style.display = "none"; + } + } From 3241ea7c1f3ec4973ba746dedd3cafa2ebe6e11b Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 22:59:08 -0400 Subject: [PATCH 25/74] Add support for teleportToEntity Add support for teleportToEntity --- .../create/entitySelectionTool/entitySelectionTool.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 0250ead0a9..b218d8b986 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -636,6 +636,16 @@ SelectionManager = (function() { } }; + that.teleportToEntity = function() { + if (SelectionManager.hasSelection()) { + var distanceFromTarget = 3 + Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); + var teleportTargetPosition = Vec3.sum(SelectionManager.worldPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: distanceFromTarget })); + MyAvatar.goToLocation(teleportTargetPosition, false); + } else { + audioFeedback.rejection(); + } + }; + return that; })(); From 8c94d20177983fa06ef7dcbbb8a4bbe45976ce3f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:00:31 -0400 Subject: [PATCH 26/74] Add support for teleportToEntity Add support for teleportToEntity --- scripts/system/create/entityList/entityList.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 80cf2cbdc8..3835e448ec 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -327,6 +327,8 @@ EntityListTool = function(shouldUseEditTabletApp) { selectAllEntitiesInCurrentSelectionBox(false); } else if (data.type === 'selectAllTouchingBox') { selectAllEntitiesInCurrentSelectionBox(true); + } else if (data.type === 'teleportToEntity') { + SelectionManager.teleportToEntity(); } }; From 943ae9aa4cf4eebdd3026c04a14c0a3af068a7f6 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:01:10 -0400 Subject: [PATCH 27/74] Add support for teleportToEntity Add support for teleportToEntity --- scripts/system/create/entityList/html/entityList.html | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index f06dc86855..e2ac043039 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -180,7 +180,14 @@ - + + + From 4c74d5a63006473492fb508528c4ddb57c651a7d Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:01:55 -0400 Subject: [PATCH 28/74] Add support for teleportToEntity Add support for teleportToEntity --- scripts/system/create/entityList/html/js/entityList.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 949b8684c8..c40b4e67a8 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -218,6 +218,7 @@ let elEntityTable, elSelectNone, elSelectAllInBox, elSelectAllTouchingBox, + elTeleportToEntity, elFilterTypeMultiselectBox, elFilterTypeText, elFilterTypeOptions, @@ -278,7 +279,8 @@ function loaded() { elSelectInverse = document.getElementById("selectinverse"); elSelectNone = document.getElementById("selectnone"); elSelectAllInBox = document.getElementById("selectallinbox"); - elSelectAllTouchingBox = document.getElementById("selectalltouchingbox"); + elSelectAllTouchingBox = document.getElementById("selectalltouchingbox"); + elTeleportToEntity = document.getElementById("teleport-to-entity"); elFilterTypeMultiselectBox = document.getElementById("filter-type-multiselect-box"); elFilterTypeText = document.getElementById("filter-type-text"); elFilterTypeOptions = document.getElementById("filter-type-options"); @@ -430,6 +432,10 @@ function loaded() { EventBridge.emitWebEvent(JSON.stringify({ type: 'selectAllTouchingBox' })); closeAllEntityListMenu(); }; + elTeleportToEntity.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "teleportToEntity" })); + closeAllEntityListMenu(); + }; elToggleSpaceMode.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' })); }; From d0de5154fed211a7b7c3aef157345f99efed2f9e Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:22:17 -0400 Subject: [PATCH 29/74] Fix for Issue #711 Fix for Issue: #711 Add error dialogue if an unsupported filetype is added as a model URL in the create app. As agreed, the label "Model URL" will indicate now: "Model URL (.fbx, .fst, .glb, .gltf, .obj, .gz)" The list of file type has been set in Italic. And the label for Material dialog has been adjust to have the same standard "(Optional)" is also in italic. --- scripts/system/create/qml/NewMaterialDialog.qml | 2 +- scripts/system/create/qml/NewModelDialog.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/qml/NewMaterialDialog.qml b/scripts/system/create/qml/NewMaterialDialog.qml index 3cc619e176..e08ca868b6 100644 --- a/scripts/system/create/qml/NewMaterialDialog.qml +++ b/scripts/system/create/qml/NewMaterialDialog.qml @@ -55,7 +55,7 @@ Rectangle { Text { id: text1 - text: qsTr("Material URL (Optional)") + text: qsTr("Material URL (Optional)") color: "#ffffff" font.pixelSize: 12 } diff --git a/scripts/system/create/qml/NewModelDialog.qml b/scripts/system/create/qml/NewModelDialog.qml index dd4ef3c8ad..758706a79b 100644 --- a/scripts/system/create/qml/NewModelDialog.qml +++ b/scripts/system/create/qml/NewModelDialog.qml @@ -55,7 +55,7 @@ Rectangle { Text { id: text1 - text: qsTr("Model URL") + text: qsTr("Model URL (.fbx, .fst, .glb, .gltf, .obj, .gz)") color: "#ffffff" font.pixelSize: 12 } From 1aa09f59c33c1ec8d3ffce7cfa1366ab8a97eee1 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:34:36 -0400 Subject: [PATCH 30/74] Increase the precison of Angular Velocity Increase the precison of Angular Velocity to make more comfortable the Issue #798 Angular Velocity can't go below 0.4 something (round to 0.5) But this won't solve the trouble. For this it would require a fixed for issue #76 Rotations that are transmitted over server lose precision --- .../system/create/entityProperties/html/js/entityProperties.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js index 8364d5b155..f3f92a887e 100644 --- a/scripts/system/create/entityProperties/html/js/entityProperties.js +++ b/scripts/system/create/entityProperties/html/js/entityProperties.js @@ -1618,7 +1618,8 @@ const GROUPS = [ type: "vec3", vec3Type: "pyr", multiplier: DEGREES_TO_RADIANS, - decimals: 4, + decimals: 6, + step: 1, subLabels: [ "x", "y", "z" ], unit: "deg/s", propertyID: "localAngularVelocity", From 413c21f4827032b56e8f2d2d9883bd30940bed06 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Mon, 19 Oct 2020 01:07:07 -0400 Subject: [PATCH 31/74] Append Vircadia to the environment variable for the metadata exporter port. --- libraries/networking/src/DomainHandler.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index f77ff2bb5b..56d32d8609 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -76,9 +76,9 @@ const quint16 DOMAIN_SERVER_EXPORTER_PORT = const quint16 DOMAIN_SERVER_METADATA_EXPORTER_PORT = QProcessEnvironment::systemEnvironment() - .contains("DOMAIN_SERVER_METADATA_EXPORTER_PORT") + .contains("VIRCADIA_DOMAIN_SERVER_METADATA_EXPORTER_PORT") ? QProcessEnvironment::systemEnvironment() - .value("DOMAIN_SERVER_METADATA_EXPORTER_PORT") + .value("VIRCADIA_DOMAIN_SERVER_METADATA_EXPORTER_PORT") .toUInt() : 9704; From c3719a753880bd86ce835548fdcd3b21e099b739 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 20 Oct 2020 00:15:40 -0400 Subject: [PATCH 32/74] Add "Move Selected Entity To Avatar" Add "Move Selected Entity To Avatar" --- .../entitySelectionTool.js | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index b218d8b986..685eadae90 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -637,15 +637,42 @@ SelectionManager = (function() { }; that.teleportToEntity = function() { - if (SelectionManager.hasSelection()) { - var distanceFromTarget = 3 + Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); - var teleportTargetPosition = Vec3.sum(SelectionManager.worldPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: distanceFromTarget })); + if (that.hasSelection()) { + var distanceFromTarget = 3 + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); + var teleportTargetPosition = Vec3.sum(that.worldPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: distanceFromTarget })); MyAvatar.goToLocation(teleportTargetPosition, false); } else { audioFeedback.rejection(); } }; + that.moveEntitiesSelectionToAvatar = function() { + if (that.hasSelection()) { + that.saveProperties(); + var distanceFromTarget = 3 + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); + var targetPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -distanceFromTarget })); + // editing a parent will cause all the children to automatically follow along, so don't + // edit any entity who has an ancestor in that.selections + var toMove = that.selections.filter(function (selection) { + if (that.selections.indexOf(that.savedProperties[selection].parentID) >= 0) { + return false; // a parent is also being moved, so don't issue an edit for this entity + } else { + return true; + } + }); + for (var i = 0; i < toMove.length; i++) { + var id = toMove[i]; + var properties = that.savedProperties[id]; + var relativePosition = Vec3.subtract(properties.position, that.worldPosition); + var newPosition = Vec3.sum(relativePosition, targetPosition); + Entities.editEntity(id, { "position": newPosition }); + } + that._update(false, this); + } else { + audioFeedback.rejection(); + } + }; + return that; })(); From 6d7d9a3dde67a008033864d3b7230e6521ef025b Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 20 Oct 2020 00:16:38 -0400 Subject: [PATCH 33/74] Add "Move Selected Entity To Avatar" Add "Move Selected Entity To Avatar" --- scripts/system/create/entityList/entityList.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 3835e448ec..20434484a1 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -329,6 +329,8 @@ EntityListTool = function(shouldUseEditTabletApp) { selectAllEntitiesInCurrentSelectionBox(true); } else if (data.type === 'teleportToEntity') { SelectionManager.teleportToEntity(); + } else if (data.type === 'moveEntitySelectionToAvatar') { + SelectionManager.moveEntitiesSelectionToAvatar(); } }; From 5924a65eebd817dfcfb2c1ad083d822f77b67cd8 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 20 Oct 2020 00:17:11 -0400 Subject: [PATCH 34/74] Add "Move Selected Entity To Avatar" Add "Move Selected Entity To Avatar" --- scripts/system/create/entityList/html/entityList.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index e2ac043039..df8652ddd6 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -148,6 +148,13 @@ + +
- - + +
From fdae7877e1f1c26c5efdaca26665b0da2345aba3 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:46:15 -0400 Subject: [PATCH 37/74] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- scripts/system/html/css/edit-style.css | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 842a4e27f1..2ba68e505b 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -1456,6 +1456,11 @@ input[type=button]#export { font-size: 15px; } +#entity-table-scroll .vglyph { + font-family: Vircadia-Glyphs; + font-size: 15px; +} + #entity-table { margin-top: -28px; margin-bottom: -18px; @@ -1468,7 +1473,7 @@ input[type=button]#export { background: none; } -#entity-table .glyph { +#entity-table .glyph .vglyph { margin: 0 -2px 0 -2px; vertical-align: middle; } @@ -1501,11 +1506,11 @@ input[type=button]#export { outline: none; } -#entity-table th .glyph { +#entity-table th .glyph .vglyph { position: relative; left: 4px; } -#entity-table th .glyph + .sort-order { +#entity-table th .glyph .vglyph + .sort-order { position: relative; left: 4px; } @@ -1532,7 +1537,7 @@ input[type=button]#export { #entity-table td { box-sizing: border-box; } -#entity-table td.glyph { +#entity-table td .glyph .vglyph { text-align: center; padding: 0; } @@ -1877,7 +1882,7 @@ div.multiZoneSelToolbar { left:0; right:0; bottom:0; - display:block; + display:none; } div.entity-list-menu { From 8afa9781225998553a3a8af5f05129f2f854e13e Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:47:10 -0400 Subject: [PATCH 38/74] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- scripts/system/create/edit.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 5c488a71ee..35bcd45786 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -1720,6 +1720,9 @@ function unparentSelectedEntities() { } else { Window.notify("Entity unparented"); } + //Refresh + entityListTool.sendUpdate(); + selectionManager._update(false, this); } else { audioFeedback.rejection(); if (selectedEntities.length > 1) { @@ -1756,6 +1759,9 @@ function parentSelectedEntities() { if (parentCheck) { audioFeedback.confirmation(); Window.notify("Entities parented"); + //Refresh + entityListTool.sendUpdate(); + selectionManager._update(false, this); } else { audioFeedback.rejection(); Window.notify("Entities are already parented to last"); @@ -2963,4 +2969,22 @@ function zoneSortOrder(a, b) { return 0; } +function getParentState(id) { + var state = "NONE"; + var properties = Entities.getEntityProperties(id, ["parentID"]); + var children = Entities.getChildrenIDs(id); + if (properties.parentID !== Uuid.NULL) { + if (children.length > 0) { + state = "PARENT_CHILDREN"; + } else { + state = "CHILDREN"; + } + } else { + if (children.length > 0) { + state = "PARENT"; + } + } + return state; +} + }()); // END LOCAL_SCOPE From 48bd101d08cad848b012b47b9bc6c2018b8e64bc Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:47:55 -0400 Subject: [PATCH 39/74] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- .../entitySelectionTool.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 685eadae90..0f8c8cc8bf 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -697,8 +697,10 @@ SelectionDisplay = (function() { const COLOR_HOVER = { red: 255, green: 220, blue: 82 }; const COLOR_DUPLICATOR = { red: 162, green: 0, blue: 255 }; const COLOR_ROTATE_CURRENT_RING = { red: 255, green: 99, blue: 9 }; - const COLOR_BOUNDING_EDGE = { red: 128, green: 128, blue: 128 }; - const COLOR_SCALE_CUBE = { red: 160, green: 160, blue: 160 }; + const COLOR_BOUNDING_EDGE = { red: 160, green: 160, blue: 160 }; + const COLOR_BOUNDING_EDGE_PARENT = { red: 194, green: 123, blue: 0 }; //{ red: 255, green: 160, blue: 0 }; + const COLOR_BOUNDING_EDGE_CHILDREN = { red: 0, green: 168, blue: 214 }; // { red: 0, green: 200, blue: 255 } + const COLOR_SCALE_CUBE = { red: 192, green: 192, blue: 192 }; const COLOR_DEBUG_PICK_PLANE = { red: 255, green: 255, blue: 255 }; const COLOR_DEBUG_PICK_PLANE_HIT = { red: 255, green: 165, blue: 0 }; @@ -1828,6 +1830,18 @@ SelectionDisplay = (function() { var rotationZ = Quat.multiply(rotation, localRotationZ); worldRotationZ = rotationZ; + var handleBoundingBoxColor = COLOR_BOUNDING_EDGE; + if (SelectionManager.selections.length === 1) { + var parentState = getParentState(SelectionManager.selections[0]); + if (parentState === "CHILDREN") { + handleBoundingBoxColor = COLOR_BOUNDING_EDGE_CHILDREN; + } else { + if (parentState === "PARENT" || parentState === "PARENT_CHILDREN") { + handleBoundingBoxColor = COLOR_BOUNDING_EDGE_PARENT; + } + } + } + var selectionBoxGeometry = { position: position, rotation: rotation, @@ -1949,6 +1963,7 @@ SelectionDisplay = (function() { Entities.editEntity(handleBoundingBox, { position: position, rotation: rotation, + color: handleBoundingBoxColor, dimensions: dimensions }); From cfec2c492b15dd7ef6128155180c4a7ce16c80fe Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:48:49 -0400 Subject: [PATCH 40/74] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- scripts/system/create/entityList/entityList.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 20434484a1..cb6beeaa4a 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -203,6 +203,17 @@ EntityListTool = function(shouldUseEditTabletApp) { } else if (properties.type === "Image") { url = properties.imageURL; } + + var parentStatus = getParentState(ids[i]); + var parentState = ""; + if (parentStatus === "PARENT") { + parentState = "N"; + } else if (parentStatus === "CHILDREN") { + parentState = "O"; + } else if (parentStatus === "PARENT_CHILDREN") { + parentState = "M"; + } + entities.push({ id: ids[i], name: properties.name, @@ -222,7 +233,8 @@ EntityListTool = function(shouldUseEditTabletApp) { isBaked: entityIsBaked(properties), drawCalls: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.drawCalls) : ""), - hasScript: properties.script !== "" + hasScript: properties.script !== "", + parentState: parentState }); } } From 46bb29bded2c21498836d08ee19da64c7f63692d Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:49:36 -0400 Subject: [PATCH 41/74] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection From 8baebbdd16aed3ed5d35524b8c4dd839d07dc688 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:50:28 -0400 Subject: [PATCH 42/74] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- .../create/entityList/html/js/entityList.js | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 74112047f1..b6e682e0c2 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -134,6 +134,14 @@ const COLUMNS = { initialWidth: 0.06, defaultSortOrder: DESCENDING_SORT, }, + parentState: { + columnHeader: "M", + vglyph: true, + dropdownLabel: "Hierarchy", + propertyID: "parentState", + initialWidth: 0.04, + defaultSortOrder: DESCENDING_SORT, + }, }; const FILTER_TYPES = [ @@ -499,9 +507,12 @@ function loaded() { elTh.setAttribute("id", thID); elTh.setAttribute("columnIndex", columnIndex); elTh.setAttribute("columnID", columnID); - if (columnData.glyph) { + if (columnData.glyph || columnData.vglyph) { let elGlyph = document.createElement("span"); elGlyph.className = "glyph"; + if (columnData.vglyph) { + elGlyph.className = "vglyph"; + } elGlyph.innerHTML = columnData.columnHeader; elTh.appendChild(elGlyph); } else { @@ -801,10 +812,11 @@ function loaded() { isBaked: entity.isBaked, drawCalls: displayIfNonZero(entity.drawCalls), hasScript: entity.hasScript, + parentState: entity.parentState, elRow: null, // if this entity has a visible row element assigned to it selected: false // if this entity is selected for edit regardless of having a visible row }; - + entities.push(entityData); entitiesByID[entityData.id] = entityData; }); @@ -1060,6 +1072,8 @@ function loaded() { let elCell = elRow.childNodes[i]; if (column.data.glyph) { elCell.innerHTML = itemData[column.data.propertyID] ? column.data.columnHeader : null; + } else if (column.data.vglyph) { + elCell.innerHTML = itemData[column.data.propertyID]; } else { let value = itemData[column.data.propertyID]; if (column.data.format) { @@ -1147,6 +1161,9 @@ function loaded() { let column = columnsByID[columnID]; let visible = column.elTh.style.visibility !== "hidden"; let className = column.data.glyph ? "glyph" : ""; + if (column.data.vglyph) { + className = "vglyph"; + } className += visible ? "" : " hidden"; return className; } From 4c1de14cbbda078172e95e9bb9c24362945b1b4f Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 21 Oct 2020 00:56:55 -0400 Subject: [PATCH 43/74] Add input error handling and notice. --- domain-server/resources/web/js/shared.js | 2 -- domain-server/resources/web/wizard/js/wizard.js | 17 ++++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/domain-server/resources/web/js/shared.js b/domain-server/resources/web/js/shared.js index 0395106297..bffd512890 100644 --- a/domain-server/resources/web/js/shared.js +++ b/domain-server/resources/web/js/shared.js @@ -522,8 +522,6 @@ function createDomainIDPrompt(callback) { if (callback) { callback(inputValue); } - - swal.close(); }); } diff --git a/domain-server/resources/web/wizard/js/wizard.js b/domain-server/resources/web/wizard/js/wizard.js index 6c46a3b35c..6039c68cfa 100644 --- a/domain-server/resources/web/wizard/js/wizard.js +++ b/domain-server/resources/web/wizard/js/wizard.js @@ -179,7 +179,14 @@ function promptToCreateDomainID() { "label": label }; - $.post("/api/domains", domainJSON, function (data) { + $.post("/api/domainsss", domainJSON, function (data) { + if (data.status === "failure") { + swal.showInputError("Error: " + data.error); + return; + } + + swal.close(); + // we successfully created a domain ID, set it on that field var domainID = data.domain.domainId; console.log("Setting domain ID to ", data, domainID); @@ -192,9 +199,13 @@ function promptToCreateDomainID() { // POST the form JSON to the domain-server settings.json endpoint so the settings are saved postSettings(formJSON, goToNextStep); - }, 'json').fail(function () { + }, 'json').fail(function (data) { + if (data && data.status === "failure") { + swal.showInputError("Error: " + data.error); + } else { + swal.showInputError("Error: Failed to post to metaverse."); + } console.log("Failed to create domain ID..."); - goToNextStep(); }); }); }, 500); // Apparently swal needs time before opening another prompt. From c1a47878b935abecd1332518f12582a24fecd3fc Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 21 Oct 2020 00:57:30 -0400 Subject: [PATCH 44/74] Fix indent. --- domain-server/resources/web/wizard/js/wizard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/wizard/js/wizard.js b/domain-server/resources/web/wizard/js/wizard.js index 6039c68cfa..1350de7205 100644 --- a/domain-server/resources/web/wizard/js/wizard.js +++ b/domain-server/resources/web/wizard/js/wizard.js @@ -199,7 +199,7 @@ function promptToCreateDomainID() { // POST the form JSON to the domain-server settings.json endpoint so the settings are saved postSettings(formJSON, goToNextStep); - }, 'json').fail(function (data) { + }, 'json').fail(function (data) { if (data && data.status === "failure") { swal.showInputError("Error: " + data.error); } else { From 35210fdb3259a266da5175e7047156e4144b488c Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 01:12:48 -0400 Subject: [PATCH 45/74] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- interface/resources/fonts/vircadia_glyphs.ttf | Bin 4660 -> 5240 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/interface/resources/fonts/vircadia_glyphs.ttf b/interface/resources/fonts/vircadia_glyphs.ttf index b6a8c2e7ad4c30ed5d6d713f6590cae1f5a27f10..f7e9d7f372c88e34027d1ab63880127354150ed1 100644 GIT binary patch literal 5240 zcmd5=eT*B&b^pED-PtAggIq4TOY(R;lFQ?gcc(jw$J;&Mon=drRNK*qeHH>)-{+H} zQ>t?WDRylGb=)K<;8aLmrAA`Aa2m&P>mqeh*C`6vaofZQ;iWu=sT1wn044*pd~)U7nah_U0r@@v?d0hP zKK$nLoi75?!+_abJF#-Sw5R=J0N(=;uC1L|QO?lw0ObKR*VaFFf9Lb`y8!(ufL*6Q zy1G(%V(dQwN%YrVU%CGb4&y0+<^k01Sy?~v$kx{@K=v6xy5-DA&wY$`(gDEvHvqRl z=tjWv3x$sy%`E)~bm>O`@Q+_V`zKf44!~Yu&k4R@B6rw^y*&6Xz`iX$*$c6xtCJJw zICv6ToGn^XoOg3lO=4^GE);-$n!NL+C9A4!zjl0izu>>qs;C?h24XEe18EW>@nRN5isZg|@0`svTOUWrnt@sv7-!SSx#8u`zgEG;DaqqSv5Kqx){$DyxUZV&fZ{ z_J@Nv^lVnAPD@=_WRQhP*6mPJ;xq} zhYq^<0PX;&6-Yd21ud0}%X6b%6h=-+uIGx3Ruo3Ps29zK4j-c^;1ot-Fik3N%#iB2 zo;&MCZoyS~(3)#Sq31G#rG6sIh1U4EY22j9i_IyX*<5+2I`~>SomQ=x?oP|>DkPIs zAwGJn{o9;g3`{FO`sgH+*;xCQk)Fe*+6GNdw~sSz}SNorW+$L99jD*}R>$ZH6jPZIaV)lhvN zw0@n+!RQEQOv!OWk{M%Osa9K1(p+Jb%A|dROX<58`we39=xAVPYo2N_nMusD@{TWYSt2E+6kB$|%8VDix}@9f zQMYKMl+3i1b)CWrOG`H{+(%4O%A4(6chpgc^r%>|GSfv<8CR#wb5dsTHW5*Ja;BM8 zQdPT@&6Kisu#$Jq6ER7YF)8-)Dk?D84)%L+5MU2Z;@9vvo&d&$E4q>TQMgDw&mE<_ z%B7)`iv3tm_@92zlDtW31Vd*P*A(V&2yf>uk}8~+_|H9OD6JJ&zFKDBH#WKv1H<)Z zH+l;SvvYBSmhhn}FXV+}l}GgB?~J*w>s7x~^<392|E(@Om_B^HrO<2TY%Z5AcXZA< z*E^bFXs@*muB4bss``q?RUPQRAx0wTr682R~rBT$!FK=W=O1tsC0lZp|Pq zWip8vjd89$s~LJat>>K5vl{1LHd38(F4s``h@s`2QYXdvmO>$A7@EO3S4{D$iFroI zBgGD|&!HiFXJHc+dc#S!@hr50X%dqqzG%T4yhE9t6~A3~3wAb@k`*FZBUMrzN7u(& zWqR!1mtVSHmNQn?_Wk;%-i`D2rJ0QYTZCZlmnrZSPp6Ij(0cM-yXBI2JMd8L8Z|3Wc3hAsf5@rI+s|E0Y_U>@P4~ zN~cv`P}D}s*W3$B+m~96+E_&u@tcGZIP6jOITWyfTLB8aDh*wXAT#t5p%eIla5qD% zRH<;qJYIf`+_8AIbfW$wiLvCyj)#H|-PK)o8=P-)yuiF`{UdvhJ@L@4>FJb|Dw8TJ zG9#IhG&;mGX|mpKGy1HyX?kK}f^D@kIreEYaF@Hc-f{bmve#4>^z`n-pFH=%;BS7P za%%1d$x5X)MdFN8YC*DeO_P`^<f(RHqfmNP-1@={e#W11>ym(QGJU3!aJ3sg{+FHulx3@Xh2CvYzQqF!>H?o5_ zvW8L2QYUNZA09npx9!Qwl&1X?-7)y8H=WOK5g^Ug=|cWnRCg@Xw4A~Ba}~?FSbNyE zH`jZ5ycU+>u+OunuW(&_|7@vl*MD)w^hcLI!5;dBcn?0wep5ue4m|cedk%GM1JL04 zF%m1&aIxu)kz2^CTy@8UOX|;%msdSEFBa_K`qi2d^FR!$o+!?HWL{Y7uQFr4TCMD_ ztXHd6j;zsAw%=d>dt<)3w6D5et(p!qN6VRhf4zTUt$#PM=hiOtS6$X>%vUEm)oOLU zI?=9Ks$-2>+5Uz8JwF_8&R6#>Rqv^GCaM{cpAq@%{k04IyA=f-BdD`4u%}SQES9hX zdvO=wc#)V9VHA$hY&0kEaMF6N@Y+#-hUU~+;X1g=XGqP@dafe^k_<(mDwbLio>06z z-$ZJ|i((h=b8{3PT%v9o;k zY@V5!89X`H-@UtkkbbH{$c|fSEtNU4%Y0PIWGtO)gJ(?3RFu@bbm7P@E0bZQsqxOJ zfX(a$_Bd2zQA7hROkf&4pxG1uwAGK_{sw5Y`ZO$<>xa>-?FV!9LNHtK$7c&Z%`Y!5 zE-zANd10~LSsa`ge(s*xzWvCK?G@ku7rI#Y{Xxg~FD{6(g{z+Qh^W+^*}go`?(=>B z)mL5>yV@bY#e`o4H8j!2)b;pX!^)`_>hHnqhN~(43Q2=YKZDnS!6OMD`m4W-cZ7Lt z!uROQ&|m@u*Tly#ie#<@ebdAH&*Rm2N%T*qNlFxF$r>l2^q8!%%Eatf+dvj zi3H2=@Ye}e!0={*Ib0e^unM9u!5WB`5}X3jwgjg^G(1rNbP(-H@(mE}ORx!|0|~Z3 zbS%MHWN3qr4V9i2yK6a>?2U(*Pz6sggM~1`5_;H^U>Vc+odhe8@xugjOyR8rt6t4kb8?D&3u68x~zaO&mzzKAgf? ztYQVnaSAIqijz2v2XF>!I0xK!>g?*u@lz{DPo93@%-T6%87FWO_u@2Ga28lTaq`~N zD`$nMg`XpsgTNasRX^g1Bglrf7k}K#|r) z-9m^fZgGdRifp$*WAsPwU}nC#_ndnkbI&<*2LwRJqmXcL|NcVF_iTUdyCV6s;#N1Nd72(c0R{)$}?&3y=e#v9@vHk$Ra<0Q3z2d)CjK zSS@_YdKHkC0n|2DA32MAAmlFssGeTkIJr1~{Q_XT0E@P?d-8Y+ za@;LADel{okV))edK+ngJ;q)JaCv;EA7YNS8FJ=CYE>s+w-( zek$Sr%})=BN7ZB-Lv&7uT>kZ92R@RckIJgPtqb7Y5Dou*|n68Ai9ze18~)O*S#~O4ZTp z)spY~wa9nt)S2@A-pI-*Dz(-8H|wq+sY-_4$g86tsCh+EsiP{&eNo9UB2!ir*^CU` z&?8fpWrhANs+K&@uZ?~n7;B#Ido^m;dT+;Ec{TF=+BX&D_eQU)`MgT)jH)Q=uSKSz za5K^kLyz)GJg2T3hFG=l_RIf~S3a=WAIv@=4If4JJbN52TA0ONd<39oDDkivHf1gw z%6hN2-_Uz0mLjQ4eDZkfw`6*$S#~BLpJ6Fh zY27)|myK;Ljb^sDXJ}@!QD=v(`sh$96&QL};?>97zLe6p(^K8ipX4Sc$~{fr-|Oi_ z5zC^!sxqQ^_KY5<2V`*=0;)2ae(* zJ_p#**cxGUj)W&Fl%ud&51X^p44VssVKj_9;U+F9#nKgvH*BV(3UQeictP}wap8@G zqraO39o52GI7789?i;+}t>o3X%x8$#d7anfIuDzlmHbwDf-{!3G8u`b81stN>Qb39 zikz)$T*^)ck>@m&w5Anvg^al^!&u5H&|0mk9lH2uQo5lqrZh_xJ->HClk^6)A6WXX zTpE2%5}udR`E7c>k@q@PlN0g0L*1*@>W`QzWtfncBF-e+a@psIrOV}(nXh_TAwyz@ z;n;OEold3wrdcp@)4pGm)O>r=^|eeo*ERC4U07vVY5tCfiAm|woN3LK?KF`(^vg!B z>lb&`&P&GVEh46NW*hl*CNPWnTrqF8Rvr7YL=q7Zlj006qYRDhW6#1yh!5iweicvR zw}EMqYHp#yFxp9d&z&Sk=F&I`#d)eP^2;D>O5P0B!f`T+DTS|VBAdB8NfyaTyw1Ko zo~;=Z-#lknuWgAD@89+2x1@!I`GuIFDRQLD3yzps=0p1N_bRUIdcpSs&vo6>U#cQQ zspH#^()3y>Z&~?LTjiW{wXJBH@>)yd=?s$@=igGetYtd77}PsO$L8|U&5UMS6TaSP z_*p8JY?~`@eP7FTGFnzuRROsCyP9nkuN7^}vWwS>mQBCF75SRNWtl72WQC9Zo>^9j zo-SEdR?VuKGP+;UNXh6-B1RR?m8*)TX0xhg7q2Rue@)A@OO{oW`GhW8cCnq|e0QOc z(KJQloTqhhtBSfoaFAj5vM*o?pu%=4^vAKZbuBbSJS0b*>Z7+PcUv`V)CvXDP?dC= zD5a!i#j;g(dU|4&p1AnR%a5eeMlNU8gJyHbEsMoZHFivPmj-hME2p!YW!3;%&}m^t z1Yvv_Og2c4<5k329DhGg`O%x+@p5BYHFAzjQi@3#VvKVm=M?I-?enbi$jh%>BqL|} z-Gv?8spah5+S2LUZ`s{w1QkP96k)4`3E1p$_64{Y;C6r_FQBck|4HE6VLcQnBuII# zAPA^JZY3^w_HZymV!60+3Zd}hD{}|E8t2>drKWN3`a>T+eqj02%iV4!Eti~Dj~?9TmFmipnmuszGw1JF8U4j`WMy+Z z(nZb4u+*(-U*@VL={Zl5Xt%|V9ZgC1UY=~3NMRp#vlHwRR1~odLtxshn@)YIAPT)* zHyxQL4-27r(+9!$OCXG^!O(MWC1$sr(YI)C(J~LVI9Eo0M7I?!^Qx-lN3Z8K&CgRi zuc;q8Yqrdp@-{^|`*-xw(TiT!amXIMnB{V};FO=GDcjI>!yf(6DjUXMJ!+bBQ+-u^ zRMfB%Z1zR=l^eS5{NUP>Ic5Ir8jrrie&uJ{djk8O&0X9NBXnQEJEKr#UOuxKkmwFUB3W@XKq16HHqSg7QjvBM5Yx zj7i@d3^oR&X^X+GL%~K6Xb#hp-YaW^`-wfjc4crPuQY3mL8l!A!A8(&RdvNSCUtXg zWpH{hdSkk=7#!LaoDSNZz)&20QnvOe`2)ksE%w6oJSz3_iy+G(cOR_WXxmJ_sXc&3@DC|;>5YVk8*Sw+3UC)hH zj_f>AO1J7!`!MZ1(m4L{J9WKC?>t1&;azk%8QDdL7k<6$6B}j@nR!JnWtXpSX3N_0 zvD}xX#jI}X4xKo%>qu$;QpO06?4-jD&%0x8_SopDhrYOQm~I}4*tx8kJGQJ{4h)qm zi=#g;XEKY@m1E0Bz$ic71k~v18~YGKD!~L9Zh{$PbQ3JW#JvelA&1KePD95x63n6F z9}+Bs@OFX~5PqEC42ZTiJXsL&q+bP*mS7D;R)Td9`3W{a6eKtgnR*E}A=8~=2bRht z`=>D`7~lzJFc2hILJd)ZQwXr0U=fdBN-#$WuO?Uq!`AN zq$F4aBO}2&7&!?xz^IhqJPfKP*n~lgsEX|(4&V~1*pD+fjSIkmOV#~nPG11-!bzOM zMXX~L=YYFTp1QccdQPw`y@#jzUfSwXGE4Oa*Sn>>kK=vxAHzwU!+AUy>s3V$UG&hy z9PqJ|=gvQP=5)2!?e*ry`fq9f9-R+d5~keHVQlaJ{`zj6w{-lUJ@fuu^?REL3W9ip z4NRkn5G}OP!3?%xJGz*S8EA78EM9dQApY*ePZDx*1pP!x{Kw(1?|xGJ%X!y7lm7y& Ck#F?? From 70b04b12268fd71ceb3486e047cc4fa2c47c4be6 Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Wed, 21 Oct 2020 16:42:10 -0400 Subject: [PATCH 46/74] Update wizard.js --- domain-server/resources/web/wizard/js/wizard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/wizard/js/wizard.js b/domain-server/resources/web/wizard/js/wizard.js index 1350de7205..d7eda38055 100644 --- a/domain-server/resources/web/wizard/js/wizard.js +++ b/domain-server/resources/web/wizard/js/wizard.js @@ -179,7 +179,7 @@ function promptToCreateDomainID() { "label": label }; - $.post("/api/domainsss", domainJSON, function (data) { + $.post("/api/domains", domainJSON, function (data) { if (data.status === "failure") { swal.showInputError("Error: " + data.error); return; From affad6741ca4dafaffe0d45f98a5e74cdcb93818 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 22:44:55 -0400 Subject: [PATCH 47/74] Better icons for Hierarchy Better icons for Hierarchy --- interface/resources/fonts/vircadia_glyphs.ttf | Bin 5240 -> 4000 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/interface/resources/fonts/vircadia_glyphs.ttf b/interface/resources/fonts/vircadia_glyphs.ttf index f7e9d7f372c88e34027d1ab63880127354150ed1..7d3fe9d913a85bcbfc00162d1ebf1617c40c1b48 100644 GIT binary patch literal 4000 zcmds)Yit}>703VQ&g{&3-)ry7$-caHX4j4#@67DOk0gG^X&#Q9M;)hmIGaapD{*TQ zH#7o;3RNgVk!S!_0-_2CAjGE_1VVxj{SXPLQt_b?&_ZY;BoJ1W@}Z!zg0+1Zr z-)T%A7=H_(NdU)B&Q<1LUwGlifcOBQebbfm^D8Tm0RIsH&grukpDxE58Ue=@K-xWX zx^gP^$xB-S{02a2X6AH7dK*^05P+7MxrOKD2jm0jhX4(pefDIfa_;z70eKvtp1I2N z^Y}fc0O|seex@>a`poA)bp~+$3Xl%YKYM;*cKkDc0X%s?YJ)X50;Ipb=b!R#{xjSH zR{Ql2UKv}BA%O0P>sGy}?zYDWEZ+uq&>cI|!_8s$T*DDK?QUx%*?s+dm_#4YdvE~a zv*Jepu2dtv4V`M9TBAUX08CC!PNE;_yWQ0q=)S$vnu{g*tu=EH{miNyz;^(P)~5Uq zS{HWU^6EGZJ*)iDZ4zLA;=I1QA=wm%jJ$nK)UJw4ce__s?1f0*g+(jBOP{En6|0eA zUpQ5^PRH6)VqJ-{Ls6Y|F1N?)^9O?U4WV!(8f#p)KAuRX(oLD>mJM1q*V?wRy<<~n zUN_7_u~hEr?&;mUWouvmz~IpEwvp{m?AW<$_voIn@xA-@A9!-&;N+pF4j(ysZ0dNW zD*u1C$p2_Nj&I{uZKDbL)<=7@uNdoY^nGz15>%j}DcDqQ3O0r4Ys*u4>R*0UT>snA zycn|1uoGSApx5Z8eQW@YNT3O==l~kbaC13q7VC{jNNLV!g_atWqiWXrC{{;CE0oP} z^W}HnO)hrk;)#Y(e0ixFzYv-T-JA$bbm!vnT)ZU`p_@y$78jTQn8+m(xs?6=iNJL5 zWwe4_o0=`Z{KgyU zs}t$8qgu_GTs)yANV7vOHW2&rKx}|c|NO>FFU{?}Vi&XgO*}wp2tg8&A_UbtWF`H; zK~5ngB64{;NU5`irs$WhzOCa&`b(;sQ(}Sod{>X2N+o^qh37s_BH-`|Ns@#hw-BukTv_F zX>6hBDwj)JC|mt2qivx=xztNWG@@ozrIXZX#3<7hkFS1d$v^4!G`#bU!{IpURK0I{ z>g!zYH@&K}7~ZES>2TVU^w7%>!hU}y_+aq;h}YkwNY3{U-uAj&A@6Ok+vRfYjU973 zH^f@JUH}<-W%d3npfD5sXl1r~w=+v<#HX2MMDQB30|I|wRuHBLvkE~5vlD`Pnd=~E znArtEqs(pynqc-o&=j*5f@YX~5cDzT0Q~et<{%XMuJy|#*V!v?{bpHANTQBez=LjP z2?q8s%V@_nW(Q>4V^+|HC1w>ewKF>*Q<1q2GHqpcL8k4@Zpbvw?14;&n7xqc1hWq^ zona0jNej$Dc<39*AOmDFzy-|W98RKwQ`hH*7Gk?r5_!d$@Hwrovvkjd`WBad{~lybApeXY^|QvRR1MBeqL*5@*zw8 zPfs;#+co=1SU`dd2NbAqq7E*&;ei)E_z^%5^=Lo{VMGu`42@Wa^@t;ZBvMGD2^ln_ z1sk9tiyT_fhK*=P2R5M-dFU`;qJSbwD5DGA=s_Gwgl%^)iP&2jA2GS@?IclXg+DPrxL7S+P@}!eN zCKaeiB`Q-FbyE-Zs?R+$yDgv3bJRH+98Hb|jzx|oj%AKr9J@IVa2(_~#BrG8HjX3J zsIy;Zzs`Q0{W|+~_Ur7|*{`!-XTQ#Vo&7rdb@uD**V%8d-(bJNeuMo6`wjLR>^InN zu-{<6!G44N2Kx>68|*jOZ?fNHzsY`+{U-ZO_M7ZC*>AGn?6&_gXk`V$zKeSRMC@lg af`qStAV2huV87kHwf{?hvPM1pe)@M1PF?u` literal 5240 zcmd5=eT*B&b^pED-PtAggIq4TOY(R;lFQ?gcc(jw$J;&Mon=drRNK*qeHH>)-{+H} zQ>t?WDRylGb=)K<;8aLmrAA`Aa2m&P>mqeh*C`6vaofZQ;iWu=sT1wn044*pd~)U7nah_U0r@@v?d0hP zKK$nLoi75?!+_abJF#-Sw5R=J0N(=;uC1L|QO?lw0ObKR*VaFFf9Lb`y8!(ufL*6Q zy1G(%V(dQwN%YrVU%CGb4&y0+<^k01Sy?~v$kx{@K=v6xy5-DA&wY$`(gDEvHvqRl z=tjWv3x$sy%`E)~bm>O`@Q+_V`zKf44!~Yu&k4R@B6rw^y*&6Xz`iX$*$c6xtCJJw zICv6ToGn^XoOg3lO=4^GE);-$n!NL+C9A4!zjl0izu>>qs;C?h24XEe18EW>@nRN5isZg|@0`svTOUWrnt@sv7-!SSx#8u`zgEG;DaqqSv5Kqx){$DyxUZV&fZ{ z_J@Nv^lVnAPD@=_WRQhP*6mPJ;xq} zhYq^<0PX;&6-Yd21ud0}%X6b%6h=-+uIGx3Ruo3Ps29zK4j-c^;1ot-Fik3N%#iB2 zo;&MCZoyS~(3)#Sq31G#rG6sIh1U4EY22j9i_IyX*<5+2I`~>SomQ=x?oP|>DkPIs zAwGJn{o9;g3`{FO`sgH+*;xCQk)Fe*+6GNdw~sSz}SNorW+$L99jD*}R>$ZH6jPZIaV)lhvN zw0@n+!RQEQOv!OWk{M%Osa9K1(p+Jb%A|dROX<58`we39=xAVPYo2N_nMusD@{TWYSt2E+6kB$|%8VDix}@9f zQMYKMl+3i1b)CWrOG`H{+(%4O%A4(6chpgc^r%>|GSfv<8CR#wb5dsTHW5*Ja;BM8 zQdPT@&6Kisu#$Jq6ER7YF)8-)Dk?D84)%L+5MU2Z;@9vvo&d&$E4q>TQMgDw&mE<_ z%B7)`iv3tm_@92zlDtW31Vd*P*A(V&2yf>uk}8~+_|H9OD6JJ&zFKDBH#WKv1H<)Z zH+l;SvvYBSmhhn}FXV+}l}GgB?~J*w>s7x~^<392|E(@Om_B^HrO<2TY%Z5AcXZA< z*E^bFXs@*muB4bss``q?RUPQRAx0wTr682R~rBT$!FK=W=O1tsC0lZp|Pq zWip8vjd89$s~LJat>>K5vl{1LHd38(F4s``h@s`2QYXdvmO>$A7@EO3S4{D$iFroI zBgGD|&!HiFXJHc+dc#S!@hr50X%dqqzG%T4yhE9t6~A3~3wAb@k`*FZBUMrzN7u(& zWqR!1mtVSHmNQn?_Wk;%-i`D2rJ0QYTZCZlmnrZSPp6Ij(0cM-yXBI2JMd8L8Z|3Wc3hAsf5@rI+s|E0Y_U>@P4~ zN~cv`P}D}s*W3$B+m~96+E_&u@tcGZIP6jOITWyfTLB8aDh*wXAT#t5p%eIla5qD% zRH<;qJYIf`+_8AIbfW$wiLvCyj)#H|-PK)o8=P-)yuiF`{UdvhJ@L@4>FJb|Dw8TJ zG9#IhG&;mGX|mpKGy1HyX?kK}f^D@kIreEYaF@Hc-f{bmve#4>^z`n-pFH=%;BS7P za%%1d$x5X)MdFN8YC*DeO_P`^<f(RHqfmNP-1@={e#W11>ym(QGJU3!aJ3sg{+FHulx3@Xh2CvYzQqF!>H?o5_ zvW8L2QYUNZA09npx9!Qwl&1X?-7)y8H=WOK5g^Ug=|cWnRCg@Xw4A~Ba}~?FSbNyE zH`jZ5ycU+>u+OunuW(&_|7@vl*MD)w^hcLI!5;dBcn?0wep5ue4m|cedk%GM1JL04 zF%m1&aIxu)kz2^CTy@8UOX|;%msdSEFBa_K`qi2d^FR!$o+!?HWL{Y7uQFr4TCMD_ ztXHd6j;zsAw%=d>dt<)3w6D5et(p!qN6VRhf4zTUt$#PM=hiOtS6$X>%vUEm)oOLU zI?=9Ks$-2>+5Uz8JwF_8&R6#>Rqv^GCaM{cpAq@%{k04IyA=f-BdD`4u%}SQES9hX zdvO=wc#)V9VHA$hY&0kEaMF6N@Y+#-hUU~+;X1g=XGqP@dafe^k_<(mDwbLio>06z z-$ZJ|i((h=b8{3PT%v9o;k zY@V5!89X`H-@UtkkbbH{$c|fSEtNU4%Y0PIWGtO)gJ(?3RFu@bbm7P@E0bZQsqxOJ zfX(a$_Bd2zQA7hROkf&4pxG1uwAGK_{sw5Y`ZO$<>xa>-?FV!9LNHtK$7c&Z%`Y!5 zE-zANd10~LSsa`ge(s*xzWvCK?G@ku7rI#Y{Xxg~FD{6(g{z+Qh^W+^*}go`?(=>B z)mL5>yV@bY#e`o4H8j!2)b;pX!^)`_>hHnqhN~(43Q2=YKZDnS!6OMD`m4W-cZ7Lt z!uROQ&|m@u*Tly#ie#<@ebdAH&*Rm2N%T*qNlFxF$r>l2^q8!%%Eatf+dvj zi3H2=@Ye}e!0={*Ib0e^unM9u!5WB`5}X3jwgjg^G(1rNbP(-H@(mE}ORx!|0|~Z3 zbS%MHWN3qr4V9i2yK6a>?2U(*Pz6sggM~1`5_;H^U>Vc+odhe8@xugjOyR8rt6t4kb8?D&3u68x~zaO&mzzKAgf? ztYQVnaSAIqijz2v2XF>!I0xK!>g?*u@lz{DPo93@%-T6%87FWO_u@2Ga28lTaq`~N zD`$nMg`XpsgT Date: Fri, 23 Oct 2020 23:17:22 -0400 Subject: [PATCH 48/74] Code Adjustments Code Adjustments --- scripts/system/html/css/edit-style.css | 8 -------- 1 file changed, 8 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 2ba68e505b..1f1fb9c86a 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -419,7 +419,6 @@ input[type=button].normal, button.hifi-edit-button.normal { font-family: FiraSans-SemiBold; font-size: 15px; text-transform: none; - //min-width: 65px; padding: 0; } @@ -1244,7 +1243,6 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { background: #2e2e2e url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACKSURBVChTjdAxDsMgDAXQT4UYuQIzCwsSKxsSJ4YDoByDY7AwUOG2aZMQqX+xhd9gzIwxA3/k8a7LCCFgraX+Fk4UY4RSCoyxNfwgzjlyzhhjXOEvSimhtUbvB3hGUkp472m2wxUKIaD3TnOCd6jWim3bvlBrfdjJOUeolEJoZj/4PMH83bl/BXgCWSs2Z09IjgoAAAAASUVORK5CYII=) no-repeat bottom right; } - div#grid-section, body#entity-list-body { padding-bottom: 0; margin: 16px; @@ -1275,12 +1273,6 @@ div#grid-section, body#entity-list-body { border-bottom-left-radius: 0; } -/*#delete { - float: right; - margin-right: 0; - background-color: #ff0000; -}*/ - #entity-list { position: relative; /* New positioning context. */ } From 5b0a00a81aa5c97c22403e66324bda7dac8fcbb3 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 23 Oct 2020 23:21:32 -0400 Subject: [PATCH 49/74] Add Parent-Children Selector group Add Parent-Children Selector group Prevent action to happen when some entities are Locked in the Selection Code Adjustments --- scripts/system/create/edit.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 35bcd45786..69e2e94818 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -1696,7 +1696,7 @@ function recursiveDelete(entities, childrenList, deletedIDs, entityHostType) { } function unparentSelectedEntities() { - if (SelectionManager.hasSelection()) { + if (SelectionManager.hasSelection() && SelectionManager.hasUnlockedSelection()) { var selectedEntities = selectionManager.selections; var parentCheck = false; @@ -1733,11 +1733,11 @@ function unparentSelectedEntities() { } } else { audioFeedback.rejection(); - Window.notifyEditError("You have nothing selected to unparent"); + Window.notifyEditError("You have nothing selected or the selection has locked entities."); } } function parentSelectedEntities() { - if (SelectionManager.hasSelection()) { + if (SelectionManager.hasSelection() && SelectionManager.hasUnlockedSelection()) { var selectedEntities = selectionManager.selections; if (selectedEntities.length <= 1) { audioFeedback.rejection(); @@ -1768,11 +1768,11 @@ function parentSelectedEntities() { } } else { audioFeedback.rejection(); - Window.notifyEditError("You have nothing selected to parent"); + Window.notifyEditError("You have nothing selected or the selection has locked entities."); } } function deleteSelectedEntities() { - if (SelectionManager.hasSelection()) { + if (SelectionManager.hasSelection() && SelectionManager.hasUnlockedSelection()) { var deletedIDs = []; SelectionManager.saveProperties(); @@ -1803,6 +1803,9 @@ function deleteSelectedEntities() { pushCommandForSelections([], savedProperties); entityListTool.deleteEntities(deletedIDs); } + } else { + audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected or the selection has locked entities."); } } From 6da472b7e31d031db95844bf0831a7f51f498d43 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 23 Oct 2020 23:22:37 -0400 Subject: [PATCH 50/74] Add Parent-Children Selector group Add Parent-Children Selector group Prevent action to happen when some entities are Locked in the Selection Code Adjustments --- .../entitySelectionTool.js | 110 +++++++++++++++++- 1 file changed, 104 insertions(+), 6 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 0f8c8cc8bf..b4bf427a85 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -19,6 +19,7 @@ const SPACE_LOCAL = "local"; const SPACE_WORLD = "world"; const HIGHLIGHT_LIST_NAME = "editHandleHighlightList"; +const MIN_DISTANCE_TO_REZ_FROM_AVATAR = 3; Script.include([ "../../libraries/controllers.js", @@ -26,7 +27,6 @@ Script.include([ "../../libraries/utils.js" ]); - function deepCopy(v) { return JSON.parse(JSON.stringify(v)); } @@ -638,18 +638,19 @@ SelectionManager = (function() { that.teleportToEntity = function() { if (that.hasSelection()) { - var distanceFromTarget = 3 + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); + var distanceFromTarget = MIN_DISTANCE_TO_REZ_FROM_AVATAR + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); var teleportTargetPosition = Vec3.sum(that.worldPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: distanceFromTarget })); MyAvatar.goToLocation(teleportTargetPosition, false); } else { audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected."); } }; that.moveEntitiesSelectionToAvatar = function() { - if (that.hasSelection()) { + if (that.hasSelection() && that.hasUnlockedSelection()) { that.saveProperties(); - var distanceFromTarget = 3 + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); + var distanceFromTarget = MIN_DISTANCE_TO_REZ_FROM_AVATAR + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); var targetPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -distanceFromTarget })); // editing a parent will cause all the children to automatically follow along, so don't // edit any entity who has an ancestor in that.selections @@ -670,9 +671,106 @@ SelectionManager = (function() { that._update(false, this); } else { audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected or the selection has locked entities."); } }; + that.selectParent = function() { + if (that.hasSelection()) { + var currentSelection = that.selections; + that.selections = []; + for (var i = 0; i < currentSelection.length; i++) { + var properties = Entities.getEntityProperties(currentSelection[i], ['parentID']); + if (properties.parentID !== Uuid.NULL) { + that.selections.push(properties.parentID); + } + } + that._update(true, this); + } else { + audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected."); + } + }; + + that.selectTopParent = function() { + if (that.hasSelection()) { + var currentSelection = that.selections; + that.selections = []; + for (var i = 0; i < currentSelection.length; i++) { + var topParentId = getTopParent(currentSelection[i]); + if (topParentId !== Uuid.NULL) { + that.selections.push(topParentId); + } + } + that._update(true, this); + } else { + audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected."); + } + }; + + function getTopParent(id) { + var topParentId = Uuid.NULL; + var properties = Entities.getEntityProperties(id, ['parentID']); + if(properties.parentID === Uuid.NULL) { + topParentId = id; + } else { + topParentId = getTopParent(properties.parentID); + } + return topParentId; + } + + that.addChildrenToSelection = function() { + if (that.hasSelection()) { + for (var i = 0; i < that.selections.length; i++) { + var childrenIds = Entities.getChildrenIDs(that.selections[i]); + var collectNewChildren; + var j; + var k = 0; + do { + collectNewChildren = Entities.getChildrenIDs(childrenIds[k]); + if (collectNewChildren.length > 0) { + for (j = 0; j < collectNewChildren.length; j++) { + childrenIds.push(collectNewChildren[j]); + } + } + k++; + } while (k < childrenIds.length); + if (childrenIds.length > 0) { + for (j = 0; j < childrenIds.length; j++) { + that.selections.push(childrenIds[j]); + } + } + } + that._update(true, this); + } else { + audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected."); + } + }; + + that.hasUnlockedSelection = function() { + var selectionNotLocked = true; + for (var i = 0; i < that.selections.length; i++) { + var properties = Entities.getEntityProperties(that.selections[i], ['locked']); + if (properties.locked) { + selectionNotLocked = false; + break; + } + } + return selectionNotLocked; + }; + + that.selectFamily = function() { + that.selectParent(); + that.addChildrenToSelection(); + }; + + that.selectTopFamily = function() { + that.selectTopParent(); + that.addChildrenToSelection(); + }; + return that; })(); @@ -698,8 +796,8 @@ SelectionDisplay = (function() { const COLOR_DUPLICATOR = { red: 162, green: 0, blue: 255 }; const COLOR_ROTATE_CURRENT_RING = { red: 255, green: 99, blue: 9 }; const COLOR_BOUNDING_EDGE = { red: 160, green: 160, blue: 160 }; - const COLOR_BOUNDING_EDGE_PARENT = { red: 194, green: 123, blue: 0 }; //{ red: 255, green: 160, blue: 0 }; - const COLOR_BOUNDING_EDGE_CHILDREN = { red: 0, green: 168, blue: 214 }; // { red: 0, green: 200, blue: 255 } + const COLOR_BOUNDING_EDGE_PARENT = { red: 194, green: 123, blue: 0 }; + const COLOR_BOUNDING_EDGE_CHILDREN = { red: 0, green: 168, blue: 214 }; const COLOR_SCALE_CUBE = { red: 192, green: 192, blue: 192 }; const COLOR_DEBUG_PICK_PLANE = { red: 255, green: 255, blue: 255 }; const COLOR_DEBUG_PICK_PLANE_HIT = { red: 255, green: 165, blue: 0 }; From ba371613ba0be00a99fc4a4997cb5e71f012a5c7 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 23 Oct 2020 23:24:06 -0400 Subject: [PATCH 51/74] Add Parent-Children Selector group Add Parent-Children Selector group Prevent action to happen when some entities are Locked in the Selection Code Adjustments --- scripts/system/create/entityList/entityList.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index cb6beeaa4a..d0294c2c27 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -207,11 +207,11 @@ EntityListTool = function(shouldUseEditTabletApp) { var parentStatus = getParentState(ids[i]); var parentState = ""; if (parentStatus === "PARENT") { - parentState = "N"; + parentState = "A"; } else if (parentStatus === "CHILDREN") { - parentState = "O"; + parentState = "C"; } else if (parentStatus === "PARENT_CHILDREN") { - parentState = "M"; + parentState = "B"; } entities.push({ @@ -339,6 +339,16 @@ EntityListTool = function(shouldUseEditTabletApp) { selectAllEntitiesInCurrentSelectionBox(false); } else if (data.type === 'selectAllTouchingBox') { selectAllEntitiesInCurrentSelectionBox(true); + } else if (data.type === 'selectParent') { + SelectionManager.selectParent(); + } else if (data.type === 'selectTopParent') { + SelectionManager.selectTopParent(); + } else if (data.type === 'addChildrenToSelection') { + SelectionManager.addChildrenToSelection(); + } else if (data.type === 'selectFamily') { + SelectionManager.selectFamily(); + } else if (data.type === 'selectTopFamily') { + SelectionManager.selectTopFamily(); } else if (data.type === 'teleportToEntity') { SelectionManager.teleportToEntity(); } else if (data.type === 'moveEntitySelectionToAvatar') { From bfc216ab00abeafe0d3807e20b31d719f82904fe Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 23 Oct 2020 23:25:51 -0400 Subject: [PATCH 52/74] Add Parent-Children Selector group Add Parent-Children Selector group "Inverse Selection" is now responding to Ctrl-I Code Adjustments --- .../create/entityList/html/entityList.html | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index 361b1a2c70..242a91eeda 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -138,7 +138,7 @@ @@ -172,7 +172,7 @@ @@ -189,6 +189,37 @@
+ + + + + + From b3ab7e05d37ff4120bf65f47c2bacabc84bd822b Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sat, 24 Oct 2020 04:20:02 -0400 Subject: [PATCH 55/74] Add missing authorship comment. --- plugins/KasenAPIExample/src/ExampleScriptPlugin.h | 4 +++- plugins/KasenAPIExample/src/KasenAPIExample.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/KasenAPIExample/src/ExampleScriptPlugin.h b/plugins/KasenAPIExample/src/ExampleScriptPlugin.h index a6af105e0e..76c0a494d7 100644 --- a/plugins/KasenAPIExample/src/ExampleScriptPlugin.h +++ b/plugins/KasenAPIExample/src/ExampleScriptPlugin.h @@ -5,10 +5,12 @@ // Created by Kasen IO on 2019.07.14 | realities.dev | kasenvr@gmail.com // Copyright 2019 Kasen IO // +// Authored by: Humbletim (humbletim@gmail.com) +// // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// Supporting file containing all QtScript specific integration. +// Supporting file containing all QtScript specific integration. #ifndef EXAMPLE_SCRIPT_PLUGIN_H #define EXAMPLE_SCRIPT_PLUGIN_H diff --git a/plugins/KasenAPIExample/src/KasenAPIExample.cpp b/plugins/KasenAPIExample/src/KasenAPIExample.cpp index d446e98e6e..720c47f6cd 100644 --- a/plugins/KasenAPIExample/src/KasenAPIExample.cpp +++ b/plugins/KasenAPIExample/src/KasenAPIExample.cpp @@ -5,10 +5,12 @@ // Created by Kasen IO on 2019.07.14 | realities.dev | kasenvr@gmail.com // Copyright 2019 Kasen IO // +// Authored by: Humbletim (humbletim@gmail.com) +// // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// Example of prototyping new JS APIs by leveraging the existing plugin system. +// Example of prototyping new JS APIs by leveraging the existing plugin system. #include "ExampleScriptPlugin.h" From 0dadb100b1064da4eaead79e0855a51dea0e6e2a Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sat, 24 Oct 2020 04:49:01 -0400 Subject: [PATCH 56/74] Revert 0b46c53df17761d3799f6d5d3886eaf85e0c2dbe --- cmake/externals/polyvox/CMakeLists.txt | 78 ++++++++++++++ interface/CMakeLists.txt | 6 -- interface/src/Application.cpp | 2 +- libraries/audio-client/src/AudioClient.cpp | 2 +- .../networking/src/UserActivityLogger.cpp | 3 - libraries/script-engine/src/ScriptEngine.cpp | 101 ++---------------- plugins/CMakeLists.txt | 4 +- 7 files changed, 88 insertions(+), 108 deletions(-) create mode 100644 cmake/externals/polyvox/CMakeLists.txt diff --git a/cmake/externals/polyvox/CMakeLists.txt b/cmake/externals/polyvox/CMakeLists.txt new file mode 100644 index 0000000000..a92c07da86 --- /dev/null +++ b/cmake/externals/polyvox/CMakeLists.txt @@ -0,0 +1,78 @@ +set(EXTERNAL_NAME polyvox) + +include(ExternalProject) +ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://public.highfidelity.com/dependencies/polyvox-master-2015-7-15.zip + URL_MD5 9ec6323b87e849ae36e562ae1c7494a9 + CMAKE_ARGS -DENABLE_EXAMPLES=OFF -DENABLE_BINDINGS=OFF -DCMAKE_INSTALL_PREFIX:PATH= + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 +) + +# Hide this external target (for ide users) +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") + +ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + +if (APPLE) + set(INSTALL_NAME_LIBRARY_DIR ${INSTALL_DIR}/lib) + + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + change-install-name-debug + COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" + COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Debug -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake + DEPENDEES install + WORKING_DIRECTORY + LOG 1 + ) + + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + change-install-name-release + COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" + COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Release -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake + DEPENDEES install + WORKING_DIRECTORY + LOG 1 + ) +endif () + + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + +if (WIN32) + set(${EXTERNAL_NAME_UPPER}_CORE_INCLUDE_DIRS ${INSTALL_DIR}/PolyVoxCore/include CACHE FILEPATH + "Path to polyvox core include directory") + set(${EXTERNAL_NAME_UPPER}_UTIL_INCLUDE_DIRS ${INSTALL_DIR}/PolyVoxUtil/include CACHE FILEPATH + "Path to polyvox util include directory") +else () + set(${EXTERNAL_NAME_UPPER}_CORE_INCLUDE_DIRS ${INSTALL_DIR}/include/PolyVoxCore CACHE FILEPATH + "Path to polyvox core include directory") + set(${EXTERNAL_NAME_UPPER}_UTIL_INCLUDE_DIRS ${INSTALL_DIR}/include/PolyVoxUtil CACHE FILEPATH + "Path to polyvox util include directory") +endif () + + +if (WIN32) + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/PolyVoxCore/lib/Debug/PolyVoxCore.lib CACHE FILEPATH "polyvox core library") + + # use generator expression to ensure the correct library is found when building different configurations in VS + set(_LIB_FOLDER "$<$:PolyVoxCore/lib/RelWithDebInfo>") + set(_LIB_FOLDER "${_LIB_FOLDER}$<$:build/library/PolyVoxCore/MinSizeRel>") + set(_LIB_FOLDER "${_LIB_FOLDER}$<$,$>:PolyVoxCore/lib/Release>") + + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE "${INSTALL_DIR}/${_LIB_FOLDER}/PolyVoxCore.lib" CACHE FILEPATH "polyvox core library") +# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/PolyVoxUtil/lib/PolyVoxUtil.lib CACHE FILEPATH "polyvox util library") +elseif (APPLE) + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libPolyVoxCore.dylib CACHE FILEPATH "polyvox core library") + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libPolyVoxCore.dylib CACHE FILEPATH "polyvox core library") +# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/lib/libPolyVoxUtil.dylib CACHE FILEPATH "polyvox util library") +else () + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libPolyVoxCore.so CACHE FILEPATH "polyvox core library") + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libPolyVoxCore.so CACHE FILEPATH "polyvox core library") +# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/lib/libPolyVoxUtil.so CACHE FILEPATH "polyvox util library") +endif () diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 0a0ade149d..7d54065286 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -165,8 +165,6 @@ elseif (WIN32) # add an executable that also has the icon itself and the configured rc file as resources add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) - ##^^^^^ creates native Win32 app w/o cmd console vvvvvv forces cmd console for logging - # add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) if (NOT DEV_BUILD) add_custom_command( @@ -190,10 +188,6 @@ if (BUILD_TOOLS AND NPM_EXECUTABLE) add_dependencies(resources jsdoc) endif() -if (WIN32 OR APPLE) - add_dependencies(${TARGET_NAME} resources screenshare) -endif() - if (WIN32) # These are external plugins, but we need to do the 'add dependency' here so that their diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b76e3f8dca..7002780e4e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7164,7 +7164,7 @@ void Application::updateWindowTitle() const { bool isDomainLoggedIn = domainAccountManager->isLoggedIn(); QString authedDomainName = domainAccountManager->getAuthedDomainName(); - QString buildVersion = " - Vircadia - " + QString buildVersion = " - " + (BuildInfo::BUILD_TYPE == BuildInfo::BuildType::Stable ? QString("Version") : QString("Build")) + " " + applicationVersion(); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 8d96a2e6b5..911da25c36 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -2163,7 +2163,7 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi int deviceChannelCount = _outputFormat.channelCount(); int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE; - _audioOutput->setBufferSize(requestedSize * 16); + _audioOutput->setBufferSize(requestedSize); connect(_audioOutput, &QAudioOutput::notify, this, &AudioClient::outputNotify); diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 94d6371ba4..3c1cbc315b 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -39,9 +39,6 @@ void UserActivityLogger::crashMonitorDisable(bool disable) { } void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCallbackParameters params) { -// qCDebug(networking).nospace() << ">>> UserActivityLogger::logAction(" << action << "," << QJsonDocument(details).toJson(); -// This logs what the UserActivityLogger would normally send to centralized servers. - return; if (_disabled.get()) { return; } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index c5c6c1fef1..4523c50e74 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -307,7 +307,7 @@ QString ScriptEngine::getContext() const { return "unknown"; } -bool ScriptEngine::isDebugMode() const { +bool ScriptEngine::isDebugMode() const { #if defined(DEBUG) return true; #else @@ -875,11 +875,6 @@ void ScriptEngine::init() { #if DEV_BUILD || PR_BUILD registerGlobalObject("StackTest", new StackTestScriptingInterface(this)); #endif - - globalObject().setProperty("KALILA", "isWaifu"); - globalObject().setProperty("Kute", newFunction([](QScriptContext* context, QScriptEngine* engine) -> QScriptValue { - return context->argument(0).toString().toLower() == "kalila" ? true : false; - })); } void ScriptEngine::registerEnum(const QString& enumName, QMetaEnum newEnum) { @@ -2444,7 +2439,6 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co BaseScriptEngine sandbox; sandbox.setProcessEventsInterval(SANDBOX_TIMEOUT); QScriptValue testConstructor, exception; - if (atoi(getenv("UNSAFE_ENTITY_SCRIPTS") ? getenv("UNSAFE_ENTITY_SCRIPTS") : "0")) { QTimer timeout; timeout.setSingleShot(true); @@ -2466,94 +2460,14 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co } else if (testConstructor.isError()) { exception = testConstructor; } - } else { - // ENTITY SCRIPT WHITELIST STARTS HERE - auto nodeList = DependencyManager::get(); - bool passList = false; // assume unsafe - QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]"; - QList safeURLPrefixes = { "file:///", "atp:", "cache:" }; - safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); - - // Entity Script Whitelist toggle check. - Setting::Handle whitelistEnabled {"private/whitelistEnabled", false }; - - if (!whitelistEnabled.get()) { - passList = true; - } - - // Pull SAFEURLS from the Interface.JSON settings. - QVariant raw = Setting::Handle("private/settingsSafeURLS").get(); - QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts); - safeURLPrefixes += settingsSafeURLS; - // END Pull SAFEURLS from the Interface.JSON settings. - - // Get current domain whitelist bypass, in case an entire domain is whitelisted. - QString currentDomain = DependencyManager::get()->getDomainURL().host(); - - QString domainSafeIP = nodeList->getDomainHandler().getHostname(); - QString domainSafeURL = URL_SCHEME_HIFI + "://" + currentDomain; - for (const auto& str : safeURLPrefixes) { - if (domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) { - qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed, entire domain is whitelisted. Current Domain Host: " - << nodeList->getDomainHandler().getHostname() - << "Current Domain: " << currentDomain; - passList = true; - } - } - // END bypass whitelist based on current domain. - - // Start processing scripts through the whitelist. - if (ScriptEngine::getContext() == "entity_server") { // If running on the server, do not engage whitelist. - passList = true; - } else if (!passList) { // If waved through, do not engage whitelist. - for (const auto& str : safeURLPrefixes) { - qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" - << scriptOrURL.startsWith(str); - if (!str.isEmpty() && scriptOrURL.startsWith(str)) { - passList = true; - qCDebug(scriptengine) << whitelistPrefix << "Script approved."; - break; // Bail early since we found a match. - } - } - } - // END processing of scripts through the whitelist. - - if (!passList) { // If the entity failed to pass for any reason, it's blocked and an error is thrown. - qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL; - exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); - } else { - QTimer timeout; - timeout.setSingleShot(true); - timeout.start(SANDBOX_TIMEOUT); - connect(&timeout, &QTimer::timeout, [=, &sandbox] { - qCDebug(scriptengine) << "ScriptEngine::entityScriptContentAvailable timeout"; - - // Guard against infinite loops and non-performant code - sandbox.raiseException( - sandbox.makeError(QString("Timed out (entity constructors are limited to %1ms)").arg(SANDBOX_TIMEOUT))); - }); - - testConstructor = sandbox.evaluate(program); - - if (sandbox.hasUncaughtException()) { - exception = sandbox.cloneUncaughtException(QString("(preflight %1)").arg(entityID.toString())); - sandbox.clearExceptions(); - } else if (testConstructor.isError()) { - exception = testConstructor; - } - } - // ENTITY SCRIPT WHITELIST ENDS HERE, uncomment below for original full disabling. - - // qDebug() << "(disabled entity script)" << entityID.toString() << scriptOrURL; - // exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); } if (exception.isError()) { - // create a local copy using makeError to decouple from the sandbox engine - exception = makeError(exception); - setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); - emit unhandledException(exception); - return; + // create a local copy using makeError to decouple from the sandbox engine + exception = makeError(exception); + setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); + emit unhandledException(exception); + return; } // CONSTRUCTOR VIABILITY @@ -2925,6 +2839,3 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS } } -QString ScriptEngine::getExternalPath(ExternalResource::Bucket bucket, const QString& path) { - return ExternalResource::getInstance()->getUrl(bucket, path); -} diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 1448e14c72..11ff195d56 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -9,7 +9,7 @@ # add the plugin directories file(GLOB PLUGIN_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles") -set(CMAKE_BUILD_TYPE "Release") + # client-side plugins if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "oculus") @@ -25,7 +25,7 @@ if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "hifiSixense") add_subdirectory(${DIR}) endif() - + set(DIR "hifiSpacemouse") add_subdirectory(${DIR}) set(DIR "hifiNeuron") From 96877db43a73fedc2f0315b501a08156c5a8da20 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sat, 24 Oct 2020 05:02:45 -0400 Subject: [PATCH 57/74] Re-apply 0dadb100b1064da4eaead79e0855a51dea0e6e2a w/ authorship. Co-Authored-By: Humbletim --- cmake/externals/polyvox/CMakeLists.txt | 78 -------------- interface/CMakeLists.txt | 6 ++ interface/src/Application.cpp | 2 +- libraries/audio-client/src/AudioClient.cpp | 2 +- .../networking/src/UserActivityLogger.cpp | 3 + libraries/script-engine/src/ScriptEngine.cpp | 101 ++++++++++++++++-- plugins/CMakeLists.txt | 4 +- 7 files changed, 108 insertions(+), 88 deletions(-) delete mode 100644 cmake/externals/polyvox/CMakeLists.txt diff --git a/cmake/externals/polyvox/CMakeLists.txt b/cmake/externals/polyvox/CMakeLists.txt deleted file mode 100644 index a92c07da86..0000000000 --- a/cmake/externals/polyvox/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -set(EXTERNAL_NAME polyvox) - -include(ExternalProject) -ExternalProject_Add( - ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/polyvox-master-2015-7-15.zip - URL_MD5 9ec6323b87e849ae36e562ae1c7494a9 - CMAKE_ARGS -DENABLE_EXAMPLES=OFF -DENABLE_BINDINGS=OFF -DCMAKE_INSTALL_PREFIX:PATH= - BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build - LOG_DOWNLOAD 1 - LOG_CONFIGURE 1 - LOG_BUILD 1 -) - -# Hide this external target (for ide users) -set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") - -ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) - -if (APPLE) - set(INSTALL_NAME_LIBRARY_DIR ${INSTALL_DIR}/lib) - - ExternalProject_Add_Step( - ${EXTERNAL_NAME} - change-install-name-debug - COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" - COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Debug -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake - DEPENDEES install - WORKING_DIRECTORY - LOG 1 - ) - - ExternalProject_Add_Step( - ${EXTERNAL_NAME} - change-install-name-release - COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" - COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Release -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake - DEPENDEES install - WORKING_DIRECTORY - LOG 1 - ) -endif () - - -string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) - -if (WIN32) - set(${EXTERNAL_NAME_UPPER}_CORE_INCLUDE_DIRS ${INSTALL_DIR}/PolyVoxCore/include CACHE FILEPATH - "Path to polyvox core include directory") - set(${EXTERNAL_NAME_UPPER}_UTIL_INCLUDE_DIRS ${INSTALL_DIR}/PolyVoxUtil/include CACHE FILEPATH - "Path to polyvox util include directory") -else () - set(${EXTERNAL_NAME_UPPER}_CORE_INCLUDE_DIRS ${INSTALL_DIR}/include/PolyVoxCore CACHE FILEPATH - "Path to polyvox core include directory") - set(${EXTERNAL_NAME_UPPER}_UTIL_INCLUDE_DIRS ${INSTALL_DIR}/include/PolyVoxUtil CACHE FILEPATH - "Path to polyvox util include directory") -endif () - - -if (WIN32) - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/PolyVoxCore/lib/Debug/PolyVoxCore.lib CACHE FILEPATH "polyvox core library") - - # use generator expression to ensure the correct library is found when building different configurations in VS - set(_LIB_FOLDER "$<$:PolyVoxCore/lib/RelWithDebInfo>") - set(_LIB_FOLDER "${_LIB_FOLDER}$<$:build/library/PolyVoxCore/MinSizeRel>") - set(_LIB_FOLDER "${_LIB_FOLDER}$<$,$>:PolyVoxCore/lib/Release>") - - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE "${INSTALL_DIR}/${_LIB_FOLDER}/PolyVoxCore.lib" CACHE FILEPATH "polyvox core library") -# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/PolyVoxUtil/lib/PolyVoxUtil.lib CACHE FILEPATH "polyvox util library") -elseif (APPLE) - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libPolyVoxCore.dylib CACHE FILEPATH "polyvox core library") - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libPolyVoxCore.dylib CACHE FILEPATH "polyvox core library") -# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/lib/libPolyVoxUtil.dylib CACHE FILEPATH "polyvox util library") -else () - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libPolyVoxCore.so CACHE FILEPATH "polyvox core library") - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libPolyVoxCore.so CACHE FILEPATH "polyvox core library") -# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/lib/libPolyVoxUtil.so CACHE FILEPATH "polyvox util library") -endif () diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 7d54065286..0a0ade149d 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -165,6 +165,8 @@ elseif (WIN32) # add an executable that also has the icon itself and the configured rc file as resources add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) + ##^^^^^ creates native Win32 app w/o cmd console vvvvvv forces cmd console for logging + # add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) if (NOT DEV_BUILD) add_custom_command( @@ -188,6 +190,10 @@ if (BUILD_TOOLS AND NPM_EXECUTABLE) add_dependencies(resources jsdoc) endif() +if (WIN32 OR APPLE) + add_dependencies(${TARGET_NAME} resources screenshare) +endif() + if (WIN32) # These are external plugins, but we need to do the 'add dependency' here so that their diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7002780e4e..b76e3f8dca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7164,7 +7164,7 @@ void Application::updateWindowTitle() const { bool isDomainLoggedIn = domainAccountManager->isLoggedIn(); QString authedDomainName = domainAccountManager->getAuthedDomainName(); - QString buildVersion = " - " + QString buildVersion = " - Vircadia - " + (BuildInfo::BUILD_TYPE == BuildInfo::BuildType::Stable ? QString("Version") : QString("Build")) + " " + applicationVersion(); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 911da25c36..8d96a2e6b5 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -2163,7 +2163,7 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi int deviceChannelCount = _outputFormat.channelCount(); int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE; - _audioOutput->setBufferSize(requestedSize); + _audioOutput->setBufferSize(requestedSize * 16); connect(_audioOutput, &QAudioOutput::notify, this, &AudioClient::outputNotify); diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 3c1cbc315b..94d6371ba4 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -39,6 +39,9 @@ void UserActivityLogger::crashMonitorDisable(bool disable) { } void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCallbackParameters params) { +// qCDebug(networking).nospace() << ">>> UserActivityLogger::logAction(" << action << "," << QJsonDocument(details).toJson(); +// This logs what the UserActivityLogger would normally send to centralized servers. + return; if (_disabled.get()) { return; } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 4523c50e74..c5c6c1fef1 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -307,7 +307,7 @@ QString ScriptEngine::getContext() const { return "unknown"; } -bool ScriptEngine::isDebugMode() const { +bool ScriptEngine::isDebugMode() const { #if defined(DEBUG) return true; #else @@ -875,6 +875,11 @@ void ScriptEngine::init() { #if DEV_BUILD || PR_BUILD registerGlobalObject("StackTest", new StackTestScriptingInterface(this)); #endif + + globalObject().setProperty("KALILA", "isWaifu"); + globalObject().setProperty("Kute", newFunction([](QScriptContext* context, QScriptEngine* engine) -> QScriptValue { + return context->argument(0).toString().toLower() == "kalila" ? true : false; + })); } void ScriptEngine::registerEnum(const QString& enumName, QMetaEnum newEnum) { @@ -2439,6 +2444,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co BaseScriptEngine sandbox; sandbox.setProcessEventsInterval(SANDBOX_TIMEOUT); QScriptValue testConstructor, exception; + if (atoi(getenv("UNSAFE_ENTITY_SCRIPTS") ? getenv("UNSAFE_ENTITY_SCRIPTS") : "0")) { QTimer timeout; timeout.setSingleShot(true); @@ -2460,14 +2466,94 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co } else if (testConstructor.isError()) { exception = testConstructor; } + } else { + // ENTITY SCRIPT WHITELIST STARTS HERE + auto nodeList = DependencyManager::get(); + bool passList = false; // assume unsafe + QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]"; + QList safeURLPrefixes = { "file:///", "atp:", "cache:" }; + safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); + + // Entity Script Whitelist toggle check. + Setting::Handle whitelistEnabled {"private/whitelistEnabled", false }; + + if (!whitelistEnabled.get()) { + passList = true; + } + + // Pull SAFEURLS from the Interface.JSON settings. + QVariant raw = Setting::Handle("private/settingsSafeURLS").get(); + QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts); + safeURLPrefixes += settingsSafeURLS; + // END Pull SAFEURLS from the Interface.JSON settings. + + // Get current domain whitelist bypass, in case an entire domain is whitelisted. + QString currentDomain = DependencyManager::get()->getDomainURL().host(); + + QString domainSafeIP = nodeList->getDomainHandler().getHostname(); + QString domainSafeURL = URL_SCHEME_HIFI + "://" + currentDomain; + for (const auto& str : safeURLPrefixes) { + if (domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) { + qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed, entire domain is whitelisted. Current Domain Host: " + << nodeList->getDomainHandler().getHostname() + << "Current Domain: " << currentDomain; + passList = true; + } + } + // END bypass whitelist based on current domain. + + // Start processing scripts through the whitelist. + if (ScriptEngine::getContext() == "entity_server") { // If running on the server, do not engage whitelist. + passList = true; + } else if (!passList) { // If waved through, do not engage whitelist. + for (const auto& str : safeURLPrefixes) { + qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" + << scriptOrURL.startsWith(str); + if (!str.isEmpty() && scriptOrURL.startsWith(str)) { + passList = true; + qCDebug(scriptengine) << whitelistPrefix << "Script approved."; + break; // Bail early since we found a match. + } + } + } + // END processing of scripts through the whitelist. + + if (!passList) { // If the entity failed to pass for any reason, it's blocked and an error is thrown. + qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL; + exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); + } else { + QTimer timeout; + timeout.setSingleShot(true); + timeout.start(SANDBOX_TIMEOUT); + connect(&timeout, &QTimer::timeout, [=, &sandbox] { + qCDebug(scriptengine) << "ScriptEngine::entityScriptContentAvailable timeout"; + + // Guard against infinite loops and non-performant code + sandbox.raiseException( + sandbox.makeError(QString("Timed out (entity constructors are limited to %1ms)").arg(SANDBOX_TIMEOUT))); + }); + + testConstructor = sandbox.evaluate(program); + + if (sandbox.hasUncaughtException()) { + exception = sandbox.cloneUncaughtException(QString("(preflight %1)").arg(entityID.toString())); + sandbox.clearExceptions(); + } else if (testConstructor.isError()) { + exception = testConstructor; + } + } + // ENTITY SCRIPT WHITELIST ENDS HERE, uncomment below for original full disabling. + + // qDebug() << "(disabled entity script)" << entityID.toString() << scriptOrURL; + // exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); } if (exception.isError()) { - // create a local copy using makeError to decouple from the sandbox engine - exception = makeError(exception); - setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); - emit unhandledException(exception); - return; + // create a local copy using makeError to decouple from the sandbox engine + exception = makeError(exception); + setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); + emit unhandledException(exception); + return; } // CONSTRUCTOR VIABILITY @@ -2839,3 +2925,6 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS } } +QString ScriptEngine::getExternalPath(ExternalResource::Bucket bucket, const QString& path) { + return ExternalResource::getInstance()->getUrl(bucket, path); +} diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 11ff195d56..1448e14c72 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -9,7 +9,7 @@ # add the plugin directories file(GLOB PLUGIN_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles") - +set(CMAKE_BUILD_TYPE "Release") # client-side plugins if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "oculus") @@ -25,7 +25,7 @@ if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "hifiSixense") add_subdirectory(${DIR}) endif() - + set(DIR "hifiSpacemouse") add_subdirectory(${DIR}) set(DIR "hifiNeuron") From bcebf36261cb14bb4106bbf5d50aefb70eaf1ec0 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 24 Oct 2020 13:19:09 -0400 Subject: [PATCH 58/74] Minor Code Adjustments Minor Code Adjustments --- .../entitySelectionTool/entitySelectionTool.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index b4bf427a85..ffa828affe 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -712,7 +712,7 @@ SelectionManager = (function() { function getTopParent(id) { var topParentId = Uuid.NULL; var properties = Entities.getEntityProperties(id, ['parentID']); - if(properties.parentID === Uuid.NULL) { + if (properties.parentID === Uuid.NULL) { topParentId = id; } else { topParentId = getTopParent(properties.parentID); @@ -723,22 +723,22 @@ SelectionManager = (function() { that.addChildrenToSelection = function() { if (that.hasSelection()) { for (var i = 0; i < that.selections.length; i++) { - var childrenIds = Entities.getChildrenIDs(that.selections[i]); + var childrenIDs = Entities.getChildrenIDs(that.selections[i]); var collectNewChildren; var j; var k = 0; do { - collectNewChildren = Entities.getChildrenIDs(childrenIds[k]); + collectNewChildren = Entities.getChildrenIDs(childrenIDs[k]); if (collectNewChildren.length > 0) { for (j = 0; j < collectNewChildren.length; j++) { - childrenIds.push(collectNewChildren[j]); + childrenIDs.push(collectNewChildren[j]); } } k++; - } while (k < childrenIds.length); - if (childrenIds.length > 0) { - for (j = 0; j < childrenIds.length; j++) { - that.selections.push(childrenIds[j]); + } while (k < childrenIDs.length); + if (childrenIDs.length > 0) { + for (j = 0; j < childrenIDs.length; j++) { + that.selections.push(childrenIDs[j]); } } } From 8cc9c19b4037c935365713ba2283a1d1bccea858 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 24 Oct 2020 22:37:35 -0400 Subject: [PATCH 59/74] Set the shortkey CTRL-A and CTRL-I only Set the shortkeys for Select All and Inverse Selection to respond to CTRL-A and CTRL-I only. (Previously it was also responding to Ctrl-Shift-A, Ctrl-Alt-A, Ctrl-Shift-Alt-A and Ctrl-Shift-I, Ctrl-Alt-I, Ctrl-Shift-Alt-I) --- scripts/system/create/entityList/html/js/entityList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 4d152688b8..7cdcd7a6fc 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -1542,7 +1542,7 @@ function loaded() { break; } - if (controlKey && keyCodeString === "A") { + if (controlKey && !shiftKey && !altKey && keyCodeString === "A") { let visibleEntityIDs = visibleEntities.map(visibleEntity => visibleEntity.id); let selectionIncludesAllVisibleEntityIDs = visibleEntityIDs.every(visibleEntityID => { return selectedEntities.includes(visibleEntityID); @@ -1565,7 +1565,7 @@ function loaded() { return; } - if (controlKey && keyCodeString === "I") { + if (controlKey && !shiftKey && !altKey && keyCodeString === "I") { let visibleEntityIDs = visibleEntities.map(visibleEntity => visibleEntity.id); let selectionIncludesAllVisibleEntityIDs = visibleEntityIDs.every(visibleEntityID => { return selectedEntities.includes(visibleEntityID); From 7c4115c4cf0535c27732300194f154d022a2fd48 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 24 Oct 2020 23:59:26 -0400 Subject: [PATCH 60/74] Expose 2 new columns: Creation and Modification Date Expose 2 new optional columns: - Creation Date - Modification Date To address Issue #673 --- .../system/create/entityList/entityList.js | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index d0294c2c27..623e0b7326 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -190,7 +190,7 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("getMultipleProperties", function () { var multipleProperties = Entities.getMultipleEntityProperties(ids, ['position', 'name', 'type', 'locked', 'visible', 'renderInfo', 'modelURL', 'materialURL', 'imageURL', 'script', 'certificateID', - 'skybox.url', 'ambientLight.url']); + 'skybox.url', 'ambientLight.url', 'created', 'lastEdited']); for (var i = 0; i < multipleProperties.length; i++) { var properties = multipleProperties[i]; @@ -234,7 +234,9 @@ EntityListTool = function(shouldUseEditTabletApp) { drawCalls: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.drawCalls) : ""), hasScript: properties.script !== "", - parentState: parentState + parentState: parentState, + created: formatToStringDateTime(properties.created), + lastEdited: formatToStringDateTime(properties.lastEdited), }); } } @@ -254,6 +256,20 @@ EntityListTool = function(shouldUseEditTabletApp) { }); }; + function formatToStringDateTime(timestamp) { + var d = new Date(Math.floor(timestamp/1000)); + var dateTime = d.getUTCFullYear() + "-" + zeroPad((d.getUTCMonth() + 1), 2) + "-" + zeroPad(d.getUTCDate(), 2); + dateTime = dateTime + " " + zeroPad(d.getUTCHours(),2) + ":" + zeroPad(d.getUTCMinutes(), 2) + ":" + zeroPad(d.getUTCSeconds(), 2); + dateTime = dateTime + "." + zeroPad(d.getUTCMilliseconds(), 3); + return dateTime; + } + + function zeroPad(num, size) { + num = num.toString(); + while (num.length < size) num = "0" + num; + return num; + } + function onFileSaveChanged(filename) { Window.saveFileChanged.disconnect(onFileSaveChanged); if (filename !== "") { From a264fc358ef574cd4fd84b4f7246f3e5baaf1102 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 25 Oct 2020 00:00:44 -0400 Subject: [PATCH 61/74] Expose 2 new columns: Creation and Modif. Date Expose 2 new optional columns: - Creation Date - Modification Date To address Issue #673 --- .../create/entityList/html/js/entityList.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 7cdcd7a6fc..be79593511 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -141,7 +141,21 @@ const COLUMNS = { propertyID: "hasScript", initialWidth: 0.06, defaultSortOrder: DESCENDING_SORT, - }, + }, + created: { + columnHeader: "Created (UTC)", + dropdownLabel: "Creation Date", + propertyID: "created", + initialWidth: 0.38, + defaultSortOrder: DESCENDING_SORT, + }, + lastEdited: { + columnHeader: "Modified (UTC)", + dropdownLabel: "Modification Date", + propertyID: "lastEdited", + initialWidth: 0.38, + defaultSortOrder: DESCENDING_SORT, + }, }; const FILTER_TYPES = [ @@ -842,6 +856,8 @@ function loaded() { drawCalls: displayIfNonZero(entity.drawCalls), hasScript: entity.hasScript, parentState: entity.parentState, + created: entity.created, + lastEdited: entity.lastEdited, elRow: null, // if this entity has a visible row element assigned to it selected: false // if this entity is selected for edit regardless of having a visible row }; From 1e51df0843a0c46f899f50414129e5cba741a6b0 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 25 Oct 2020 14:25:19 -0400 Subject: [PATCH 62/74] Minor adjustments Minor adjustments --- scripts/system/create/entityList/entityList.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 623e0b7326..252481d44d 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -236,7 +236,7 @@ EntityListTool = function(shouldUseEditTabletApp) { hasScript: properties.script !== "", parentState: parentState, created: formatToStringDateTime(properties.created), - lastEdited: formatToStringDateTime(properties.lastEdited), + lastEdited: formatToStringDateTime(properties.lastEdited) }); } } @@ -259,14 +259,16 @@ EntityListTool = function(shouldUseEditTabletApp) { function formatToStringDateTime(timestamp) { var d = new Date(Math.floor(timestamp/1000)); var dateTime = d.getUTCFullYear() + "-" + zeroPad((d.getUTCMonth() + 1), 2) + "-" + zeroPad(d.getUTCDate(), 2); - dateTime = dateTime + " " + zeroPad(d.getUTCHours(),2) + ":" + zeroPad(d.getUTCMinutes(), 2) + ":" + zeroPad(d.getUTCSeconds(), 2); + dateTime = dateTime + " " + zeroPad(d.getUTCHours(), 2) + ":" + zeroPad(d.getUTCMinutes(), 2) + ":" + zeroPad(d.getUTCSeconds(), 2); dateTime = dateTime + "." + zeroPad(d.getUTCMilliseconds(), 3); return dateTime; } function zeroPad(num, size) { num = num.toString(); - while (num.length < size) num = "0" + num; + while (num.length < size) { + num = "0" + num; + } return num; } From 50067e3361db39278e54d90777c9ae4491e53b2e Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sun, 25 Oct 2020 18:36:20 -0400 Subject: [PATCH 63/74] Prevent crash on entity-script-server for due to logging interface. --- libraries/script-engine/src/ScriptEngine.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index c5c6c1fef1..b3b0b26293 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -130,6 +130,11 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) { // This message was sent by one of our script engines, let's try to see if we can find the source. // Note that the first entry in the backtrace should be "print" and is somewhat useless to us AbstractLoggerInterface* loggerInterface = AbstractLoggerInterface::get(); + if (!loggerInterface) { + qCDebug(scriptengine_script, "%s", qUtf8Printable(message)); + return QScriptValue(); + } + if (loggerInterface->showSourceDebugging()) { QScriptContext* userContext = context; while (userContext && QScriptContextInfo(userContext).functionType() == QScriptContextInfo::NativeFunction) { From 4b2c71cf6175e7d07b805c44fb91c010ff6dc836 Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Sun, 25 Oct 2020 19:49:59 -0400 Subject: [PATCH 64/74] Update libraries/script-engine/src/ScriptEngine.cpp Co-authored-by: David Rowe --- libraries/script-engine/src/ScriptEngine.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index b3b0b26293..88c682370c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -130,12 +130,7 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) { // This message was sent by one of our script engines, let's try to see if we can find the source. // Note that the first entry in the backtrace should be "print" and is somewhat useless to us AbstractLoggerInterface* loggerInterface = AbstractLoggerInterface::get(); - if (!loggerInterface) { - qCDebug(scriptengine_script, "%s", qUtf8Printable(message)); - return QScriptValue(); - } - - if (loggerInterface->showSourceDebugging()) { + if (loggerInterface && loggerInterface->showSourceDebugging()) { QScriptContext* userContext = context; while (userContext && QScriptContextInfo(userContext).functionType() == QScriptContextInfo::NativeFunction) { userContext = userContext->parentContext(); From d31d7f0a1815d06da2db19e948653efe1927d59c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 26 Oct 2020 14:36:36 +1300 Subject: [PATCH 65/74] Hide "secure transactions" section in Settings > Security --- interface/resources/qml/hifi/dialogs/security/Security.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/resources/qml/hifi/dialogs/security/Security.qml b/interface/resources/qml/hifi/dialogs/security/Security.qml index b1f62633e7..1da20838b6 100644 --- a/interface/resources/qml/hifi/dialogs/security/Security.qml +++ b/interface/resources/qml/hifi/dialogs/security/Security.qml @@ -333,6 +333,8 @@ Rectangle { anchors.left: parent.left; anchors.right: parent.right; height: childrenRect.height; + // FIXME: Reuse or remove wallet-related code. + visible: false; Rectangle { id: walletHeaderContainer; From e0d965e1c567f572f572c06c9df85775836b2d69 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 27 Oct 2020 09:44:43 +1300 Subject: [PATCH 66/74] Fix wrapping of "Enable Automatic Threading" in server setup wizard --- domain-server/resources/web/wizard/index.shtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/wizard/index.shtml b/domain-server/resources/web/wizard/index.shtml index c15b4169ed..6d56a99682 100644 --- a/domain-server/resources/web/wizard/index.shtml +++ b/domain-server/resources/web/wizard/index.shtml @@ -204,7 +204,7 @@

-

+

From 6232aba63e75359433da4b5d61c3721fafd699f1 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Tue, 27 Oct 2020 01:22:47 -0400 Subject: [PATCH 67/74] Fix domain-server settings "Create new domain ID" dialog. --- .../resources/web/settings/js/settings.js | 81 +++++++++++-------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 18d07fa6ef..9c4b654507 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -356,7 +356,7 @@ $(document).ready(function(){ }); } - function showDomainCreationAlert(justConnected) { + function showDomainCreationAlert (justConnected) { swal({ title: 'Create new domain ID', type: 'input', @@ -365,7 +365,7 @@ $(document).ready(function(){ confirmButtonText: "Create", closeOnConfirm: false, html: true - }, function(inputValue){ + }, function (inputValue) { if (inputValue === false) { swal.close(); @@ -375,19 +375,24 @@ $(document).ready(function(){ } } else { // we're going to change the alert to a new one with a spinner while we create this domain - showSpinnerAlert('Creating domain ID'); + // showSpinnerAlert('Creating domain ID'); createNewDomainID(inputValue, justConnected); } }); } - function createNewDomainID(label, justConnected) { + function createNewDomainID (label, justConnected) { // get the JSON object ready that we'll use to create a new domain var domainJSON = { "label": label } - $.post("/api/domains", domainJSON, function(data){ + $.post("/api/domains", domainJSON, function(data) { + if (data.status === "failure") { + failedToCreateDomainID(data, justConnected); + return; + } + // we successfully created a domain ID, set it on that field var domainID = data.domain.domainId; console.log("Setting domain id to ", data, domainID); @@ -408,40 +413,50 @@ $(document).ready(function(){ text: successText, html: true, confirmButtonText: 'Save' - }, function(){ + }, function() { saveSettings(); }); - }, 'json').fail(function(){ + }, 'json').fail(function(data) { + failedToCreateDomainID(data, justConnected); + }); + } + + function failedToCreateDomainID (data, justConnected) { + var errorText = "There was a problem creating your new domain ID. Do you want to try again or"; - var errorText = "There was a problem creating your new domain ID. Do you want to try again or"; + if (data && data.status === "failure") { + errorText = "Error: " + data.error + "
Do you want to try again or"; + console.log("Error: " + data.error); + } else { + console.log("Error: Failed to post to metaverse."); + } - if (justConnected) { - errorText += " just save your new access token?

You can always create a new domain ID later."; + if (justConnected) { + errorText += " just save your new access token?

You can always create a new domain ID later."; + } else { + errorText += " cancel?" + } + + // we failed to create the new domain ID, show a sweet-alert that lets them try again or cancel + swal({ + title: '', + type: 'error', + text: errorText, + html: true, + confirmButtonText: 'Try again', + showCancelButton: true, + closeOnConfirm: false + }, function (isConfirm) { + if (isConfirm) { + // they want to try creating a domain ID again + showDomainCreationAlert(justConnected); } else { - errorText += " cancel?" - } - - // we failed to create the new domain ID, show a sweet-alert that lets them try again or cancel - swal({ - title: '', - type: 'error', - text: errorText, - html: true, - confirmButtonText: 'Try again', - showCancelButton: true, - closeOnConfirm: false - }, function(isConfirm){ - if (isConfirm) { - // they want to try creating a domain ID again - showDomainCreationAlert(justConnected); - } else { - // they want to cancel - if (justConnected) { - // since they just connected we need to save the access token here - saveSettings(); - } + // they want to cancel + if (justConnected) { + // since they just connected we need to save the access token here + saveSettings(); } - }); + } }); } From 32843133993c7350d4108a8c39f5b3072bb20c6d Mon Sep 17 00:00:00 2001 From: Dale Glass Date: Tue, 27 Oct 2020 01:19:22 +0100 Subject: [PATCH 68/74] Mark font textures as something that shouldn't be downscaled --- libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp | 4 ++-- libraries/gpu/src/gpu/Texture.h | 4 ++++ libraries/render-utils/src/text/Font.cpp | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp index 2b9b209c67..af865b3ad7 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp @@ -223,7 +223,7 @@ void GLTextureTransferEngineDefault::updateMemoryPressure() { idealMemoryAllocation += texture->evalTotalSize(); // Track how much we're actually using totalVariableMemoryAllocation += gltexture->size(); - if (vartexture->canDemote()) { + if (!gltexture->_gpuObject.getImportant() && vartexture->canDemote()) { canDemote |= true; } if (vartexture->canPromote()) { @@ -503,7 +503,7 @@ void GLTextureTransferEngineDefault::processDemotes(size_t reliefRequired, const for (const auto& texture : strongTextures) { GLTexture* gltexture = Backend::getGPUObject(*texture); GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture); - if (vargltexture->canDemote()) { + if (!gltexture->_gpuObject.getImportant() && vargltexture->canDemote()) { demoteQueue.push({ texture, (float)gltexture->size() }); } } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index debedf02a5..54c7d49421 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -571,6 +571,9 @@ public: void setExternalRecycler(const ExternalRecycler& recycler); ExternalRecycler getExternalRecycler() const; + bool getImportant() const { return _important; } + void setImportant(bool important) { _important = important; } + const GPUObjectPointer gpuObject {}; ExternalUpdates getUpdates() const; @@ -632,6 +635,7 @@ protected: bool _autoGenerateMips = false; bool _isIrradianceValid = false; bool _defined = false; + bool _important = false; static TexturePointer create(TextureUsageType usageType, Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips, const Sampler& sampler); diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 024be6598d..a30bbad0e5 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -260,6 +260,7 @@ void Font::read(QIODevice& in) { gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR)); _texture->setStoredMipFormat(formatMip); _texture->assignStoredMip(0, image.sizeInBytes(), image.constBits()); + _texture->setImportant(true); } void Font::setupGPU() { From bb35521d29b40776603c47940dc9d634123585d5 Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Wed, 28 Oct 2020 02:05:17 -0400 Subject: [PATCH 69/74] Apply suggestions from code review Co-authored-by: David Rowe --- domain-server/resources/web/settings/js/settings.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 9c4b654507..ea38a30f49 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -356,7 +356,7 @@ $(document).ready(function(){ }); } - function showDomainCreationAlert (justConnected) { + function showDomainCreationAlert(justConnected) { swal({ title: 'Create new domain ID', type: 'input', @@ -381,7 +381,7 @@ $(document).ready(function(){ }); } - function createNewDomainID (label, justConnected) { + function createNewDomainID(label, justConnected) { // get the JSON object ready that we'll use to create a new domain var domainJSON = { "label": label @@ -413,15 +413,15 @@ $(document).ready(function(){ text: successText, html: true, confirmButtonText: 'Save' - }, function() { + }, function () { saveSettings(); }); - }, 'json').fail(function(data) { + }, 'json').fail(function (data) { failedToCreateDomainID(data, justConnected); }); } - function failedToCreateDomainID (data, justConnected) { + function failedToCreateDomainID(data, justConnected) { var errorText = "There was a problem creating your new domain ID. Do you want to try again or"; if (data && data.status === "failure") { From f012772fa37323ac18f87a728c8d38dc95ca38f9 Mon Sep 17 00:00:00 2001 From: humbletim Date: Thu, 29 Oct 2020 11:29:26 -0400 Subject: [PATCH 70/74] add toHttpDateString helper method --- libraries/networking/src/ResourceRequest.cpp | 6 ++++++ libraries/networking/src/ResourceRequest.h | 1 + 2 files changed, 7 insertions(+) diff --git a/libraries/networking/src/ResourceRequest.cpp b/libraries/networking/src/ResourceRequest.cpp index c63bd4c563..0f475579d6 100644 --- a/libraries/networking/src/ResourceRequest.cpp +++ b/libraries/networking/src/ResourceRequest.cpp @@ -15,8 +15,14 @@ #include #include +#include #include +QString ResourceRequest::toHttpDateString(uint64_t msecsSinceEpoch) { + return QLocale::c() + .toString(QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch), QLatin1String("ddd, dd MMM yyyy hh:mm:ss 'GMT'")) + .toLatin1(); +} void ResourceRequest::send() { if (QThread::currentThread() != thread()) { diff --git a/libraries/networking/src/ResourceRequest.h b/libraries/networking/src/ResourceRequest.h index 550294d79b..042e706291 100644 --- a/libraries/networking/src/ResourceRequest.h +++ b/libraries/networking/src/ResourceRequest.h @@ -90,6 +90,7 @@ public: void setCacheEnabled(bool value) { _cacheEnabled = value; } void setByteRange(ByteRange byteRange) { _byteRange = byteRange; } + static QString toHttpDateString(uint64_t msecsSinceEpoch); public slots: void send(); From ae7aa3eb883a0a1235773cd522848a79fc5b1054 Mon Sep 17 00:00:00 2001 From: humbletim Date: Thu, 29 Oct 2020 11:30:33 -0400 Subject: [PATCH 71/74] update ScriptCache to detect local script modifications --- .../networking/src/FileResourceRequest.cpp | 2 ++ libraries/script-engine/src/ScriptCache.cpp | 31 ++++++++++++++----- libraries/script-engine/src/ScriptCache.h | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/FileResourceRequest.cpp b/libraries/networking/src/FileResourceRequest.cpp index f9ec7797be..ebeb5936c2 100644 --- a/libraries/networking/src/FileResourceRequest.cpp +++ b/libraries/networking/src/FileResourceRequest.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -54,6 +55,7 @@ void FileResourceRequest::doSend() { } else { QFile file(filename); if (file.exists()) { + setProperty("last-modified", toHttpDateString(QFileInfo(file).lastModified().toMSecsSinceEpoch())); if (file.open(QFile::ReadOnly)) { if (file.size() < _byteRange.fromInclusive || file.size() < _byteRange.toExclusive) { diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index b23aa48762..58c5047802 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -85,11 +85,25 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable Lock lock(_containerLock); if (_scriptCache.contains(url) && !forceDownload) { - auto scriptContent = _scriptCache[url]; - lock.unlock(); - qCDebug(scriptengine) << "Found script in cache:" << url.fileName(); - contentAvailable(url.toString(), scriptContent, true, true, STATUS_CACHED); - } else { + auto entry = _scriptCache[url]; + if (url.isLocalFile() || url.scheme().isEmpty()) { + auto mtime = QFileInfo(url.toLocalFile()).lastModified(); + QString localTime = ResourceRequest::toHttpDateString(mtime.toMSecsSinceEpoch()); + QString cachedTime = entry["last-modified"].toString(); + if (cachedTime != localTime) { + forceDownload = true; + qCDebug(scriptengine) << "Found script in cache, but local file modified; reloading:" << url.fileName() + << "(memory:" << cachedTime << "disk:" << localTime << ")"; + } + } + if (!forceDownload) { + lock.unlock(); + qCDebug(scriptengine) << "Found script in cache:" << url.fileName(); + contentAvailable(url.toString(), entry["data"].toString(), true, true, STATUS_CACHED); + return; + } + } + { auto& scriptRequest = _activeScriptRequests[url]; bool alreadyWaiting = scriptRequest.scriptUsers.size() > 0; scriptRequest.scriptUsers.push_back(contentAvailable); @@ -140,7 +154,10 @@ void ScriptCache::scriptContentAvailable(int maxRetries) { _activeScriptRequests.remove(url); - _scriptCache[url] = scriptContent = req->getData(); + _scriptCache[url] = { + { "data", scriptContent = req->getData() }, + { "last-modified", req->property("last-modified") }, + }; } else { auto result = req->getResult(); bool irrecoverable = @@ -177,7 +194,7 @@ void ScriptCache::scriptContentAvailable(int maxRetries) { allCallbacks = scriptRequest.scriptUsers; if (_scriptCache.contains(url)) { - scriptContent = _scriptCache[url]; + scriptContent = _scriptCache[url]["data"].toString(); } _activeScriptRequests.remove(url); qCWarning(scriptengine) << "Error loading script from URL (" << status <<")"; diff --git a/libraries/script-engine/src/ScriptCache.h b/libraries/script-engine/src/ScriptCache.h index 511d392409..4ab4458ee9 100644 --- a/libraries/script-engine/src/ScriptCache.h +++ b/libraries/script-engine/src/ScriptCache.h @@ -60,7 +60,7 @@ private: Mutex _containerLock; QMap _activeScriptRequests; - QHash _scriptCache; + QHash _scriptCache; QMultiMap _scriptUsers; }; From 6c25b9470d1d73f4c39d4adf8ea050cc9faf5931 Mon Sep 17 00:00:00 2001 From: daleglass <51060919+daleglass@users.noreply.github.com> Date: Thu, 29 Oct 2020 19:20:18 +0100 Subject: [PATCH 72/74] Update libraries/shared/src/LogHandler.cpp Co-authored-by: kasenvr <52365539+kasenvr@users.noreply.github.com> --- libraries/shared/src/LogHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 5009fe9194..72d53f0bcb 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -51,7 +51,7 @@ LogHandler::LogHandler() { auto optionList = logOptions.split(","); - for(auto option : optionList) { + for (auto option : optionList) { option = option.trimmed(); if (option == "color") { From a7fb294a1b5d9dec5d8ced5584243e60483cfc62 Mon Sep 17 00:00:00 2001 From: humbletim Date: Sat, 31 Oct 2020 13:39:29 -0400 Subject: [PATCH 73/74] Update libraries/networking/src/ResourceRequest.cpp Co-authored-by: David Rowe --- libraries/networking/src/ResourceRequest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/ResourceRequest.cpp b/libraries/networking/src/ResourceRequest.cpp index 0f475579d6..8739cb61da 100644 --- a/libraries/networking/src/ResourceRequest.cpp +++ b/libraries/networking/src/ResourceRequest.cpp @@ -19,8 +19,8 @@ #include QString ResourceRequest::toHttpDateString(uint64_t msecsSinceEpoch) { - return QLocale::c() - .toString(QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch), QLatin1String("ddd, dd MMM yyyy hh:mm:ss 'GMT'")) + return QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch) + .toString("ddd, dd MMM yyyy hh:mm:ss 'GMT'") .toLatin1(); } From f41ef31ef59e9e441746929978aac74b832cefa9 Mon Sep 17 00:00:00 2001 From: humbletim Date: Sat, 31 Oct 2020 13:50:47 -0400 Subject: [PATCH 74/74] changes per CR --- libraries/script-engine/src/ScriptCache.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index 58c5047802..0b63803a33 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -87,8 +87,8 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable if (_scriptCache.contains(url) && !forceDownload) { auto entry = _scriptCache[url]; if (url.isLocalFile() || url.scheme().isEmpty()) { - auto mtime = QFileInfo(url.toLocalFile()).lastModified(); - QString localTime = ResourceRequest::toHttpDateString(mtime.toMSecsSinceEpoch()); + auto modifiedTime = QFileInfo(url.toLocalFile()).lastModified(); + QString localTime = ResourceRequest::toHttpDateString(modifiedTime.toMSecsSinceEpoch()); QString cachedTime = entry["last-modified"].toString(); if (cachedTime != localTime) { forceDownload = true; @@ -97,10 +97,10 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable } } if (!forceDownload) { - lock.unlock(); - qCDebug(scriptengine) << "Found script in cache:" << url.fileName(); - contentAvailable(url.toString(), entry["data"].toString(), true, true, STATUS_CACHED); - return; + lock.unlock(); + qCDebug(scriptengine) << "Found script in cache:" << url.fileName(); + contentAvailable(url.toString(), entry["data"].toString(), true, true, STATUS_CACHED); + return; } } { @@ -155,8 +155,8 @@ void ScriptCache::scriptContentAvailable(int maxRetries) { _activeScriptRequests.remove(url); _scriptCache[url] = { - { "data", scriptContent = req->getData() }, - { "last-modified", req->property("last-modified") }, + { "data", scriptContent = req->getData() }, + { "last-modified", req->property("last-modified") }, }; } else { auto result = req->getResult();