diff --git a/android/app/CMakeLists.txt b/android/app/CMakeLists.txt index 4c50cd8609..d24a84c6a5 100644 --- a/android/app/CMakeLists.txt +++ b/android/app/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME native-lib) setup_hifi_library() -link_hifi_libraries(shared networking gl gpu image fbx render-utils physics entities octree ${PLATFORM_GL_BACKEND}) +link_hifi_libraries(shared task networking gl gpu qml image fbx render-utils physics entities octree ${PLATFORM_GL_BACKEND}) target_opengl() target_bullet() diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 0a868737b0..1ae65290ff 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -464,32 +464,41 @@ void AssetServer::handleAssetMappingOperation(QSharedPointer me auto replyPacket = NLPacketList::create(PacketType::AssetMappingOperationReply, QByteArray(), true, true); replyPacket->writePrimitive(messageID); + bool canWriteToAssetServer = true; + if (senderNode) { + canWriteToAssetServer = senderNode->getCanWriteToAssetServer(); + } + switch (operationType) { case AssetMappingOperationType::Get: - handleGetMappingOperation(*message, senderNode, *replyPacket); + handleGetMappingOperation(*message, *replyPacket); break; case AssetMappingOperationType::GetAll: - handleGetAllMappingOperation(*message, senderNode, *replyPacket); + handleGetAllMappingOperation(*replyPacket); break; case AssetMappingOperationType::Set: - handleSetMappingOperation(*message, senderNode, *replyPacket); + handleSetMappingOperation(*message, canWriteToAssetServer, *replyPacket); break; case AssetMappingOperationType::Delete: - handleDeleteMappingsOperation(*message, senderNode, *replyPacket); + handleDeleteMappingsOperation(*message, canWriteToAssetServer, *replyPacket); break; case AssetMappingOperationType::Rename: - handleRenameMappingOperation(*message, senderNode, *replyPacket); + handleRenameMappingOperation(*message, canWriteToAssetServer, *replyPacket); break; case AssetMappingOperationType::SetBakingEnabled: - handleSetBakingEnabledOperation(*message, senderNode, *replyPacket); + handleSetBakingEnabledOperation(*message, canWriteToAssetServer, *replyPacket); break; } auto nodeList = DependencyManager::get(); - nodeList->sendPacketList(std::move(replyPacket), *senderNode); + if (senderNode) { + nodeList->sendPacketList(std::move(replyPacket), *senderNode); + } else { + nodeList->sendPacketList(std::move(replyPacket), message->getSenderSockAddr()); + } } -void AssetServer::handleGetMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket) { +void AssetServer::handleGetMappingOperation(ReceivedMessage& message, NLPacketList& replyPacket) { QString assetPath = message.readString(); QUrl url { assetPath }; @@ -568,7 +577,7 @@ void AssetServer::handleGetMappingOperation(ReceivedMessage& message, SharedNode } } -void AssetServer::handleGetAllMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket) { +void AssetServer::handleGetAllMappingOperation(NLPacketList& replyPacket) { replyPacket.writePrimitive(AssetUtils::AssetServerError::NoError); uint32_t count = (uint32_t)_fileMappings.size(); @@ -591,8 +600,8 @@ void AssetServer::handleGetAllMappingOperation(ReceivedMessage& message, SharedN } } -void AssetServer::handleSetMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket) { - if (senderNode->getCanWriteToAssetServer()) { +void AssetServer::handleSetMappingOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket) { + if (hasWriteAccess) { QString assetPath = message.readString(); auto assetHash = message.read(AssetUtils::SHA256_HASH_LENGTH).toHex(); @@ -614,8 +623,8 @@ void AssetServer::handleSetMappingOperation(ReceivedMessage& message, SharedNode } } -void AssetServer::handleDeleteMappingsOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket) { - if (senderNode->getCanWriteToAssetServer()) { +void AssetServer::handleDeleteMappingsOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket) { + if (hasWriteAccess) { int numberOfDeletedMappings { 0 }; message.readPrimitive(&numberOfDeletedMappings); @@ -642,8 +651,8 @@ void AssetServer::handleDeleteMappingsOperation(ReceivedMessage& message, Shared } } -void AssetServer::handleRenameMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket) { - if (senderNode->getCanWriteToAssetServer()) { +void AssetServer::handleRenameMappingOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket) { + if (hasWriteAccess) { QString oldPath = message.readString(); QString newPath = message.readString(); @@ -664,8 +673,8 @@ void AssetServer::handleRenameMappingOperation(ReceivedMessage& message, SharedN } } -void AssetServer::handleSetBakingEnabledOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket) { - if (senderNode->getCanWriteToAssetServer()) { +void AssetServer::handleSetBakingEnabledOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket) { + if (hasWriteAccess) { bool enabled { true }; message.readPrimitive(&enabled); @@ -739,9 +748,14 @@ void AssetServer::handleAssetGet(QSharedPointer message, Shared } void AssetServer::handleAssetUpload(QSharedPointer message, SharedNodePointer senderNode) { + bool canWriteToAssetServer = true; + if (senderNode) { + canWriteToAssetServer = senderNode->getCanWriteToAssetServer(); + } - if (senderNode->getCanWriteToAssetServer()) { - qCDebug(asset_server) << "Starting an UploadAssetTask for upload from" << uuidStringWithoutCurlyBraces(senderNode->getUUID()); + + if (canWriteToAssetServer) { + qCDebug(asset_server) << "Starting an UploadAssetTask for upload from" << uuidStringWithoutCurlyBraces(message->getSourceID()); auto task = new UploadAssetTask(message, senderNode, _filesDirectory, _filesizeLimit); _transferTaskPool.start(task); @@ -761,7 +775,11 @@ void AssetServer::handleAssetUpload(QSharedPointer message, Sha // send off the packet auto nodeList = DependencyManager::get(); - nodeList->sendPacket(std::move(permissionErrorPacket), *senderNode); + if (senderNode) { + nodeList->sendPacket(std::move(permissionErrorPacket), *senderNode); + } else { + nodeList->sendPacket(std::move(permissionErrorPacket), message->getSenderSockAddr()); + } } } diff --git a/assignment-client/src/assets/AssetServer.h b/assignment-client/src/assets/AssetServer.h index 5e7a3c1700..6cbfa76414 100644 --- a/assignment-client/src/assets/AssetServer.h +++ b/assignment-client/src/assets/AssetServer.h @@ -21,17 +21,9 @@ #include "AssetUtils.h" #include "ReceivedMessage.h" -namespace std { - template <> - struct hash { - size_t operator()(const QString& v) const { return qHash(v); } - }; -} +#include "RegisteredMetaTypes.h" struct AssetMeta { - AssetMeta() { - } - int bakeVersion { 0 }; bool failedLastBake { false }; QString lastBakeErrors; @@ -60,14 +52,15 @@ private slots: void sendStatsPacket() override; private: - using Mappings = std::unordered_map; + void handleGetMappingOperation(ReceivedMessage& message, NLPacketList& replyPacket); + void handleGetAllMappingOperation(NLPacketList& replyPacket); + void handleSetMappingOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket); + void handleDeleteMappingsOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket); + void handleRenameMappingOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket); + void handleSetBakingEnabledOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket); - void handleGetMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); - void handleGetAllMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); - void handleSetMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); - void handleDeleteMappingsOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); - void handleRenameMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); - void handleSetBakingEnabledOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket); + void handleAssetServerBackup(ReceivedMessage& message, NLPacketList& replyPacket); + void handleAssetServerRestore(ReceivedMessage& message, NLPacketList& replyPacket); // Mapping file operations must be called from main assignment thread only bool loadMappingsFromFile(); @@ -111,7 +104,7 @@ private: /// Remove baked paths when the original asset is deleteds void removeBakedPathsForDeletedAsset(AssetUtils::AssetHash originalAssetHash); - Mappings _fileMappings; + AssetUtils::Mappings _fileMappings; QDir _resourcesDirectory; QDir _filesDirectory; diff --git a/assignment-client/src/assets/SendAssetTask.cpp b/assignment-client/src/assets/SendAssetTask.cpp index 6da092357f..d17d254afd 100644 --- a/assignment-client/src/assets/SendAssetTask.cpp +++ b/assignment-client/src/assets/SendAssetTask.cpp @@ -112,5 +112,9 @@ void SendAssetTask::run() { } auto nodeList = DependencyManager::get(); - nodeList->sendPacketList(std::move(replyPacketList), *_senderNode); + if (_senderNode) { + nodeList->sendPacketList(std::move(replyPacketList), *_senderNode); + } else { + nodeList->sendPacketList(std::move(replyPacketList), _message->getSenderSockAddr()); + } } diff --git a/assignment-client/src/assets/UploadAssetTask.cpp b/assignment-client/src/assets/UploadAssetTask.cpp index 68bf4db5fd..d3e755212a 100644 --- a/assignment-client/src/assets/UploadAssetTask.cpp +++ b/assignment-client/src/assets/UploadAssetTask.cpp @@ -41,9 +41,12 @@ void UploadAssetTask::run() { uint64_t fileSize; buffer.read(reinterpret_cast(&fileSize), sizeof(fileSize)); - - qDebug() << "UploadAssetTask reading a file of " << fileSize << "bytes from" - << uuidStringWithoutCurlyBraces(_senderNode->getUUID()); + + if (_senderNode) { + qDebug() << "UploadAssetTask reading a file of " << fileSize << "bytes from" << uuidStringWithoutCurlyBraces(_senderNode->getUUID()); + } else { + qDebug() << "UploadAssetTask reading a file of " << fileSize << "bytes from" << _receivedMessage->getSenderSockAddr(); + } auto replyPacket = NLPacket::create(PacketType::AssetUploadReply, -1, true); replyPacket->writePrimitive(messageID); @@ -55,9 +58,12 @@ void UploadAssetTask::run() { auto hash = AssetUtils::hashData(fileData); auto hexHash = hash.toHex(); - - qDebug() << "Hash for uploaded file from" << uuidStringWithoutCurlyBraces(_senderNode->getUUID()) - << "is: (" << hexHash << ") "; + + if (_senderNode) { + qDebug() << "Hash for uploaded file from" << uuidStringWithoutCurlyBraces(_senderNode->getUUID()) << "is: (" << hexHash << ")"; + } else { + qDebug() << "Hash for uploaded file from" << _receivedMessage->getSenderSockAddr() << "is: (" << hexHash << ")"; + } QFile file { _resourcesDir.filePath(QString(hexHash)) }; @@ -103,5 +109,9 @@ void UploadAssetTask::run() { } auto nodeList = DependencyManager::get(); - nodeList->sendPacket(std::move(replyPacket), *_senderNode); + if (_senderNode) { + nodeList->sendPacket(std::move(replyPacket), *_senderNode); + } else { + nodeList->sendPacket(std::move(replyPacket), _receivedMessage->getSenderSockAddr()); + } } diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 7f088d8183..8af4eec934 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "AudioMixer.h" + #include #include @@ -36,8 +38,6 @@ #include "AvatarAudioStream.h" #include "InjectedAudioStream.h" -#include "AudioMixer.h" - static const float DEFAULT_ATTENUATION_PER_DOUBLING_IN_DISTANCE = 0.5f; // attenuation = -6dB * log2(distance) static const int DISABLE_STATIC_JITTER_FRAMES = -1; static const float DEFAULT_NOISE_MUTING_THRESHOLD = 1.0f; diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index ed3a5b0541..8c47893aa3 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -18,6 +18,8 @@ #include #include +#include + #include "AudioMixerStats.h" #include "AudioMixerSlavePool.h" diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 2560f43337..d4d4f847ee 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "AudioMixerClientData.h" + #include #include @@ -22,8 +24,6 @@ #include "AudioLogging.h" #include "AudioHelpers.h" #include "AudioMixer.h" -#include "AudioMixerClientData.h" - AudioMixerClientData::AudioMixerClientData(const QUuid& nodeID) : NodeData(nodeID), diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index c3a31715ea..514e1c9756 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -21,6 +21,7 @@ #include #include +#include #include #include "PositionalAudioStream.h" diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index 29d42a9ced..b975ba8bfe 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "AudioMixerSlave.h" + #include #include @@ -34,8 +36,6 @@ #include "InjectedAudioStream.h" #include "AudioHelpers.h" -#include "AudioMixerSlave.h" - using AudioStreamMap = AudioMixerClientData::AudioStreamMap; // packet helpers @@ -176,7 +176,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) { auto nodeID = node->getUUID(); // compute the node's max relative volume - float nodeVolume; + float nodeVolume = 0.0f; for (auto& streamPair : nodeData->getAudioStreams()) { auto nodeStream = streamPair.second; @@ -193,10 +193,8 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) { } // max-heapify the nodes by relative volume - throttledNodes.push_back(std::make_pair(nodeVolume, node)); - if (!throttledNodes.empty()) { - std::push_heap(throttledNodes.begin(), throttledNodes.end()); - } + throttledNodes.push_back({ nodeVolume, node }); + std::push_heap(throttledNodes.begin(), throttledNodes.end()); } } }); diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index c1e275e4d3..f67be55b92 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -22,6 +22,8 @@ setup_memory_debugger() symlink_or_copy_directory_beside_target(${_SHOULD_SYMLINK_RESOURCES} "${CMAKE_CURRENT_SOURCE_DIR}/resources" "resources") # link the shared hifi libraries +include_hifi_library_headers(gpu) +include_hifi_library_headers(graphics) link_hifi_libraries(embedded-webserver networking shared avatars) # find OpenSSL diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index c6d118a87b..93d703c8b3 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1,12 +1,6 @@ { "version": 2.1, "settings": [ - { - "name": "label", - "label": "Label", - "settings": [ - ] - }, { "name": "metaverse", "label": "Metaverse / Networking", @@ -15,7 +9,8 @@ "name": "access_token", "label": "Access Token", "help": "This is your OAuth access token to connect this domain-server with your High Fidelity account.
It can be generated by clicking the 'Connect Account' button above.
You can also go to the My Security page of your account and generate a token with the 'domains' scope and paste it here.", - "advanced": true + "advanced": true, + "backup": false }, { "name": "id", @@ -55,8 +50,8 @@ ] }, { - "label": "Places / Paths", - "html_id": "places_paths", + "label": "Paths", + "html_id": "paths", "restart": false, "settings": [ { @@ -64,6 +59,7 @@ "label": "Paths", "help": "Clients can enter a path to reach an exact viewpoint in your domain.
Add rows to the table below to map a path to a viewpoint.
The index path ( / ) is where clients will enter if they do not enter an explicit path.", "type": "table", + "content_setting": true, "can_add_new_rows": true, "key": { "name": "path", @@ -164,7 +160,8 @@ { "name": "http_username", "label": "HTTP Username", - "help": "Username used for basic HTTP authentication." + "help": "Username used for basic HTTP authentication.", + "backup": false }, { "name": "http_password", @@ -172,7 +169,8 @@ "type": "password", "help": "Password used for basic HTTP authentication. Leave this alone if you do not want to change it.", "password_placeholder": "******", - "value-hidden": true + "value-hidden": true, + "backup": false }, { "name": "verify_http_password", @@ -935,6 +933,7 @@ "name": "persistent_scripts", "type": "table", "label": "Persistent Scripts", + "content_setting": true, "help": "Add the URLs for scripts that you would like to ensure are always running in your domain.", "can_add_new_rows": true, "columns": [ @@ -955,99 +954,6 @@ } ] }, - { - "name": "asset_server", - "label": "Asset Server (ATP)", - "assignment-types": [ 3 ], - "settings": [ - { - "name": "enabled", - "type": "checkbox", - "label": "Enabled", - "help": "Assigns an asset-server in your domain to serve files to clients via the ATP protocol (over UDP)", - "default": true, - "advanced": true - }, - { - "name": "assets_path", - "type": "string", - "label": "Assets Path", - "help": "The path to the directory assets are stored in.
If this path is relative, it will be relative to the application data directory.
If you change this path you will need to manually copy any existing assets from the previous directory.", - "default": "", - "advanced": true - }, - { - "name": "assets_filesize_limit", - "type": "int", - "label": "File Size Limit", - "help": "The file size limit of an asset that can be imported into the asset server in MBytes. 0 (default) means no limit on file size.", - "default": 0, - "advanced": true - } - ] - }, - { - "name": "entity_script_server", - "label": "Entity Script Server (ESS)", - "assignment-types": [ 5 ], - "settings": [ - { - "name": "entity_pps_per_script", - "label": "Entity PPS per script", - "help": "The number of packets per second (PPS) that can be sent to the entity server for each server entity script. This contributes to a total overall amount.
Example: 1000 PPS with 5 entites gives a total PPS of 5000 that is shared among the entity scripts. A single could use 4000 PPS, leaving 1000 for the rest, for example.", - "default": 900, - "type": "int", - "advanced": true - }, - { - "name": "max_total_entity_pps", - "label": "Maximum Total Entity PPS", - "help": "The maximum total packets per seconds (PPS) that can be sent to the entity server.
Example: 5 scripts @ 1000 PPS per script = 5000 total PPS. A maximum total PPS of 4000 would cap this 5000 total PPS to 4000.", - "default": 9000, - "type": "int", - "advanced": true - } - ] - }, - { - "name": "avatars", - "label": "Avatars", - "assignment-types": [ 1, 2 ], - "settings": [ - { - "name": "min_avatar_height", - "type": "double", - "label": "Minimum Avatar Height (meters)", - "help": "Limits the height of avatars in your domain. Must be at least 0.009.", - "placeholder": 0.4, - "default": 0.4 - }, - { - "name": "max_avatar_height", - "type": "double", - "label": "Maximum Avatar Height (meters)", - "help": "Limits the scale of avatars in your domain. Cannot be greater than 1755.", - "placeholder": 5.2, - "default": 5.2 - }, - { - "name": "avatar_whitelist", - "label": "Avatars Allowed from:", - "help": "Comma separated list of URLs (with optional paths) that avatar .fst files are allowed from. If someone attempts to use an avatar with a different domain, it will be rejected and the replacement avatar will be used. If left blank, any domain is allowed.", - "placeholder": "", - "default": "", - "advanced": true - }, - { - "name": "replacement_avatar", - "label": "Replacement Avatar for disallowed avatars", - "help": "A URL for an avatar .fst to be used when someone tries to use an avatar that is not allowed. If left blank, the generic default avatar is used.", - "placeholder": "", - "default": "", - "advanced": true - } - ] - }, { "name": "audio_threading", "label": "Audio Threading", @@ -1080,6 +986,7 @@ "name": "attenuation_per_doubling_in_distance", "label": "Default Domain Attenuation", "help": "Factor between 0 and 1.0 (0: No attenuation, 1.0: extreme attenuation)", + "content_setting": true, "placeholder": "0.5", "default": "0.5", "advanced": false @@ -1105,6 +1012,7 @@ "label": "Zones", "help": "In this table you can define a set of zones in which you can specify various audio properties.", "numbered": false, + "content_setting": true, "can_add_new_rows": true, "key": { "name": "name", @@ -1155,6 +1063,7 @@ "type": "table", "label": "Attenuation Coefficients", "help": "In this table you can set custom attenuation coefficients between audio zones", + "content_setting": true, "numbered": true, "can_order": true, "can_add_new_rows": true, @@ -1185,6 +1094,7 @@ "label": "Reverb Settings", "help": "In this table you can set reverb levels for audio zones. For a medium-sized (e.g., 100 square meter) meeting room, try a decay time of around 1.5 seconds and a wet/dry mix of 25%. For an airplane hangar or cathedral, try a decay time of 4 seconds and a wet/dry mix of 50%.", "numbered": true, + "content_setting": true, "can_add_new_rows": true, "columns": [ { @@ -1266,9 +1176,82 @@ } ] }, + { + "name": "avatars", + "label": "Avatars", + "assignment-types": [ 1, 2 ], + "settings": [ + { + "name": "min_avatar_height", + "type": "double", + "label": "Minimum Avatar Height (meters)", + "help": "Limits the height of avatars in your domain. Must be at least 0.009.", + "placeholder": 0.4, + "default": 0.4 + }, + { + "name": "max_avatar_height", + "type": "double", + "label": "Maximum Avatar Height (meters)", + "help": "Limits the scale of avatars in your domain. Cannot be greater than 1755.", + "placeholder": 5.2, + "default": 5.2 + }, + { + "name": "avatar_whitelist", + "label": "Avatars Allowed from:", + "help": "Comma separated list of URLs (with optional paths) that avatar .fst files are allowed from. If someone attempts to use an avatar with a different domain, it will be rejected and the replacement avatar will be used. If left blank, any domain is allowed.", + "placeholder": "", + "default": "", + "advanced": true + }, + { + "name": "replacement_avatar", + "label": "Replacement Avatar for disallowed avatars", + "help": "A URL for an avatar .fst to be used when someone tries to use an avatar that is not allowed. If left blank, the generic default avatar is used.", + "placeholder": "", + "default": "", + "advanced": true + } + ] + }, + { + "name": "avatar_mixer", + "label": "Avatar Mixer", + "assignment-types": [ + 1 + ], + "settings": [ + { + "name": "max_node_send_bandwidth", + "type": "double", + "label": "Per-Node Bandwidth", + "help": "Desired maximum send bandwidth (in Megabits per second) to each node", + "placeholder": 5.0, + "default": 5.0, + "advanced": true + }, + { + "name": "auto_threads", + "label": "Automatically determine thread count", + "type": "checkbox", + "help": "Allow system to determine number of threads (recommended)", + "default": false, + "advanced": true + }, + { + "name": "num_threads", + "label": "Number of Threads", + "help": "Threads to spin up for avatar mixing (if not automatically set)", + "placeholder": "1", + "default": "1", + "advanced": true + } + ] + }, { "name": "entity_server_settings", - "label": "Entity Server Settings", + "label": "Entities", "assignment-types": [ 6 ], @@ -1309,6 +1292,7 @@ "name": "entityEditFilter", "label": "Filter Entity Edits", "help": "Check all entity edits against this filter function.", + "content_setting": true, "placeholder": "url whose content is like: function filter(properties) { return properties; }", "default": "", "advanced": true @@ -1503,35 +1487,55 @@ ] }, { - "name": "avatar_mixer", - "label": "Avatar Mixer", - "assignment-types": [ - 1 - ], + "name": "asset_server", + "label": "Asset Server (ATP)", + "assignment-types": [ 3 ], "settings": [ { - "name": "max_node_send_bandwidth", - "type": "double", - "label": "Per-Node Bandwidth", - "help": "Desired maximum send bandwidth (in Megabits per second) to each node", - "placeholder": 5.0, - "default": 5.0, - "advanced": true - }, - { - "name": "auto_threads", - "label": "Automatically determine thread count", + "name": "enabled", "type": "checkbox", - "help": "Allow system to determine number of threads (recommended)", - "default": false, + "label": "Enabled", + "help": "Assigns an asset-server in your domain to serve files to clients via the ATP protocol (over UDP)", + "default": true, "advanced": true }, { - "name": "num_threads", - "label": "Number of Threads", - "help": "Threads to spin up for avatar mixing (if not automatically set)", - "placeholder": "1", - "default": "1", + "name": "assets_path", + "type": "string", + "label": "Assets Path", + "help": "The path to the directory assets are stored in.
If this path is relative, it will be relative to the application data directory.
If you change this path you will need to manually copy any existing assets from the previous directory.", + "default": "", + "advanced": true + }, + { + "name": "assets_filesize_limit", + "type": "int", + "label": "File Size Limit", + "help": "The file size limit of an asset that can be imported into the asset server in MBytes. 0 (default) means no limit on file size.", + "default": 0, + "advanced": true + } + ] + }, + { + "name": "entity_script_server", + "label": "Entity Script Server (ESS)", + "assignment-types": [ 5 ], + "settings": [ + { + "name": "entity_pps_per_script", + "label": "Entity PPS per script", + "help": "The number of packets per second (PPS) that can be sent to the entity server for each server entity script. This contributes to a total overall amount.
Example: 1000 PPS with 5 entites gives a total PPS of 5000 that is shared among the entity scripts. A single could use 4000 PPS, leaving 1000 for the rest, for example.", + "default": 900, + "type": "int", + "advanced": true + }, + { + "name": "max_total_entity_pps", + "label": "Maximum Total Entity PPS", + "help": "The maximum total packets per seconds (PPS) that can be sent to the entity server.
Example: 5 scripts @ 1000 PPS per script = 5000 total PPS. A maximum total PPS of 4000 would cap this 5000 total PPS to 4000.", + "default": 9000, + "type": "int", "advanced": true } ] diff --git a/domain-server/resources/web/base-settings-scripts.html b/domain-server/resources/web/base-settings-scripts.html new file mode 100644 index 0000000000..fe370c4675 --- /dev/null +++ b/domain-server/resources/web/base-settings-scripts.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/domain-server/resources/web/base-settings.html b/domain-server/resources/web/base-settings.html new file mode 100644 index 0000000000..da5561d03d --- /dev/null +++ b/domain-server/resources/web/base-settings.html @@ -0,0 +1,59 @@ +
+
+ +
+ + +
+ +
+
+
+
+
diff --git a/domain-server/resources/web/content/index.shtml b/domain-server/resources/web/content/index.shtml index 0e48c1eff8..9b507f7826 100644 --- a/domain-server/resources/web/content/index.shtml +++ b/domain-server/resources/web/content/index.shtml @@ -1,45 +1,19 @@ -
-
-
- -
-
+ -
-
-
-
-

Upload Entities File

-
-
-
-

- Upload an entities file (e.g.: models.json.gz) to replace the content of this domain.
- Note: Your domain's content will be replaced by the content you upload, but the backup files of your domain's content will not immediately be changed. -

-

If your domain has any content that you would like to re-use at a later date, save a manual backup of your models.json.gz file, which is usually stored at the following paths:

- -
C:/Users/[username]/AppData/Roaming/High Fidelity/assignment-client/entities/models.json.gz
- -
/Users/[username]/Library/Application Support/High Fidelity/assignment-client/entities/models.json.gz
- -
/home/[username]/.local/share/High Fidelity/assignment-client/entities/models.json.gz
-
- -
-
- -
-
-
-
-
+ - - + + + + + diff --git a/domain-server/resources/web/content/js/content.js b/domain-server/resources/web/content/js/content.js index 2e6e084164..e448952c65 100644 --- a/domain-server/resources/web/content/js/content.js +++ b/domain-server/resources/web/content/js/content.js @@ -1,14 +1,6 @@ $(document).ready(function(){ - function showSpinnerAlert(title) { - swal({ - title: title, - text: '
', - html: true, - showConfirmButton: false, - allowEscapeKey: false - }); - } + Settings.afterReloadActions = function() {}; var frm = $('#upload-form'); frm.submit(function (ev) { diff --git a/domain-server/resources/web/css/style.css b/domain-server/resources/web/css/style.css index 158008fc2b..5121b85a42 100644 --- a/domain-server/resources/web/css/style.css +++ b/domain-server/resources/web/css/style.css @@ -18,6 +18,14 @@ body { margin-top: 70px; } +/* unfortunate hack so that anchors go to the right place with fixed navbar */ +:target:before { + content: " "; + display: block; + height: 70px; + margin-top: -70px; +} + [hidden] { display: none !important; } @@ -118,11 +126,6 @@ span.port { margin-top: 10px; } -#small-save-button { - width: 100%; - margin-bottom: 15px; -} - td.buttons { width: 30px; } @@ -345,3 +348,89 @@ table .headers + .headers td { text-align: center; margin-top: 20px; } + +@media (min-width: 768px) { + ul.nav li.dropdown-on-hover:hover ul.dropdown-menu { + display: block; + } +} + +ul.nav li.dropdown ul.dropdown-menu { + padding: 0px 0px; +} + +ul.nav li.dropdown li a { + padding-top: 7px; + padding-bottom: 7px; +} + +ul.nav li.dropdown li a:hover { + color: white; + background-color: #337ab7; +} + +ul.nav li.dropdown ul.dropdown-menu .divider { + margin: 0px 0; +} + +#visit-domain-link { + background-color: transparent; +} + +.navbar-btn { + margin-left: 10px; +} + +#save-settings-xs-button { + float: right; + margin-right: 10px; +} + +#button-bars { + display: inline-block; + float: left; +} + +#hamburger-badge { + position: relative; + top: -2px; + float: left; + margin-right: 10px; + margin-left: 0px; +} + +#restart-server { + margin-left: 0px; +} + +#restart-server:hover { + text-decoration: none; +} + +.badge { + margin-left: 5px; + background-color: #00B4EF !important; +} + +.panel-title { + display: inline-block; +} + +#visit-hmd-icon { + width: 25px; + position: relative; + top: -1px; +} + +.advanced-settings-section { + margin-top: 20px; +} + +#restore-settings-button { + margin-top: 10px; +} + +/* fix for https://bugs.webkit.org/show_bug.cgi?id=39620 */ +.save-button-text { + pointer-events: none; +} diff --git a/domain-server/resources/web/header.html b/domain-server/resources/web/header.html index 1e32e9f02f..1b7b306fff 100644 --- a/domain-server/resources/web/header.html +++ b/domain-server/resources/web/header.html @@ -17,30 +17,47 @@
- @@ -50,7 +67,7 @@