mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 19:16:56 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into black-bis
This commit is contained in:
commit
4edf2275b5
61 changed files with 1381 additions and 1204 deletions
|
@ -68,6 +68,7 @@ if (USE_GLES AND (NOT ANDROID))
|
||||||
set(DISABLE_QML_OPTION ON)
|
set(DISABLE_QML_OPTION ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
option(BUILD_CLIENT "Build client components" ${BUILD_CLIENT_OPTION})
|
option(BUILD_CLIENT "Build client components" ${BUILD_CLIENT_OPTION})
|
||||||
option(BUILD_SERVER "Build server components" ${BUILD_SERVER_OPTION})
|
option(BUILD_SERVER "Build server components" ${BUILD_SERVER_OPTION})
|
||||||
option(BUILD_TESTS "Build tests" ${BUILD_TESTS_OPTION})
|
option(BUILD_TESTS "Build tests" ${BUILD_TESTS_OPTION})
|
||||||
|
@ -162,7 +163,6 @@ if (BUILD_SERVER)
|
||||||
set_target_properties(domain-server PROPERTIES FOLDER "Apps")
|
set_target_properties(domain-server PROPERTIES FOLDER "Apps")
|
||||||
add_subdirectory(ice-server)
|
add_subdirectory(ice-server)
|
||||||
set_target_properties(ice-server PROPERTIES FOLDER "Apps")
|
set_target_properties(ice-server PROPERTIES FOLDER "Apps")
|
||||||
add_subdirectory(server-console)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_CLIENT)
|
if (BUILD_CLIENT)
|
||||||
|
@ -174,6 +174,7 @@ endif()
|
||||||
|
|
||||||
if (BUILD_CLIENT OR BUILD_SERVER)
|
if (BUILD_CLIENT OR BUILD_SERVER)
|
||||||
add_subdirectory(plugins)
|
add_subdirectory(plugins)
|
||||||
|
add_subdirectory(server-console)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway
|
# BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway
|
||||||
|
|
|
@ -7,6 +7,8 @@ target_bullet()
|
||||||
set(INTERFACE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../interface")
|
set(INTERFACE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../interface")
|
||||||
add_subdirectory("${INTERFACE_DIR}" "libraries/interface")
|
add_subdirectory("${INTERFACE_DIR}" "libraries/interface")
|
||||||
include_directories("${INTERFACE_DIR}/src")
|
include_directories("${INTERFACE_DIR}/src")
|
||||||
|
set(HIFI_CODEC_PLUGIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../plugins/hifiCodec")
|
||||||
|
add_subdirectory("${HIFI_CODEC_PLUGIN_DIR}" "libraries/hifiCodecPlugin")
|
||||||
|
|
||||||
target_link_libraries(native-lib android log m interface)
|
target_link_libraries(native-lib android log m interface)
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,10 @@ android {
|
||||||
if (Os.isFamily(Os.FAMILY_UNIX)) {
|
if (Os.isFamily(Os.FAMILY_UNIX)) {
|
||||||
def uploadDumpSymsTask = rootProject.getTasksByName("uploadBreakpadDumpSyms${variant.name.capitalize()}", false).first()
|
def uploadDumpSymsTask = rootProject.getTasksByName("uploadBreakpadDumpSyms${variant.name.capitalize()}", false).first()
|
||||||
def runDumpSymsTask = rootProject.getTasksByName("runBreakpadDumpSyms${variant.name.capitalize()}", false).first()
|
def runDumpSymsTask = rootProject.getTasksByName("runBreakpadDumpSyms${variant.name.capitalize()}", false).first()
|
||||||
|
def renameHifiACTask = rootProject.getTasksByName("renameHifiACTask${variant.name.capitalize()}", false).first()
|
||||||
runDumpSymsTask.dependsOn(task)
|
runDumpSymsTask.dependsOn(task)
|
||||||
variant.assemble.dependsOn(uploadDumpSymsTask)
|
variant.assemble.dependsOn(uploadDumpSymsTask)
|
||||||
|
variant.mergeResources.dependsOn(renameHifiACTask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,11 +143,9 @@ def packages = [
|
||||||
includeLibs: ['libtbb.so', 'libtbbmalloc.so'],
|
includeLibs: ['libtbb.so', 'libtbbmalloc.so'],
|
||||||
],
|
],
|
||||||
hifiAC: [
|
hifiAC: [
|
||||||
file: 'libplugins_libhifiCodec.zip',
|
baseUrl: 'http://s3.amazonaws.com/hifi-public/dependencies/',
|
||||||
versionId: 'i31pW.qNbvFOXRxbyiJUxg3sphaFNmZU',
|
file: 'codecSDK-android_armv8-2.0.zip',
|
||||||
checksum: '9412a8e12c88a4096c1fc843bb9fe52d',
|
checksum: '1cbef929675818fc64c4101b72f84a6a'
|
||||||
sharedLibFolder: '',
|
|
||||||
includeLibs: ['libplugins_libhifiCodec.so']
|
|
||||||
],
|
],
|
||||||
etc2comp: [
|
etc2comp: [
|
||||||
file: 'etc2comp-patched-armv8-libcpp.tgz',
|
file: 'etc2comp-patched-armv8-libcpp.tgz',
|
||||||
|
@ -367,7 +365,8 @@ task downloadDependencies {
|
||||||
doLast {
|
doLast {
|
||||||
packages.each { entry ->
|
packages.each { entry ->
|
||||||
def filename = entry.value['file'];
|
def filename = entry.value['file'];
|
||||||
def url = baseUrl + filename;
|
def dependencyBaseUrl = entry.value['baseUrl']
|
||||||
|
def url = (dependencyBaseUrl?.trim() ? dependencyBaseUrl : baseUrl) + filename;
|
||||||
if (entry.value.containsKey('versionId')) {
|
if (entry.value.containsKey('versionId')) {
|
||||||
url = url + '?versionId=' + entry.value['versionId']
|
url = url + '?versionId=' + entry.value['versionId']
|
||||||
}
|
}
|
||||||
|
@ -668,6 +667,21 @@ task uploadBreakpadDumpSymsRelease(type:io.github.httpbuilderng.http.HttpTask, d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task renameHifiACTaskDebug() {
|
||||||
|
doLast {
|
||||||
|
def sourceFile = new File("${appDir}/build/intermediates/cmake/debug/obj/arm64-v8a/","libhifiCodec.so")
|
||||||
|
def destinationFile = new File("${appDir}/src/main/jniLibs/arm64-v8a", "libplugins_libhifiCodec.so")
|
||||||
|
copy { from sourceFile; into destinationFile.parent; rename(sourceFile.name, destinationFile.name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task renameHifiACTaskRelease(type: Copy) {
|
||||||
|
doLast {
|
||||||
|
def sourceFile = new File("${appDir}/build/intermediates/cmake/release/obj/arm64-v8a/","libhifiCodec.so")
|
||||||
|
def destinationFile = new File("${appDir}/src/main/jniLibs/arm64-v8a", "libplugins_libhifiCodec.so")
|
||||||
|
copy { from sourceFile; into destinationFile.parent; rename(sourceFile.name, destinationFile.name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME this code is prototyping the desired functionality for doing build time binary dependency resolution.
|
// FIXME this code is prototyping the desired functionality for doing build time binary dependency resolution.
|
||||||
// See the comment on the qtBundle task above
|
// See the comment on the qtBundle task above
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -112,6 +112,11 @@ void AvatarMixerClientData::processSetTraitsMessage(ReceivedMessage& message,
|
||||||
AvatarTraits::TraitWireSize traitSize;
|
AvatarTraits::TraitWireSize traitSize;
|
||||||
message.readPrimitive(&traitSize);
|
message.readPrimitive(&traitSize);
|
||||||
|
|
||||||
|
if (traitSize < -1 || traitSize > message.getBytesLeftToRead()) {
|
||||||
|
qWarning() << "Refusing to process simple trait of size" << traitSize << "from" << message.getSenderSockAddr();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (packetTraitVersion > _lastReceivedTraitVersions[traitType]) {
|
if (packetTraitVersion > _lastReceivedTraitVersions[traitType]) {
|
||||||
_avatar->processTrait(traitType, message.read(traitSize));
|
_avatar->processTrait(traitType, message.read(traitSize));
|
||||||
_lastReceivedTraitVersions[traitType] = packetTraitVersion;
|
_lastReceivedTraitVersions[traitType] = packetTraitVersion;
|
||||||
|
@ -128,26 +133,41 @@ void AvatarMixerClientData::processSetTraitsMessage(ReceivedMessage& message,
|
||||||
} else {
|
} else {
|
||||||
AvatarTraits::TraitInstanceID instanceID = QUuid::fromRfc4122(message.readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
AvatarTraits::TraitInstanceID instanceID = QUuid::fromRfc4122(message.readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
|
if (message.getBytesLeftToRead() == 0) {
|
||||||
|
qWarning () << "Received an instanced trait with no size from" << message.getSenderSockAddr();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
AvatarTraits::TraitWireSize traitSize;
|
AvatarTraits::TraitWireSize traitSize;
|
||||||
message.readPrimitive(&traitSize);
|
message.readPrimitive(&traitSize);
|
||||||
|
|
||||||
auto& instanceVersionRef = _lastReceivedTraitVersions.getInstanceValueRef(traitType, instanceID);
|
if (traitSize < -1 || traitSize > message.getBytesLeftToRead()) {
|
||||||
|
qWarning() << "Refusing to process instanced trait of size" << traitSize << "from" << message.getSenderSockAddr();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (packetTraitVersion > instanceVersionRef) {
|
if (traitType == AvatarTraits::AvatarEntity) {
|
||||||
if (traitSize == AvatarTraits::DELETED_TRAIT_SIZE) {
|
auto& instanceVersionRef = _lastReceivedTraitVersions.getInstanceValueRef(traitType, instanceID);
|
||||||
_avatar->processDeletedTraitInstance(traitType, instanceID);
|
|
||||||
|
|
||||||
// to track a deleted instance but keep version information
|
if (packetTraitVersion > instanceVersionRef) {
|
||||||
// the avatar mixer uses the negative value of the sent version
|
if (traitSize == AvatarTraits::DELETED_TRAIT_SIZE) {
|
||||||
instanceVersionRef = -packetTraitVersion;
|
_avatar->processDeletedTraitInstance(traitType, instanceID);
|
||||||
|
|
||||||
|
// to track a deleted instance but keep version information
|
||||||
|
// the avatar mixer uses the negative value of the sent version
|
||||||
|
instanceVersionRef = -packetTraitVersion;
|
||||||
|
} else {
|
||||||
|
_avatar->processTraitInstance(traitType, instanceID, message.read(traitSize));
|
||||||
|
instanceVersionRef = packetTraitVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
anyTraitsChanged = true;
|
||||||
} else {
|
} else {
|
||||||
_avatar->processTraitInstance(traitType, instanceID, message.read(traitSize));
|
message.seek(message.getPosition() + traitSize);
|
||||||
instanceVersionRef = packetTraitVersion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
anyTraitsChanged = true;
|
|
||||||
} else {
|
} else {
|
||||||
message.seek(message.getPosition() + traitSize);
|
qWarning() << "Refusing to process traits packet with instanced trait of unprocessable type from" << message.getSenderSockAddr();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,7 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isDeleted && (sentInstanceIt == sentIDValuePairs.end() || receivedVersion > sentInstanceIt->value)) {
|
if (!isDeleted && (sentInstanceIt == sentIDValuePairs.end() || receivedVersion > sentInstanceIt->value)) {
|
||||||
|
|
||||||
// this instance version exists and has never been sent or is newer so we need to send it
|
// this instance version exists and has never been sent or is newer so we need to send it
|
||||||
bytesWritten += sendingAvatar->packTraitInstance(traitType, instanceID, traitsPacketList, receivedVersion);
|
bytesWritten += sendingAvatar->packTraitInstance(traitType, instanceID, traitsPacketList, receivedVersion);
|
||||||
|
|
||||||
|
@ -161,6 +162,7 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis
|
||||||
sentIDValuePairs.emplace_back(instanceID, receivedVersion);
|
sentIDValuePairs.emplace_back(instanceID, receivedVersion);
|
||||||
}
|
}
|
||||||
} else if (isDeleted && sentInstanceIt != sentIDValuePairs.end() && absoluteReceivedVersion > sentInstanceIt->value) {
|
} else if (isDeleted && sentInstanceIt != sentIDValuePairs.end() && absoluteReceivedVersion > sentInstanceIt->value) {
|
||||||
|
|
||||||
// this instance version was deleted and we haven't sent the delete to this client yet
|
// this instance version was deleted and we haven't sent the delete to this client yet
|
||||||
bytesWritten += AvatarTraits::packInstancedTraitDelete(traitType, instanceID, traitsPacketList, absoluteReceivedVersion);
|
bytesWritten += AvatarTraits::packInstancedTraitDelete(traitType, instanceID, traitsPacketList, absoluteReceivedVersion);
|
||||||
|
|
||||||
|
@ -180,6 +182,7 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis
|
||||||
listeningNodeData->setLastOtherAvatarTraitsSendPoint(otherNodeLocalID, timeOfLastTraitsChange);
|
listeningNodeData->setLastOtherAvatarTraitsSendPoint(otherNodeLocalID, timeOfLastTraitsChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,8 @@ macro(install_beside_console)
|
||||||
install(CODE "
|
install(CODE "
|
||||||
set(MACOSX_BUNDLE_EXECUTABLE_NAME domain-server)
|
set(MACOSX_BUNDLE_EXECUTABLE_NAME domain-server)
|
||||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.server-components)
|
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.server-components)
|
||||||
set(MACOSX_BUNDLE_BUNDLE_NAME Sandbox\\ Components)
|
set(MACOSX_BUNDLE_BUNDLE_NAME Console\\ Components)
|
||||||
configure_file(${HF_CMAKE_DIR}/templates/MacOSXBundleSandboxComponentsInfo.plist.in ${ESCAPED_BUNDLE_NAME}/Contents/Info.plist)
|
configure_file(${HF_CMAKE_DIR}/templates/MacOSXBundleConsoleComponentsInfo.plist.in ${ESCAPED_BUNDLE_NAME}/Contents/Info.plist)
|
||||||
execute_process(COMMAND ${MACDEPLOYQT_COMMAND} ${ESCAPED_BUNDLE_NAME} -verbose=2 -executable=${ESCAPED_EXECUTABLE_NAME})"
|
execute_process(COMMAND ${MACDEPLOYQT_COMMAND} ${ESCAPED_BUNDLE_NAME} -verbose=2 -executable=${ESCAPED_EXECUTABLE_NAME})"
|
||||||
COMPONENT ${SERVER_COMPONENT}
|
COMPONENT ${SERVER_COMPONENT}
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,7 +18,7 @@ macro(SET_PACKAGING_PARAMETERS)
|
||||||
set(BUILD_GLOBAL_SERVICES "DEVELOPMENT")
|
set(BUILD_GLOBAL_SERVICES "DEVELOPMENT")
|
||||||
set(USE_STABLE_GLOBAL_SERVICES 0)
|
set(USE_STABLE_GLOBAL_SERVICES 0)
|
||||||
set(BUILD_NUMBER 0)
|
set(BUILD_NUMBER 0)
|
||||||
set(APP_USER_MODEL_ID "com.highfidelity.sandbox-dev")
|
set(APP_USER_MODEL_ID "com.highfidelity.console-dev")
|
||||||
|
|
||||||
set_from_env(RELEASE_TYPE RELEASE_TYPE "DEV")
|
set_from_env(RELEASE_TYPE RELEASE_TYPE "DEV")
|
||||||
set_from_env(RELEASE_NUMBER RELEASE_NUMBER "")
|
set_from_env(RELEASE_NUMBER RELEASE_NUMBER "")
|
||||||
|
@ -37,6 +37,7 @@ macro(SET_PACKAGING_PARAMETERS)
|
||||||
set(BUILD_VERSION ${RELEASE_NUMBER})
|
set(BUILD_VERSION ${RELEASE_NUMBER})
|
||||||
set(BUILD_ORGANIZATION "High Fidelity")
|
set(BUILD_ORGANIZATION "High Fidelity")
|
||||||
set(HIGH_FIDELITY_PROTOCOL "hifi")
|
set(HIGH_FIDELITY_PROTOCOL "hifi")
|
||||||
|
set(HIGH_FIDELITY_APP_PROTOCOL "hifiapp")
|
||||||
set(INTERFACE_BUNDLE_NAME "Interface")
|
set(INTERFACE_BUNDLE_NAME "Interface")
|
||||||
set(INTERFACE_ICON_PREFIX "interface")
|
set(INTERFACE_ICON_PREFIX "interface")
|
||||||
|
|
||||||
|
@ -142,7 +143,12 @@ macro(SET_PACKAGING_PARAMETERS)
|
||||||
set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||||
set(INTERFACE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
set(INTERFACE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||||
|
|
||||||
set(CONSOLE_EXEC_NAME "Sandbox.app")
|
if (CLIENT_ONLY)
|
||||||
|
set(CONSOLE_EXEC_NAME "Console.app")
|
||||||
|
else ()
|
||||||
|
set(CONSOLE_EXEC_NAME "Sandbox.app")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(CONSOLE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${CONSOLE_EXEC_NAME}")
|
set(CONSOLE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${CONSOLE_EXEC_NAME}")
|
||||||
|
|
||||||
set(CONSOLE_APP_CONTENTS "${CONSOLE_INSTALL_APP_PATH}/Contents")
|
set(CONSOLE_APP_CONTENTS "${CONSOLE_INSTALL_APP_PATH}/Contents")
|
||||||
|
@ -176,16 +182,19 @@ macro(SET_PACKAGING_PARAMETERS)
|
||||||
# shortcut names
|
# shortcut names
|
||||||
if (PRODUCTION_BUILD)
|
if (PRODUCTION_BUILD)
|
||||||
set(INTERFACE_SHORTCUT_NAME "High Fidelity Interface")
|
set(INTERFACE_SHORTCUT_NAME "High Fidelity Interface")
|
||||||
set(CONSOLE_SHORTCUT_NAME "Sandbox")
|
set(CONSOLE_SHORTCUT_NAME "Console")
|
||||||
set(APP_USER_MODEL_ID "com.highfidelity.sandbox")
|
set(SANDBOX_SHORTCUT_NAME "Sandbox")
|
||||||
|
set(APP_USER_MODEL_ID "com.highfidelity.console")
|
||||||
else ()
|
else ()
|
||||||
set(INTERFACE_SHORTCUT_NAME "High Fidelity Interface - ${BUILD_VERSION_NO_SHA}")
|
set(INTERFACE_SHORTCUT_NAME "High Fidelity Interface - ${BUILD_VERSION_NO_SHA}")
|
||||||
set(CONSOLE_SHORTCUT_NAME "Sandbox - ${BUILD_VERSION_NO_SHA}")
|
set(CONSOLE_SHORTCUT_NAME "Console - ${BUILD_VERSION_NO_SHA}")
|
||||||
|
set(SANDBOX_SHORTCUT_NAME "Sandbox - ${BUILD_VERSION_NO_SHA}")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(INTERFACE_HF_SHORTCUT_NAME "${INTERFACE_SHORTCUT_NAME}")
|
set(INTERFACE_HF_SHORTCUT_NAME "${INTERFACE_SHORTCUT_NAME}")
|
||||||
set(CONSOLE_HF_SHORTCUT_NAME "High Fidelity ${CONSOLE_SHORTCUT_NAME}")
|
set(CONSOLE_HF_SHORTCUT_NAME "High Fidelity ${CONSOLE_SHORTCUT_NAME}")
|
||||||
|
set(SANDBOX_HF_SHORTCUT_NAME "High Fidelity ${SANDBOX_SHORTCUT_NAME}")
|
||||||
|
|
||||||
set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "High Fidelity")
|
set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "High Fidelity")
|
||||||
set(PRE_SANDBOX_CONSOLE_SHORTCUT_NAME "Server Console")
|
set(PRE_SANDBOX_CONSOLE_SHORTCUT_NAME "Server Console")
|
||||||
|
|
||||||
|
|
22
cmake/macros/TargetHifiAudioCodec.cmake
Normal file
22
cmake/macros/TargetHifiAudioCodec.cmake
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# Copyright 2018 High Fidelity, Inc.
|
||||||
|
# Created by Gabriel Calero and Cristian Duarte on 2018/10/05
|
||||||
|
#
|
||||||
|
# Distributed under the Apache License, Version 2.0.
|
||||||
|
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
#
|
||||||
|
macro(TARGET_HIFIAUDIOCODEC)
|
||||||
|
if (ANDROID)
|
||||||
|
set(HIFIAC_INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/hifiAC/codecSDK)
|
||||||
|
set(HIFIAC_LIB_DIR "${HIFIAC_INSTALL_DIR}/Release")
|
||||||
|
set(HIFIAC_INCLUDE_DIRS "${HIFIAC_INSTALL_DIR}/include" CACHE TYPE INTERNAL)
|
||||||
|
list(APPEND HIFIAC_LIBS "${HIFIAC_LIB_DIR}/libaudio.a")
|
||||||
|
set(HIFIAC_LIBRARIES ${HIFIAC_LIBS} CACHE TYPE INTERNAL)
|
||||||
|
else()
|
||||||
|
add_dependency_external_projects(hifiAudioCodec)
|
||||||
|
target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${TARGET_NAME} ${HIFIAUDIOCODEC_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAC_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${TARGET_NAME} ${HIFIAC_LIBRARIES})
|
||||||
|
endmacro()
|
|
@ -42,6 +42,14 @@
|
||||||
<string>hifi</string>
|
<string>hifi</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_NAME} APP URL</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>hifiapp</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
|
|
@ -13,10 +13,12 @@ set(INTERFACE_DISPLAY_NAME "Interface")
|
||||||
set(INTERFACE_SHORTCUT_NAME "@INTERFACE_SHORTCUT_NAME@")
|
set(INTERFACE_SHORTCUT_NAME "@INTERFACE_SHORTCUT_NAME@")
|
||||||
set(INTERFACE_HF_SHORTCUT_NAME "@INTERFACE_HF_SHORTCUT_NAME@")
|
set(INTERFACE_HF_SHORTCUT_NAME "@INTERFACE_HF_SHORTCUT_NAME@")
|
||||||
set(INTERFACE_WIN_EXEC_NAME "@INTERFACE_EXEC_PREFIX@.exe")
|
set(INTERFACE_WIN_EXEC_NAME "@INTERFACE_EXEC_PREFIX@.exe")
|
||||||
set(CONSOLE_DISPLAY_NAME "Sandbox")
|
set(CONSOLE_DISPLAY_NAME "Console")
|
||||||
set(CONSOLE_INSTALL_SUBDIR "@CONSOLE_INSTALL_DIR@")
|
set(CONSOLE_INSTALL_SUBDIR "@CONSOLE_INSTALL_DIR@")
|
||||||
set(CONSOLE_SHORTCUT_NAME "@CONSOLE_SHORTCUT_NAME@")
|
set(CONSOLE_SHORTCUT_NAME "@CONSOLE_SHORTCUT_NAME@")
|
||||||
set(CONSOLE_HF_SHORTCUT_NAME "@CONSOLE_HF_SHORTCUT_NAME@")
|
set(CONSOLE_HF_SHORTCUT_NAME "@CONSOLE_HF_SHORTCUT_NAME@")
|
||||||
|
set(SANDBOX_SHORTCUT_NAME "@SANDBOX_SHORTCUT_NAME@")
|
||||||
|
set(SANDBOX_HF_SHORTCUT_NAME "@SANDBOX_HF_SHORTCUT_NAME@")
|
||||||
set(CONSOLE_WIN_EXEC_NAME "@CONSOLE_EXEC_NAME@")
|
set(CONSOLE_WIN_EXEC_NAME "@CONSOLE_EXEC_NAME@")
|
||||||
set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "@PRE_SANDBOX_INTERFACE_SHORTCUT_NAME@")
|
set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "@PRE_SANDBOX_INTERFACE_SHORTCUT_NAME@")
|
||||||
set(PRE_SANDBOX_CONSOLE_SHORTCUT_NAME "@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@")
|
set(PRE_SANDBOX_CONSOLE_SHORTCUT_NAME "@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@")
|
||||||
|
@ -25,6 +27,7 @@ set(DS_EXEC_NAME "@DS_EXEC_NAME@")
|
||||||
set(AC_DISPLAY_NAME "Assignment Client")
|
set(AC_DISPLAY_NAME "Assignment Client")
|
||||||
set(AC_EXEC_NAME "@AC_EXEC_NAME@")
|
set(AC_EXEC_NAME "@AC_EXEC_NAME@")
|
||||||
set(HIGH_FIDELITY_PROTOCOL "@HIGH_FIDELITY_PROTOCOL@")
|
set(HIGH_FIDELITY_PROTOCOL "@HIGH_FIDELITY_PROTOCOL@")
|
||||||
|
set(HIGH_FIDELITY_APP_PROTOCOL "@HIGH_FIDELITY_APP_PROTOCOL@")
|
||||||
set(PRODUCTION_BUILD "@PRODUCTION_BUILD@")
|
set(PRODUCTION_BUILD "@PRODUCTION_BUILD@")
|
||||||
set(PR_BUILD "@PR_BUILD@")
|
set(PR_BUILD "@PR_BUILD@")
|
||||||
set(BUILD_ORGANIZATION "@BUILD_ORGANIZATION@")
|
set(BUILD_ORGANIZATION "@BUILD_ORGANIZATION@")
|
||||||
|
|
|
@ -405,6 +405,14 @@ Var GAClientID
|
||||||
Section "-Previous Install Cleanup"
|
Section "-Previous Install Cleanup"
|
||||||
; Remove the resources folder so we don't end up including removed QML files
|
; Remove the resources folder so we don't end up including removed QML files
|
||||||
RMDir /r "$INSTDIR\resources"
|
RMDir /r "$INSTDIR\resources"
|
||||||
|
|
||||||
|
; delete old assignment-client and domain-server so they're no longer present
|
||||||
|
; in client only installs.
|
||||||
|
Delete "$INSTDIR\@DS_EXEC_NAME@"
|
||||||
|
Delete "$INSTDIR\@AC_EXEC_NAME@"
|
||||||
|
|
||||||
|
; delete interface so it's not there for server-only installs
|
||||||
|
Delete "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@"
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
@CPACK_NSIS_INSTALLATION_TYPES@
|
@CPACK_NSIS_INSTALLATION_TYPES@
|
||||||
|
@ -532,9 +540,9 @@ SectionEnd
|
||||||
|
|
||||||
Var PostInstallDialog
|
Var PostInstallDialog
|
||||||
Var DesktopClientCheckbox
|
Var DesktopClientCheckbox
|
||||||
Var DesktopServerCheckbox
|
Var DesktopConsoleCheckbox
|
||||||
Var ServerStartupCheckbox
|
Var ConsoleStartupCheckbox
|
||||||
Var LaunchServerNowCheckbox
|
Var LaunchConsoleNowCheckbox
|
||||||
Var LaunchClientNowCheckbox
|
Var LaunchClientNowCheckbox
|
||||||
Var CleanInstallCheckbox
|
Var CleanInstallCheckbox
|
||||||
Var CurrentOffset
|
Var CurrentOffset
|
||||||
|
@ -747,32 +755,20 @@ Function PostInstallOptionsPage
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
${If} @SERVER_COMPONENT_CONDITIONAL@
|
||||||
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @SANDBOX_HF_SHORTCUT_NAME@"
|
||||||
|
${Else}
|
||||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@"
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@"
|
||||||
Pop $DesktopServerCheckbox
|
|
||||||
IntOp $CurrentOffset $CurrentOffset + 15
|
|
||||||
|
|
||||||
; set the checkbox state depending on what is present in the registry
|
|
||||||
!insertmacro SetInstallOption $DesktopServerCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED}
|
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
|
||||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install"
|
|
||||||
Pop $LaunchServerNowCheckbox
|
|
||||||
|
|
||||||
; set the checkbox state depending on what is present in the registry
|
|
||||||
!insertmacro SetInstallOption $LaunchServerNowCheckbox @SERVER_LAUNCH_NOW_REG_KEY@ ${BST_CHECKED}
|
|
||||||
${StrContains} $substringResult "/forceNoLaunchServer" $CMDLINE
|
|
||||||
${IfNot} $substringResult == ""
|
|
||||||
${NSD_SetState} $LaunchServerNowCheckbox ${BST_UNCHECKED}
|
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
IntOp $CurrentOffset $CurrentOffset + 15
|
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
|
Pop $DesktopConsoleCheckbox
|
||||||
|
IntOp $CurrentOffset $CurrentOffset + 15
|
||||||
|
; set the checkbox state depending on what is present in the registry
|
||||||
|
!insertmacro SetInstallOption $DesktopConsoleCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED}
|
||||||
|
|
||||||
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
||||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @INTERFACE_HF_SHORTCUT_NAME@ after install"
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @INTERFACE_HF_SHORTCUT_NAME@ after install"
|
||||||
Pop $LaunchClientNowCheckbox
|
Pop $LaunchClientNowCheckbox
|
||||||
IntOp $CurrentOffset $CurrentOffset + 30
|
IntOp $CurrentOffset $CurrentOffset + 15
|
||||||
|
|
||||||
; set the checkbox state depending on what is present in the registry
|
; set the checkbox state depending on what is present in the registry
|
||||||
!insertmacro SetInstallOption $LaunchClientNowCheckbox @CLIENT_LAUNCH_NOW_REG_KEY@ ${BST_CHECKED}
|
!insertmacro SetInstallOption $LaunchClientNowCheckbox @CLIENT_LAUNCH_NOW_REG_KEY@ ${BST_CHECKED}
|
||||||
|
@ -783,27 +779,44 @@ Function PostInstallOptionsPage
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
${If} @SERVER_COMPONENT_CONDITIONAL@
|
||||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup"
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ after install"
|
||||||
Pop $ServerStartupCheckbox
|
${Else}
|
||||||
IntOp $CurrentOffset $CurrentOffset + 15
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install"
|
||||||
|
|
||||||
; set the checkbox state depending on what is present in the registry
|
|
||||||
!insertmacro SetInstallOption $ServerStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_CHECKED}
|
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
Pop $LaunchConsoleNowCheckbox
|
||||||
|
|
||||||
|
; set the checkbox state depending on what is present in the registry
|
||||||
|
!insertmacro SetInstallOption $LaunchConsoleNowCheckbox @SERVER_LAUNCH_NOW_REG_KEY@ ${BST_CHECKED}
|
||||||
|
${StrContains} $substringResult "/forceNoLaunchServer" $CMDLINE
|
||||||
|
${IfNot} $substringResult == ""
|
||||||
|
${NSD_SetState} $LaunchConsoleNowCheckbox ${BST_UNCHECKED}
|
||||||
|
${EndIf}
|
||||||
|
IntOp $CurrentOffset $CurrentOffset + 30
|
||||||
|
|
||||||
|
${If} @SERVER_COMPONENT_CONDITIONAL@
|
||||||
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ on startup"
|
||||||
|
${Else}
|
||||||
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup"
|
||||||
|
${EndIf}
|
||||||
|
Pop $ConsoleStartupCheckbox
|
||||||
|
IntOp $CurrentOffset $CurrentOffset + 15
|
||||||
|
|
||||||
|
; set the checkbox state depending on what is present in the registry
|
||||||
|
!insertmacro SetInstallOption $ConsoleStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_CHECKED}
|
||||||
|
|
||||||
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Perform a clean install (Delete older settings and content)"
|
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Perform a clean install (Delete older settings and content)"
|
||||||
Pop $CleanInstallCheckbox
|
Pop $CleanInstallCheckbox
|
||||||
IntOp $CurrentOffset $CurrentOffset + 15
|
IntOp $CurrentOffset $CurrentOffset + 15
|
||||||
|
|
||||||
${If} @PR_BUILD@ == 1
|
${If} @PR_BUILD@ == 1
|
||||||
; a PR build defaults all install options expect LaunchServerNowCheckbox, LaunchClientNowCheckbox and the settings copy to unchecked
|
; a PR build defaults all install options expect LaunchConsoleNowCheckbox, LaunchClientNowCheckbox and the settings copy to unchecked
|
||||||
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
||||||
${NSD_SetState} $DesktopClientCheckbox ${BST_UNCHECKED}
|
${NSD_SetState} $DesktopClientCheckbox ${BST_UNCHECKED}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
${If} @SERVER_COMPONENT_CONDITIONAL@
|
||||||
${NSD_SetState} $DesktopServerCheckbox ${BST_UNCHECKED}
|
${NSD_SetState} $DesktopConsoleCheckbox ${BST_UNCHECKED}
|
||||||
${NSD_SetState} $ServerStartupCheckbox ${BST_UNCHECKED}
|
${NSD_SetState} $ConsoleStartupCheckbox ${BST_UNCHECKED}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
; push the offset
|
; push the offset
|
||||||
|
@ -824,9 +837,9 @@ FunctionEnd
|
||||||
!macroend
|
!macroend
|
||||||
|
|
||||||
Var DesktopClientState
|
Var DesktopClientState
|
||||||
Var DesktopServerState
|
Var DesktopConsoleState
|
||||||
Var ServerStartupState
|
Var ConsoleStartupState
|
||||||
Var LaunchServerNowState
|
Var LaunchConsoleNowState
|
||||||
Var LaunchClientNowState
|
Var LaunchClientNowState
|
||||||
Var CopyFromProductionState
|
Var CopyFromProductionState
|
||||||
Var CleanInstallState
|
Var CleanInstallState
|
||||||
|
@ -842,11 +855,11 @@ Function ReadInstallTypes
|
||||||
StrCpy $Express "1"
|
StrCpy $Express "1"
|
||||||
|
|
||||||
StrCpy $DesktopClientState ${BST_CHECKED}
|
StrCpy $DesktopClientState ${BST_CHECKED}
|
||||||
StrCpy $ServerStartupState ${BST_CHECKED}
|
StrCpy $ConsoleStartupState ${BST_CHECKED}
|
||||||
StrCpy $LaunchServerNowState ${BST_CHECKED}
|
StrCpy $LaunchConsoleNowState ${BST_CHECKED}
|
||||||
StrCpy $LaunchClientNowState ${BST_CHECKED}
|
StrCpy $LaunchClientNowState ${BST_CHECKED}
|
||||||
StrCpy $CleanInstallState ${BST_UNCHECKED}
|
StrCpy $CleanInstallState ${BST_UNCHECKED}
|
||||||
StrCpy $DesktopServerState ${BST_UNCHECKED}
|
StrCpy $DesktopConsoleState ${BST_UNCHECKED}
|
||||||
|
|
||||||
${If} @PR_BUILD@ == 1
|
${If} @PR_BUILD@ == 1
|
||||||
StrCpy $CopyFromProductionState ${BST_UNCHECKED}
|
StrCpy $CopyFromProductionState ${BST_UNCHECKED}
|
||||||
|
@ -860,28 +873,25 @@ Function ReadInstallTypes
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
Function ReadPostInstallOptions
|
Function ReadPostInstallOptions
|
||||||
|
|
||||||
|
; check if the user asked for a desktop shortcut to console
|
||||||
|
${NSD_GetState} $DesktopConsoleCheckbox $DesktopConsoleState
|
||||||
|
|
||||||
|
; check if the user asked to have console launched every startup
|
||||||
|
${NSD_GetState} $ConsoleStartupCheckbox $ConsoleStartupState
|
||||||
|
|
||||||
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
||||||
; check if the user asked for a desktop shortcut to High Fidelity
|
; check if the user asked for a desktop shortcut to High Fidelity
|
||||||
${NSD_GetState} $DesktopClientCheckbox $DesktopClientState
|
${NSD_GetState} $DesktopClientCheckbox $DesktopClientState
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
|
||||||
; check if the user asked for a desktop shortcut to Sandbox
|
|
||||||
${NSD_GetState} $DesktopServerCheckbox $DesktopServerState
|
|
||||||
|
|
||||||
; check if the user asked to have Sandbox launched every startup
|
|
||||||
${NSD_GetState} $ServerStartupCheckbox $ServerStartupState
|
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
${If} @PR_BUILD@ == 1
|
${If} @PR_BUILD@ == 1
|
||||||
; check if we need to copy settings/content from production for this PR build
|
; check if we need to copy settings/content from production for this PR build
|
||||||
${NSD_GetState} $CopyFromProductionCheckbox $CopyFromProductionState
|
${NSD_GetState} $CopyFromProductionCheckbox $CopyFromProductionState
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
; check if we need to launch the console post-install
|
||||||
; check if we need to launch the server post-install
|
${NSD_GetState} $LaunchConsoleNowCheckbox $LaunchConsoleNowState
|
||||||
${NSD_GetState} $LaunchServerNowCheckbox $LaunchServerNowState
|
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
||||||
; check if we need to launch the client post-install
|
; check if we need to launch the client post-install
|
||||||
|
@ -893,6 +903,31 @@ Function ReadPostInstallOptions
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
Function HandlePostInstallOptions
|
Function HandlePostInstallOptions
|
||||||
|
|
||||||
|
${If} @SERVER_COMPONENT_CONDITIONAL@
|
||||||
|
; check if the user asked for a desktop shortcut to the console
|
||||||
|
${If} $DesktopConsoleState == ${BST_CHECKED}
|
||||||
|
Delete "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
|
||||||
|
CreateShortCut "$DESKTOP\@SANDBOX_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||||
|
!insertmacro WriteInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ YES
|
||||||
|
; Set appUserModelId
|
||||||
|
ApplicationID::Set "$DESKTOP\@SANDBOX_HF_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@"
|
||||||
|
${Else}
|
||||||
|
!insertmacro WriteInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO
|
||||||
|
${EndIf}
|
||||||
|
${Else}
|
||||||
|
; check if the user asked for a desktop shortcut to the console
|
||||||
|
${If} $DesktopConsoleState == ${BST_CHECKED}
|
||||||
|
Delete "$DESKTOP\@SANDBOX_HF_SHORTCUT_NAME@.lnk"
|
||||||
|
CreateShortCut "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||||
|
!insertmacro WriteInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ YES
|
||||||
|
; Set appUserModelId
|
||||||
|
ApplicationID::Set "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@"
|
||||||
|
${Else}
|
||||||
|
!insertmacro WriteInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO
|
||||||
|
${EndIf}
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
${If} @CLIENT_COMPONENT_CONDITIONAL@
|
||||||
; check if the user asked for a desktop shortcut to High Fidelity
|
; check if the user asked for a desktop shortcut to High Fidelity
|
||||||
${If} $DesktopClientState == ${BST_CHECKED}
|
${If} $DesktopClientState == ${BST_CHECKED}
|
||||||
|
@ -901,38 +936,25 @@ Function HandlePostInstallOptions
|
||||||
${Else}
|
${Else}
|
||||||
!insertmacro WriteInstallOption @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ NO
|
!insertmacro WriteInstallOption @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ NO
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
; check if the user asked to have Console launched every startup
|
||||||
; check if the user asked for a desktop shortcut to Sandbox
|
${If} $ConsoleStartupState == ${BST_CHECKED}
|
||||||
${If} $DesktopServerState == ${BST_CHECKED}
|
; in case we added a shortcut in the global context, pull that now
|
||||||
CreateShortCut "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
SetShellVarContext all
|
||||||
!insertmacro WriteInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ YES
|
Delete "$SMSTARTUP\@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@.lnk"
|
||||||
; Set appUserModelId
|
|
||||||
ApplicationID::Set "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@"
|
|
||||||
${Else}
|
|
||||||
!insertmacro WriteInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO
|
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
|
; make a startup shortcut in this user's current context
|
||||||
|
; use the console shortcut name regardless of server/interface install
|
||||||
|
SetShellVarContext current
|
||||||
|
CreateShortCut "$SMSTARTUP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||||
|
|
||||||
; check if the user asked to have Sandbox launched every startup
|
; reset the shell var context back
|
||||||
${If} $ServerStartupState == ${BST_CHECKED}
|
SetShellVarContext all
|
||||||
; in case we added a shortcut in the global context, pull that now
|
|
||||||
SetShellVarContext all
|
|
||||||
Delete "$SMSTARTUP\@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@.lnk"
|
|
||||||
|
|
||||||
; make a startup shortcut in this user's current context
|
!insertmacro WriteInstallOption @CONSOLE_STARTUP_REG_KEY@ YES
|
||||||
SetShellVarContext current
|
${Else}
|
||||||
CreateShortCut "$SMSTARTUP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
!insertmacro WriteInstallOption @CONSOLE_STARTUP_REG_KEY@ NO
|
||||||
|
|
||||||
; reset the shell var context back
|
|
||||||
SetShellVarContext all
|
|
||||||
|
|
||||||
!insertmacro WriteInstallOption @CONSOLE_STARTUP_REG_KEY@ YES
|
|
||||||
${Else}
|
|
||||||
!insertmacro WriteInstallOption @CONSOLE_STARTUP_REG_KEY@ NO
|
|
||||||
${EndIf}
|
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
; check if the user asked for a clean install
|
; check if the user asked for a clean install
|
||||||
|
@ -982,32 +1004,38 @@ Function HandlePostInstallOptions
|
||||||
${EndIf}
|
${EndIf}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
${If} $LaunchClientNowState == ${BST_CHECKED}
|
||||||
${AndIf} $LaunchServerNowState == ${BST_CHECKED}
|
|
||||||
!insertmacro WriteInstallOption @SERVER_LAUNCH_NOW_REG_KEY@ YES
|
|
||||||
|
|
||||||
; both launches use the explorer trick in case the user has elevated permissions for the installer
|
|
||||||
${If} $LaunchClientNowState == ${BST_CHECKED}
|
|
||||||
!insertmacro WriteInstallOption @CLIENT_LAUNCH_NOW_REG_KEY@ YES
|
!insertmacro WriteInstallOption @CLIENT_LAUNCH_NOW_REG_KEY@ YES
|
||||||
; create shortcut with ARGUMENTS
|
${Else}
|
||||||
CreateShortCut "$TEMP\SandboxShortcut.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@" "-- --launchInterface"
|
|
||||||
Exec '"$WINDIR\explorer.exe" "$TEMP\SandboxShortcut.lnk"'
|
|
||||||
${Else}
|
|
||||||
!insertmacro WriteInstallOption @CLIENT_LAUNCH_NOW_REG_KEY@ NO
|
!insertmacro WriteInstallOption @CLIENT_LAUNCH_NOW_REG_KEY@ NO
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
|
${If} $LaunchConsoleNowState == ${BST_CHECKED}
|
||||||
|
!insertmacro WriteInstallOption @SERVER_LAUNCH_NOW_REG_KEY@ YES
|
||||||
|
${Else}
|
||||||
|
!insertmacro WriteInstallOption @SERVER_LAUNCH_NOW_REG_KEY@ NO
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
|
${If} $LaunchConsoleNowState == ${BST_CHECKED}
|
||||||
|
${If} @SERVER_COMPONENT_CONDITIONAL@
|
||||||
|
${AndIf} $LaunchClientNowState == ${BST_CHECKED}
|
||||||
|
${AndIf} @CLIENT_COMPONENT_CONDITIONAL@
|
||||||
|
; both launches use the explorer trick in case the user has elevated permissions for the installer
|
||||||
|
; create shortcut with ARGUMENTS
|
||||||
|
CreateShortCut "$TEMP\ConsoleShortcut.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@" "-- --launchInterface"
|
||||||
|
Exec '"$WINDIR\explorer.exe" "$TEMP\ConsoleShortcut.lnk"'
|
||||||
|
${Else}
|
||||||
Exec '"$WINDIR\explorer.exe" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"'
|
Exec '"$WINDIR\explorer.exe" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"'
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
${ElseIf} @CLIENT_COMPONENT_CONDITIONAL@
|
${If} $LaunchClientNowState == ${BST_CHECKED}
|
||||||
!insertmacro WriteInstallOption @SERVER_LAUNCH_NOW_REG_KEY@ NO
|
${AndIf} @CLIENT_COMPONENT_CONDITIONAL@
|
||||||
|
${Unless} $LaunchConsoleNowState == ${BST_CHECKED}
|
||||||
; launch uses the explorer trick in case the user has elevated permissions for the installer
|
${OrUnless} @SERVER_COMPONENT_CONDITIONAL@
|
||||||
${If} $LaunchClientNowState == ${BST_CHECKED}
|
; launch uses the explorer trick in case the user has elevated permissions for the installer
|
||||||
!insertmacro WriteInstallOption @CLIENT_LAUNCH_NOW_REG_KEY@ YES
|
|
||||||
Exec '"$WINDIR\explorer.exe" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@"'
|
Exec '"$WINDIR\explorer.exe" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@"'
|
||||||
${Else}
|
|
||||||
!insertmacro WriteInstallOption @CLIENT_LAUNCH_NOW_REG_KEY@ NO
|
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${EndIf}
|
${EndIf}
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
@ -1164,8 +1192,16 @@ Section "-Core installation"
|
||||||
|
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
; Conditional handling for server console shortcut
|
|
||||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
${If} @SERVER_COMPONENT_CONDITIONAL@
|
||||||
|
; handling for server console shortcut
|
||||||
|
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk"
|
||||||
|
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_SHORTCUT_NAME@.lnk" \
|
||||||
|
"$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||||
|
; Set appUserModelId
|
||||||
|
ApplicationID::Set "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@"
|
||||||
|
${Else}
|
||||||
|
; handling for interface only console shortcut
|
||||||
|
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_SHORTCUT_NAME@.lnk"
|
||||||
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \
|
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \
|
||||||
"$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
"$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
|
||||||
; Set appUserModelId
|
; Set appUserModelId
|
||||||
|
@ -1376,12 +1412,15 @@ Section "Uninstall"
|
||||||
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
|
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
|
||||||
Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk"
|
Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk"
|
||||||
Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk"
|
Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk"
|
||||||
|
Delete "$SMPROGRAMS\$MUI_TEMP\@SANDBOX_SHORTCUT_NAME@.lnk"
|
||||||
Delete "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk"
|
Delete "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk"
|
||||||
Delete "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
|
Delete "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
|
||||||
|
Delete "$DESKTOP\@SANDBOX_HF_SHORTCUT_NAME@.lnk"
|
||||||
|
|
||||||
; if it exists, delete the startup shortcut for the current user
|
; if it exists, delete the startup shortcut for the current user
|
||||||
SetShellVarContext current
|
SetShellVarContext current
|
||||||
Delete "$SMSTARTUP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
|
Delete "$SMSTARTUP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
|
||||||
|
Delete "$SMSTARTUP\@SANDBOX_HF_SHORTCUT_NAME@.lnk"
|
||||||
SetShellVarContext all
|
SetShellVarContext all
|
||||||
|
|
||||||
@CPACK_NSIS_DELETE_ICONS@
|
@CPACK_NSIS_DELETE_ICONS@
|
||||||
|
@ -1414,6 +1453,7 @@ Section "Uninstall"
|
||||||
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
|
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
|
||||||
Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk"
|
Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk"
|
||||||
Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk"
|
Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk"
|
||||||
|
Delete "$SMPROGRAMS\$MUI_TEMP\@SANDBOX_SHORTCUT_NAME@.lnk"
|
||||||
@CPACK_NSIS_DELETE_ICONS_EXTRA@
|
@CPACK_NSIS_DELETE_ICONS_EXTRA@
|
||||||
|
|
||||||
;Delete empty start menu parent diretories
|
;Delete empty start menu parent diretories
|
||||||
|
|
BIN
interface/resources/images/interstitialPage/button.png
Normal file
BIN
interface/resources/images/interstitialPage/button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
interface/resources/images/interstitialPage/button_back.png
Normal file
BIN
interface/resources/images/interstitialPage/button_back.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
interface/resources/images/interstitialPage/button_hover.png
Normal file
BIN
interface/resources/images/interstitialPage/button_hover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
interface/resources/images/interstitialPage/button_tryAgain.png
Normal file
BIN
interface/resources/images/interstitialPage/button_tryAgain.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
File diff suppressed because it is too large
Load diff
|
@ -122,6 +122,7 @@
|
||||||
#include <RecordingScriptingInterface.h>
|
#include <RecordingScriptingInterface.h>
|
||||||
#include <UpdateSceneTask.h>
|
#include <UpdateSceneTask.h>
|
||||||
#include <RenderViewTask.h>
|
#include <RenderViewTask.h>
|
||||||
|
#include <render/EngineStats.h>
|
||||||
#include <SecondaryCamera.h>
|
#include <SecondaryCamera.h>
|
||||||
#include <ResourceCache.h>
|
#include <ResourceCache.h>
|
||||||
#include <ResourceRequest.h>
|
#include <ResourceRequest.h>
|
||||||
|
@ -365,7 +366,6 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI
|
||||||
|
|
||||||
static const uint32_t INVALID_FRAME = UINT32_MAX;
|
static const uint32_t INVALID_FRAME = UINT32_MAX;
|
||||||
|
|
||||||
static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check for entities that aren't ready for simulation
|
|
||||||
static const float INITIAL_QUERY_RADIUS = 10.0f; // priority radius for entities before physics enabled
|
static const float INITIAL_QUERY_RADIUS = 10.0f; // priority radius for entities before physics enabled
|
||||||
|
|
||||||
static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||||
|
@ -5383,8 +5383,8 @@ void Application::resetPhysicsReadyInformation() {
|
||||||
// collision information of nearby entities to make running bullet be safe.
|
// collision information of nearby entities to make running bullet be safe.
|
||||||
_fullSceneReceivedCounter = 0;
|
_fullSceneReceivedCounter = 0;
|
||||||
_fullSceneCounterAtLastPhysicsCheck = 0;
|
_fullSceneCounterAtLastPhysicsCheck = 0;
|
||||||
_nearbyEntitiesCountAtLastPhysicsCheck = 0;
|
_gpuTextureMemSizeStabilityCount = 0;
|
||||||
_nearbyEntitiesStabilityCount = 0;
|
_gpuTextureMemSizeAtLastCheck = 0;
|
||||||
_physicsEnabled = false;
|
_physicsEnabled = false;
|
||||||
_octreeProcessor.startEntitySequence();
|
_octreeProcessor.startEntitySequence();
|
||||||
}
|
}
|
||||||
|
@ -5623,18 +5623,21 @@ void Application::update(float deltaTime) {
|
||||||
// for nearby entities before starting bullet up.
|
// for nearby entities before starting bullet up.
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) {
|
if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) {
|
||||||
// we've received a new full-scene octree stats packet, or it's been long enough to try again anyway
|
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
|
||||||
_lastPhysicsCheckTime = now;
|
if (gpuTextureMemSizeStable() || !enableInterstitial) {
|
||||||
_fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter;
|
// we've received a new full-scene octree stats packet, or it's been long enough to try again anyway
|
||||||
_lastQueriedViews.clear(); // Force new view.
|
_lastPhysicsCheckTime = now;
|
||||||
|
_fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter;
|
||||||
|
_lastQueriedViews.clear(); // Force new view.
|
||||||
|
|
||||||
// process octree stats packets are sent in between full sends of a scene (this isn't currently true).
|
// process octree stats packets are sent in between full sends of a scene (this isn't currently true).
|
||||||
// We keep physics disabled until we've received a full scene and everything near the avatar in that
|
// We keep physics disabled until we've received a full scene and everything near the avatar in that
|
||||||
// scene is ready to compute its collision shape.
|
// scene is ready to compute its collision shape.
|
||||||
if (getMyAvatar()->isReadyForPhysics()) {
|
if (getMyAvatar()->isReadyForPhysics()) {
|
||||||
_physicsEnabled = true;
|
_physicsEnabled = true;
|
||||||
setIsInterstitialMode(false);
|
setIsInterstitialMode(false);
|
||||||
getMyAvatar()->updateMotionBehaviorFromMenu();
|
getMyAvatar()->updateMotionBehaviorFromMenu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (domainLoadingInProgress) {
|
} else if (domainLoadingInProgress) {
|
||||||
|
@ -5921,6 +5924,10 @@ void Application::update(float deltaTime) {
|
||||||
// update the rendering without any simulation
|
// update the rendering without any simulation
|
||||||
getEntities()->update(false);
|
getEntities()->update(false);
|
||||||
}
|
}
|
||||||
|
// remove recently dead avatarEntities
|
||||||
|
SetOfEntities deadAvatarEntities;
|
||||||
|
_entitySimulation->takeDeadAvatarEntities(deadAvatarEntities);
|
||||||
|
avatarManager->removeDeadAvatarEntities(deadAvatarEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AvatarManager update
|
// AvatarManager update
|
||||||
|
@ -6245,6 +6252,8 @@ int Application::sendNackPackets() {
|
||||||
missingSequenceNumbers = sequenceNumberStats.getMissingSet();
|
missingSequenceNumbers = sequenceNumberStats.getMissingSet();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_isMissingSequenceNumbers = (missingSequenceNumbers.size() != 0);
|
||||||
|
|
||||||
// construct nack packet(s) for this node
|
// construct nack packet(s) for this node
|
||||||
foreach(const OCTREE_PACKET_SEQUENCE& missingNumber, missingSequenceNumbers) {
|
foreach(const OCTREE_PACKET_SEQUENCE& missingNumber, missingSequenceNumbers) {
|
||||||
nackPacketList->writePrimitive(missingNumber);
|
nackPacketList->writePrimitive(missingNumber);
|
||||||
|
@ -6271,9 +6280,19 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType) {
|
||||||
const bool isModifiedQuery = !_physicsEnabled;
|
const bool isModifiedQuery = !_physicsEnabled;
|
||||||
if (isModifiedQuery) {
|
if (isModifiedQuery) {
|
||||||
// Create modified view that is a simple sphere.
|
// Create modified view that is a simple sphere.
|
||||||
|
bool interstitialModeEnabled = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
|
||||||
|
|
||||||
ConicalViewFrustum sphericalView;
|
ConicalViewFrustum sphericalView;
|
||||||
sphericalView.setSimpleRadius(INITIAL_QUERY_RADIUS);
|
sphericalView.setSimpleRadius(INITIAL_QUERY_RADIUS);
|
||||||
_octreeQuery.setConicalViews({ sphericalView });
|
|
||||||
|
if (interstitialModeEnabled) {
|
||||||
|
ConicalViewFrustum farView;
|
||||||
|
farView.set(_viewFrustum);
|
||||||
|
_octreeQuery.setConicalViews({ sphericalView, farView });
|
||||||
|
} else {
|
||||||
|
_octreeQuery.setConicalViews({ sphericalView });
|
||||||
|
}
|
||||||
|
|
||||||
_octreeQuery.setOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE);
|
_octreeQuery.setOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE);
|
||||||
static constexpr float MIN_LOD_ADJUST = -20.0f;
|
static constexpr float MIN_LOD_ADJUST = -20.0f;
|
||||||
_octreeQuery.setBoundaryLevelAdjust(MIN_LOD_ADJUST);
|
_octreeQuery.setBoundaryLevelAdjust(MIN_LOD_ADJUST);
|
||||||
|
@ -6585,69 +6604,23 @@ void Application::trackIncomingOctreePacket(ReceivedMessage& message, SharedNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::nearbyEntitiesAreReadyForPhysics() {
|
bool Application::gpuTextureMemSizeStable() {
|
||||||
// this is used to avoid the following scenario:
|
auto renderConfig = qApp->getRenderEngine()->getConfiguration();
|
||||||
// A table has some items sitting on top of it. The items are at rest, meaning they aren't active in bullet.
|
auto renderStats = renderConfig->getConfig<render::EngineStats>("Stats");
|
||||||
// Someone logs in close to the table. They receive information about the items on the table before they
|
|
||||||
// receive information about the table. The items are very close to the avatar's capsule, so they become
|
|
||||||
// activated in bullet. This causes them to fall to the floor, because the table's shape isn't yet in bullet.
|
|
||||||
EntityTreePointer entityTree = getEntities()->getTree();
|
|
||||||
if (!entityTree) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't want to use EntityTree::findEntities(AABox, ...) method because that scan will snarf parented entities
|
qint64 textureResourceGPUMemSize = renderStats->textureResourceGPUMemSize;
|
||||||
// whose bounding boxes cannot be computed (it is too loose for our purposes here). Instead we manufacture
|
qint64 texturePopulatedGPUMemSize = renderStats->textureResourcePopulatedGPUMemSize;
|
||||||
// custom filters and use the general-purpose EntityTree::findEntities(filter, ...)
|
qint64 textureTransferSize = renderStats->texturePendingGPUTransferSize;
|
||||||
QVector<EntityItemPointer> entities;
|
|
||||||
AABox avatarBox(getMyAvatar()->getWorldPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE));
|
|
||||||
// create two functions that use avatarBox (entityScan and elementScan), the second calls the first
|
|
||||||
std::function<bool (EntityItemPointer&)> entityScan = [=](EntityItemPointer& entity) {
|
|
||||||
if (entity->shouldBePhysical()) {
|
|
||||||
bool success = false;
|
|
||||||
AABox entityBox = entity->getAABox(success);
|
|
||||||
// important: bail for entities that cannot supply a valid AABox
|
|
||||||
return success && avatarBox.touches(entityBox);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
std::function<bool(const OctreeElementPointer&, void*)> elementScan = [&](const OctreeElementPointer& element, void* unused) {
|
|
||||||
if (element->getAACube().touches(avatarBox)) {
|
|
||||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
|
||||||
entityTreeElement->getEntities(entityScan, entities);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
entityTree->withReadLock([&] {
|
if (_gpuTextureMemSizeAtLastCheck == textureResourceGPUMemSize) {
|
||||||
// Pass the second function to the general-purpose EntityTree::findEntities()
|
_gpuTextureMemSizeStabilityCount++;
|
||||||
// which will traverse the tree, apply the two filter functions (to element, then to entities)
|
|
||||||
// as it traverses. The end result will be a list of entities that match.
|
|
||||||
entityTree->findEntities(elementScan, entities);
|
|
||||||
});
|
|
||||||
|
|
||||||
uint32_t nearbyCount = entities.size();
|
|
||||||
if (nearbyCount == _nearbyEntitiesCountAtLastPhysicsCheck) {
|
|
||||||
_nearbyEntitiesStabilityCount++;
|
|
||||||
} else {
|
} else {
|
||||||
_nearbyEntitiesStabilityCount = 0;
|
_gpuTextureMemSizeStabilityCount = 0;
|
||||||
}
|
}
|
||||||
_nearbyEntitiesCountAtLastPhysicsCheck = nearbyCount;
|
_gpuTextureMemSizeAtLastCheck = textureResourceGPUMemSize;
|
||||||
|
|
||||||
const uint32_t MINIMUM_NEARBY_ENTITIES_STABILITY_COUNT = 3;
|
if (_gpuTextureMemSizeStabilityCount >= _minimumGPUTextureMemSizeStabilityCount) {
|
||||||
if (_nearbyEntitiesStabilityCount >= MINIMUM_NEARBY_ENTITIES_STABILITY_COUNT) {
|
return (textureResourceGPUMemSize == texturePopulatedGPUMemSize) && (textureTransferSize == 0);
|
||||||
// We've seen the same number of nearby entities for several stats packets in a row. assume we've got all
|
|
||||||
// the local entities.
|
|
||||||
bool result = true;
|
|
||||||
foreach (EntityItemPointer entity, entities) {
|
|
||||||
if (entity->shouldBePhysical() && !entity->isReadyToComputeShape()) {
|
|
||||||
HIFI_FCDEBUG(interfaceapp(), "Physics disabled until entity loads: " << entity->getID() << entity->getName());
|
|
||||||
// don't break here because we want all the relevant entities to start their downloads
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,8 @@ public:
|
||||||
// passes, mirror window passes, etc
|
// passes, mirror window passes, etc
|
||||||
void copyDisplayViewFrustum(ViewFrustum& viewOut) const;
|
void copyDisplayViewFrustum(ViewFrustum& viewOut) const;
|
||||||
|
|
||||||
|
bool isMissingSequenceNumbers() { return _isMissingSequenceNumbers; }
|
||||||
|
|
||||||
const ConicalViewFrustums& getConicalViews() const override { return _conicalViews; }
|
const ConicalViewFrustums& getConicalViews() const override { return _conicalViews; }
|
||||||
|
|
||||||
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
||||||
|
@ -230,6 +232,8 @@ public:
|
||||||
float getSettingConstrainToolbarPosition() { return _constrainToolbarPosition.get(); }
|
float getSettingConstrainToolbarPosition() { return _constrainToolbarPosition.get(); }
|
||||||
void setSettingConstrainToolbarPosition(bool setting);
|
void setSettingConstrainToolbarPosition(bool setting);
|
||||||
|
|
||||||
|
Q_INVOKABLE void setMinimumGPUTextureMemStabilityCount(int stabilityCount) { _minimumGPUTextureMemSizeStabilityCount = stabilityCount; }
|
||||||
|
|
||||||
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
|
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
|
||||||
|
|
||||||
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
|
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
|
||||||
|
@ -525,7 +529,7 @@ private:
|
||||||
bool importFromZIP(const QString& filePath);
|
bool importFromZIP(const QString& filePath);
|
||||||
bool importImage(const QString& urlString);
|
bool importImage(const QString& urlString);
|
||||||
|
|
||||||
bool nearbyEntitiesAreReadyForPhysics();
|
bool gpuTextureMemSizeStable();
|
||||||
int processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode);
|
int processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode);
|
||||||
void trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket);
|
void trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket);
|
||||||
|
|
||||||
|
@ -581,6 +585,8 @@ private:
|
||||||
QElapsedTimer _lastTimeUpdated;
|
QElapsedTimer _lastTimeUpdated;
|
||||||
QElapsedTimer _lastTimeRendered;
|
QElapsedTimer _lastTimeRendered;
|
||||||
|
|
||||||
|
int _minimumGPUTextureMemSizeStabilityCount { 30 };
|
||||||
|
|
||||||
ShapeManager _shapeManager;
|
ShapeManager _shapeManager;
|
||||||
PhysicalEntitySimulationPointer _entitySimulation;
|
PhysicalEntitySimulationPointer _entitySimulation;
|
||||||
PhysicsEnginePointer _physicsEngine;
|
PhysicsEnginePointer _physicsEngine;
|
||||||
|
@ -709,6 +715,8 @@ private:
|
||||||
|
|
||||||
bool _fakedMouseEvent { false };
|
bool _fakedMouseEvent { false };
|
||||||
|
|
||||||
|
bool _isMissingSequenceNumbers { false };
|
||||||
|
|
||||||
void checkChangeCursor();
|
void checkChangeCursor();
|
||||||
mutable QMutex _changeCursorLock { QMutex::Recursive };
|
mutable QMutex _changeCursorLock { QMutex::Recursive };
|
||||||
Qt::CursorShape _desiredCursor{ Qt::BlankCursor };
|
Qt::CursorShape _desiredCursor{ Qt::BlankCursor };
|
||||||
|
@ -719,8 +727,10 @@ private:
|
||||||
|
|
||||||
std::atomic<uint32_t> _fullSceneReceivedCounter { 0 }; // how many times have we received a full-scene octree stats packet
|
std::atomic<uint32_t> _fullSceneReceivedCounter { 0 }; // how many times have we received a full-scene octree stats packet
|
||||||
uint32_t _fullSceneCounterAtLastPhysicsCheck { 0 }; // _fullSceneReceivedCounter last time we checked physics ready
|
uint32_t _fullSceneCounterAtLastPhysicsCheck { 0 }; // _fullSceneReceivedCounter last time we checked physics ready
|
||||||
uint32_t _nearbyEntitiesCountAtLastPhysicsCheck { 0 }; // how many in-range entities last time we checked physics ready
|
|
||||||
uint32_t _nearbyEntitiesStabilityCount { 0 }; // how many times has _nearbyEntitiesCountAtLastPhysicsCheck been the same
|
qint64 _gpuTextureMemSizeStabilityCount { 0 };
|
||||||
|
qint64 _gpuTextureMemSizeAtLastCheck { 0 };
|
||||||
|
|
||||||
quint64 _lastPhysicsCheckTime { usecTimestampNow() }; // when did we last check to see if physics was ready
|
quint64 _lastPhysicsCheckTime { usecTimestampNow() }; // when did we last check to see if physics was ready
|
||||||
|
|
||||||
bool _keyboardDeviceHasFocus { true };
|
bool _keyboardDeviceHasFocus { true };
|
||||||
|
|
|
@ -452,6 +452,17 @@ void AvatarManager::handleProcessedPhysicsTransaction(PhysicsEngine::Transaction
|
||||||
transaction.clear();
|
transaction.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarManager::removeDeadAvatarEntities(const SetOfEntities& deadEntities) {
|
||||||
|
for (auto entity : deadEntities) {
|
||||||
|
QUuid sessionID = entity->getOwningAvatarID();
|
||||||
|
AvatarSharedPointer avatar = getAvatarBySessionID(sessionID);
|
||||||
|
if (avatar) {
|
||||||
|
const bool REQUIRES_REMOVAL_FROM_TREE = false;
|
||||||
|
avatar->clearAvatarEntity(entity->getID(), REQUIRES_REMOVAL_FROM_TREE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) {
|
void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) {
|
||||||
auto avatar = std::static_pointer_cast<OtherAvatar>(removedAvatar);
|
auto avatar = std::static_pointer_cast<OtherAvatar>(removedAvatar);
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <avatars-renderer/ScriptAvatar.h>
|
#include <avatars-renderer/ScriptAvatar.h>
|
||||||
#include <AudioInjector.h>
|
#include <AudioInjector.h>
|
||||||
#include <workload/Space.h>
|
#include <workload/Space.h>
|
||||||
|
#include <EntitySimulation.h> // for SetOfEntities
|
||||||
|
|
||||||
#include "AvatarMotionState.h"
|
#include "AvatarMotionState.h"
|
||||||
#include "MyAvatar.h"
|
#include "MyAvatar.h"
|
||||||
|
@ -187,6 +188,7 @@ public:
|
||||||
void queuePhysicsChange(const OtherAvatarPointer& avatar);
|
void queuePhysicsChange(const OtherAvatarPointer& avatar);
|
||||||
void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction);
|
void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction);
|
||||||
void handleProcessedPhysicsTransaction(PhysicsEngine::Transaction& transaction);
|
void handleProcessedPhysicsTransaction(PhysicsEngine::Transaction& transaction);
|
||||||
|
void removeDeadAvatarEntities(const SetOfEntities& deadEntities);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
|
|
@ -137,7 +137,7 @@ MyAvatar::MyAvatar(QThread* thread) :
|
||||||
_useSnapTurnSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "useSnapTurn", _useSnapTurn),
|
_useSnapTurnSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "useSnapTurn", _useSnapTurn),
|
||||||
_userHeightSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "userHeight", DEFAULT_AVATAR_HEIGHT),
|
_userHeightSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "userHeight", DEFAULT_AVATAR_HEIGHT),
|
||||||
_flyingHMDSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "flyingHMD", _flyingPrefHMD),
|
_flyingHMDSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "flyingHMD", _flyingPrefHMD),
|
||||||
_avatarEntityCountSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "avatarEntityData" << "size", _flyingPrefHMD)
|
_avatarEntityCountSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "avatarEntityData" << "size", 0)
|
||||||
{
|
{
|
||||||
_clientTraitsHandler = std::unique_ptr<ClientTraitsHandler>(new ClientTraitsHandler(this));
|
_clientTraitsHandler = std::unique_ptr<ClientTraitsHandler>(new ClientTraitsHandler(this));
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "SafeLanding.h"
|
#include "SafeLanding.h"
|
||||||
|
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
#include "EntityTreeRenderer.h"
|
#include "EntityTreeRenderer.h"
|
||||||
#include "ModelEntityItem.h"
|
#include "RenderableModelEntityItem.h"
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
||||||
|
@ -39,6 +42,7 @@ void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityT
|
||||||
_entityTree = entityTree;
|
_entityTree = entityTree;
|
||||||
_trackedEntities.clear();
|
_trackedEntities.clear();
|
||||||
_trackingEntities = true;
|
_trackingEntities = true;
|
||||||
|
_maxTrackedEntityCount = 0;
|
||||||
connect(std::const_pointer_cast<EntityTree>(_entityTree).get(),
|
connect(std::const_pointer_cast<EntityTree>(_entityTree).get(),
|
||||||
&EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity);
|
&EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity);
|
||||||
connect(std::const_pointer_cast<EntityTree>(_entityTree).get(),
|
connect(std::const_pointer_cast<EntityTree>(_entityTree).get(),
|
||||||
|
@ -47,6 +51,7 @@ void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityT
|
||||||
_sequenceNumbers.clear();
|
_sequenceNumbers.clear();
|
||||||
_initialStart = INVALID_SEQUENCE;
|
_initialStart = INVALID_SEQUENCE;
|
||||||
_initialEnd = INVALID_SEQUENCE;
|
_initialEnd = INVALID_SEQUENCE;
|
||||||
|
_startTime = usecTimestampNow();
|
||||||
EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority);
|
EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +60,7 @@ void SafeLanding::stopEntitySequence() {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
_trackingEntities = false;
|
_trackingEntities = false;
|
||||||
_maxTrackedEntityCount = 0;
|
_maxTrackedEntityCount = 0;
|
||||||
|
_trackedEntityStabilityCount = 0;
|
||||||
_initialStart = INVALID_SEQUENCE;
|
_initialStart = INVALID_SEQUENCE;
|
||||||
_initialEnd = INVALID_SEQUENCE;
|
_initialEnd = INVALID_SEQUENCE;
|
||||||
_trackedEntities.clear();
|
_trackedEntities.clear();
|
||||||
|
@ -66,18 +72,17 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
EntityItemPointer entity = _entityTree->findEntityByID(entityID);
|
EntityItemPointer entity = _entityTree->findEntityByID(entityID);
|
||||||
|
|
||||||
if (entity) {
|
if (entity && entity->getCreated() < _startTime) {
|
||||||
|
|
||||||
_trackedEntities.emplace(entityID, entity);
|
_trackedEntities.emplace(entityID, entity);
|
||||||
int trackedEntityCount = (int)_trackedEntities.size();
|
int trackedEntityCount = (int)_trackedEntities.size();
|
||||||
|
|
||||||
if (trackedEntityCount > _maxTrackedEntityCount) {
|
if (trackedEntityCount > _maxTrackedEntityCount) {
|
||||||
_maxTrackedEntityCount = trackedEntityCount;
|
_maxTrackedEntityCount = trackedEntityCount;
|
||||||
|
_trackedEntityStabilityCount = 0;
|
||||||
}
|
}
|
||||||
qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
|
qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
qCDebug(interfaceapp) << "Safe Landing: Null Entity: " << entityID;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,10 +109,10 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) {
|
||||||
bool SafeLanding::isLoadSequenceComplete() {
|
bool SafeLanding::isLoadSequenceComplete() {
|
||||||
if (isEntityLoadingComplete() && isSequenceNumbersComplete()) {
|
if (isEntityLoadingComplete() && isSequenceNumbersComplete()) {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
_trackedEntities.clear();
|
|
||||||
_initialStart = INVALID_SEQUENCE;
|
_initialStart = INVALID_SEQUENCE;
|
||||||
_initialEnd = INVALID_SEQUENCE;
|
_initialEnd = INVALID_SEQUENCE;
|
||||||
_entityTree = nullptr;
|
_entityTree = nullptr;
|
||||||
|
_trackingEntities = false; // Don't track anything else that comes in.
|
||||||
EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority);
|
EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,11 +121,18 @@ bool SafeLanding::isLoadSequenceComplete() {
|
||||||
|
|
||||||
float SafeLanding::loadingProgressPercentage() {
|
float SafeLanding::loadingProgressPercentage() {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
|
static const int MINIMUM_TRACKED_ENTITY_STABILITY_COUNT = 15;
|
||||||
|
|
||||||
|
float entityReadyPercentage = 0.0f;
|
||||||
if (_maxTrackedEntityCount > 0) {
|
if (_maxTrackedEntityCount > 0) {
|
||||||
return ((_maxTrackedEntityCount - _trackedEntities.size()) / (float)_maxTrackedEntityCount);
|
entityReadyPercentage = ((_maxTrackedEntityCount - _trackedEntities.size()) / (float)_maxTrackedEntityCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0f;
|
if (_trackedEntityStabilityCount < MINIMUM_TRACKED_ENTITY_STABILITY_COUNT) {
|
||||||
|
entityReadyPercentage *= 0.20f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entityReadyPercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafeLanding::isSequenceNumbersComplete() {
|
bool SafeLanding::isSequenceNumbersComplete() {
|
||||||
|
@ -130,11 +142,16 @@ bool SafeLanding::isSequenceNumbersComplete() {
|
||||||
_initialEnd + SEQUENCE_MODULO - _initialStart;
|
_initialEnd + SEQUENCE_MODULO - _initialStart;
|
||||||
auto startIter = _sequenceNumbers.find(_initialStart);
|
auto startIter = _sequenceNumbers.find(_initialStart);
|
||||||
auto endIter = _sequenceNumbers.find(_initialEnd - 1);
|
auto endIter = _sequenceNumbers.find(_initialEnd - 1);
|
||||||
|
|
||||||
|
bool missingSequenceNumbers = qApp->isMissingSequenceNumbers();
|
||||||
if (sequenceSize == 0 ||
|
if (sequenceSize == 0 ||
|
||||||
(startIter != _sequenceNumbers.end()
|
(startIter != _sequenceNumbers.end()
|
||||||
&& endIter != _sequenceNumbers.end()
|
&& endIter != _sequenceNumbers.end()
|
||||||
&& distance(startIter, endIter) == sequenceSize - 1) ) {
|
&& ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) {
|
||||||
_trackingEntities = false; // Don't track anything else that comes in.
|
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
|
||||||
|
if (!enableInterstitial) {
|
||||||
|
_trackingEntities = false; // Don't track anything else that comes in.
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,13 +162,13 @@ bool isEntityPhysicsReady(const EntityItemPointer& entity) {
|
||||||
if (entity && !entity->getCollisionless()) {
|
if (entity && !entity->getCollisionless()) {
|
||||||
const auto& entityType = entity->getType();
|
const auto& entityType = entity->getType();
|
||||||
if (entityType == EntityTypes::Model) {
|
if (entityType == EntityTypes::Model) {
|
||||||
ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get();
|
RenderableModelEntityItem * modelEntity = std::dynamic_pointer_cast<RenderableModelEntityItem>(entity).get();
|
||||||
static const std::set<ShapeType> downloadedCollisionTypes
|
static const std::set<ShapeType> downloadedCollisionTypes
|
||||||
{ SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL };
|
{ SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL };
|
||||||
bool hasAABox;
|
bool hasAABox;
|
||||||
entity->getAABox(hasAABox);
|
entity->getAABox(hasAABox);
|
||||||
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
||||||
return (!entity->shouldBePhysical() || entity->isReadyToComputeShape());
|
return (!entity->shouldBePhysical() || entity->isReadyToComputeShape() || modelEntity->computeShapeFailedToLoad());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,16 +183,20 @@ bool SafeLanding::isEntityLoadingComplete() {
|
||||||
auto entityTree = qApp->getEntities();
|
auto entityTree = qApp->getEntities();
|
||||||
auto entityMapIter = _trackedEntities.begin();
|
auto entityMapIter = _trackedEntities.begin();
|
||||||
|
|
||||||
|
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
|
||||||
|
|
||||||
while (entityMapIter != _trackedEntities.end()) {
|
while (entityMapIter != _trackedEntities.end()) {
|
||||||
auto entity = entityMapIter->second;
|
auto entity = entityMapIter->second;
|
||||||
|
|
||||||
bool isVisuallyReady = true;
|
bool isVisuallyReady = true;
|
||||||
|
|
||||||
Settings settings;
|
|
||||||
bool enableInterstitial = settings.value("enableIntersitialMode", false).toBool();
|
|
||||||
|
|
||||||
if (enableInterstitial) {
|
if (enableInterstitial) {
|
||||||
isVisuallyReady = (entity->isVisuallyReady() || !entityTree->renderableForEntityId(entityMapIter->first));
|
auto entityRenderable = entityTree->renderableForEntityId(entityMapIter->first);
|
||||||
|
if (!entityRenderable) {
|
||||||
|
entityTree->addingEntity(entityMapIter->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
|
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
|
||||||
|
@ -188,6 +209,12 @@ bool SafeLanding::isEntityLoadingComplete() {
|
||||||
entityMapIter++;
|
entityMapIter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enableInterstitial) {
|
||||||
|
_trackedEntityStabilityCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return _trackedEntities.empty();
|
return _trackedEntities.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,9 @@ private:
|
||||||
int _initialStart { INVALID_SEQUENCE };
|
int _initialStart { INVALID_SEQUENCE };
|
||||||
int _initialEnd { INVALID_SEQUENCE };
|
int _initialEnd { INVALID_SEQUENCE };
|
||||||
int _maxTrackedEntityCount { 0 };
|
int _maxTrackedEntityCount { 0 };
|
||||||
|
int _trackedEntityStabilityCount { 0 };
|
||||||
|
|
||||||
|
quint64 _startTime { 0 };
|
||||||
|
|
||||||
struct SequenceLessThan {
|
struct SequenceLessThan {
|
||||||
bool operator()(const int& a, const int& b) const;
|
bool operator()(const int& a, const int& b) const;
|
||||||
|
|
|
@ -39,6 +39,7 @@ WindowScriptingInterface::WindowScriptingInterface() {
|
||||||
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &WindowScriptingInterface::disconnectedFromDomain);
|
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &WindowScriptingInterface::disconnectedFromDomain);
|
||||||
|
|
||||||
connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused);
|
connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused);
|
||||||
|
connect(&domainHandler, &DomainHandler::redirectErrorStateChanged, this, &WindowScriptingInterface::redirectErrorStateChanged);
|
||||||
|
|
||||||
connect(qApp, &Application::svoImportRequested, [this](const QString& urlString) {
|
connect(qApp, &Application::svoImportRequested, [this](const QString& urlString) {
|
||||||
static const QMetaMethod svoImportRequestedSignal =
|
static const QMetaMethod svoImportRequestedSignal =
|
||||||
|
|
|
@ -611,6 +611,14 @@ signals:
|
||||||
*/
|
*/
|
||||||
void domainConnectionRefused(const QString& reasonMessage, int reasonCode, const QString& extraInfo);
|
void domainConnectionRefused(const QString& reasonMessage, int reasonCode, const QString& extraInfo);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when you try to visit a domain but are redirected into the error state.
|
||||||
|
* @function Window.redirectErrorStateChanged
|
||||||
|
* @param {boolean} isInErrorState - If <code>true</code>, the user has been redirected to the error URL.
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void redirectErrorStateChanged(bool isInErrorState);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with
|
* Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with
|
||||||
* <code>includeAnimated = false</code> or {@link Window.takeSecondaryCameraSnapshot|takeSecondaryCameraSnapshot}.
|
* <code>includeAnimated = false</code> or {@link Window.takeSecondaryCameraSnapshot|takeSecondaryCameraSnapshot}.
|
||||||
|
|
|
@ -206,11 +206,13 @@ float AvatarData::getDistanceBasedMinRotationDOT(glm::vec3 viewerPosition) const
|
||||||
if (distance < AVATAR_DISTANCE_LEVEL_1) {
|
if (distance < AVATAR_DISTANCE_LEVEL_1) {
|
||||||
result = AVATAR_MIN_ROTATION_DOT;
|
result = AVATAR_MIN_ROTATION_DOT;
|
||||||
} else if (distance < AVATAR_DISTANCE_LEVEL_2) {
|
} else if (distance < AVATAR_DISTANCE_LEVEL_2) {
|
||||||
result = ROTATION_CHANGE_15D;
|
result = ROTATION_CHANGE_2D;
|
||||||
} else if (distance < AVATAR_DISTANCE_LEVEL_3) {
|
} else if (distance < AVATAR_DISTANCE_LEVEL_3) {
|
||||||
result = ROTATION_CHANGE_45D;
|
result = ROTATION_CHANGE_4D;
|
||||||
} else if (distance < AVATAR_DISTANCE_LEVEL_4) {
|
} else if (distance < AVATAR_DISTANCE_LEVEL_4) {
|
||||||
result = ROTATION_CHANGE_90D;
|
result = ROTATION_CHANGE_6D;
|
||||||
|
} else if (distance < AVATAR_DISTANCE_LEVEL_5) {
|
||||||
|
result = ROTATION_CHANGE_15D;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1802,15 +1804,24 @@ QUrl AvatarData::getWireSafeSkeletonModelURL() const {
|
||||||
|
|
||||||
qint64 AvatarData::packTrait(AvatarTraits::TraitType traitType, ExtendedIODevice& destination,
|
qint64 AvatarData::packTrait(AvatarTraits::TraitType traitType, ExtendedIODevice& destination,
|
||||||
AvatarTraits::TraitVersion traitVersion) {
|
AvatarTraits::TraitVersion traitVersion) {
|
||||||
qint64 bytesWritten = 0;
|
|
||||||
bytesWritten += destination.writePrimitive(traitType);
|
|
||||||
|
|
||||||
if (traitVersion > AvatarTraits::DEFAULT_TRAIT_VERSION) {
|
qint64 bytesWritten = 0;
|
||||||
bytesWritten += destination.writePrimitive(traitVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (traitType == AvatarTraits::SkeletonModelURL) {
|
if (traitType == AvatarTraits::SkeletonModelURL) {
|
||||||
|
|
||||||
QByteArray encodedSkeletonURL = getWireSafeSkeletonModelURL().toEncoded();
|
QByteArray encodedSkeletonURL = getWireSafeSkeletonModelURL().toEncoded();
|
||||||
|
|
||||||
|
if (encodedSkeletonURL.size() > AvatarTraits::MAXIMUM_TRAIT_SIZE) {
|
||||||
|
qWarning() << "Refusing to pack simple trait" << traitType << "of size" << encodedSkeletonURL.size()
|
||||||
|
<< "bytes since it exceeds the maximum size" << AvatarTraits::MAXIMUM_TRAIT_SIZE << "bytes";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytesWritten += destination.writePrimitive(traitType);
|
||||||
|
|
||||||
|
if (traitVersion > AvatarTraits::DEFAULT_TRAIT_VERSION) {
|
||||||
|
bytesWritten += destination.writePrimitive(traitVersion);
|
||||||
|
}
|
||||||
|
|
||||||
AvatarTraits::TraitWireSize encodedURLSize = encodedSkeletonURL.size();
|
AvatarTraits::TraitWireSize encodedURLSize = encodedSkeletonURL.size();
|
||||||
bytesWritten += destination.writePrimitive(encodedURLSize);
|
bytesWritten += destination.writePrimitive(encodedURLSize);
|
||||||
|
@ -1825,14 +1836,6 @@ qint64 AvatarData::packTraitInstance(AvatarTraits::TraitType traitType, AvatarTr
|
||||||
ExtendedIODevice& destination, AvatarTraits::TraitVersion traitVersion) {
|
ExtendedIODevice& destination, AvatarTraits::TraitVersion traitVersion) {
|
||||||
qint64 bytesWritten = 0;
|
qint64 bytesWritten = 0;
|
||||||
|
|
||||||
bytesWritten += destination.writePrimitive(traitType);
|
|
||||||
|
|
||||||
if (traitVersion > AvatarTraits::DEFAULT_TRAIT_VERSION) {
|
|
||||||
bytesWritten += destination.writePrimitive(traitVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
bytesWritten += destination.write(traitInstanceID.toRfc4122());
|
|
||||||
|
|
||||||
if (traitType == AvatarTraits::AvatarEntity) {
|
if (traitType == AvatarTraits::AvatarEntity) {
|
||||||
// grab a read lock on the avatar entities and check for entity data for the given ID
|
// grab a read lock on the avatar entities and check for entity data for the given ID
|
||||||
QByteArray entityBinaryData;
|
QByteArray entityBinaryData;
|
||||||
|
@ -1843,6 +1846,20 @@ qint64 AvatarData::packTraitInstance(AvatarTraits::TraitType traitType, AvatarTr
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (entityBinaryData.size() > AvatarTraits::MAXIMUM_TRAIT_SIZE) {
|
||||||
|
qWarning() << "Refusing to pack instanced trait" << traitType << "of size" << entityBinaryData.size()
|
||||||
|
<< "bytes since it exceeds the maximum size " << AvatarTraits::MAXIMUM_TRAIT_SIZE << "bytes";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytesWritten += destination.writePrimitive(traitType);
|
||||||
|
|
||||||
|
if (traitVersion > AvatarTraits::DEFAULT_TRAIT_VERSION) {
|
||||||
|
bytesWritten += destination.writePrimitive(traitVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytesWritten += destination.write(traitInstanceID.toRfc4122());
|
||||||
|
|
||||||
if (!entityBinaryData.isNull()) {
|
if (!entityBinaryData.isNull()) {
|
||||||
AvatarTraits::TraitWireSize entityBinarySize = entityBinaryData.size();
|
AvatarTraits::TraitWireSize entityBinarySize = entityBinaryData.size();
|
||||||
|
|
||||||
|
|
|
@ -309,16 +309,19 @@ const float AVATAR_SEND_FULL_UPDATE_RATIO = 0.02f;
|
||||||
const float AVATAR_MIN_ROTATION_DOT = 0.9999999f;
|
const float AVATAR_MIN_ROTATION_DOT = 0.9999999f;
|
||||||
const float AVATAR_MIN_TRANSLATION = 0.0001f;
|
const float AVATAR_MIN_TRANSLATION = 0.0001f;
|
||||||
|
|
||||||
const float ROTATION_CHANGE_15D = 0.9914449f;
|
// quaternion dot products
|
||||||
const float ROTATION_CHANGE_45D = 0.9238795f;
|
const float ROTATION_CHANGE_2D = 0.99984770f; // 2 degrees
|
||||||
const float ROTATION_CHANGE_90D = 0.7071068f;
|
const float ROTATION_CHANGE_4D = 0.99939083f; // 4 degrees
|
||||||
const float ROTATION_CHANGE_179D = 0.0087266f;
|
const float ROTATION_CHANGE_6D = 0.99862953f; // 6 degrees
|
||||||
|
const float ROTATION_CHANGE_15D = 0.99144486f; // 15 degrees
|
||||||
const float AVATAR_DISTANCE_LEVEL_1 = 10.0f;
|
const float ROTATION_CHANGE_179D = 0.00872653f; // 179 degrees
|
||||||
const float AVATAR_DISTANCE_LEVEL_2 = 100.0f;
|
|
||||||
const float AVATAR_DISTANCE_LEVEL_3 = 1000.0f;
|
|
||||||
const float AVATAR_DISTANCE_LEVEL_4 = 10000.0f;
|
|
||||||
|
|
||||||
|
// rotation culling distance thresholds
|
||||||
|
const float AVATAR_DISTANCE_LEVEL_1 = 12.5f; // meters
|
||||||
|
const float AVATAR_DISTANCE_LEVEL_2 = 16.6f; // meters
|
||||||
|
const float AVATAR_DISTANCE_LEVEL_3 = 25.0f; // meters
|
||||||
|
const float AVATAR_DISTANCE_LEVEL_4 = 50.0f; // meters
|
||||||
|
const float AVATAR_DISTANCE_LEVEL_5 = 200.0f; // meters
|
||||||
|
|
||||||
// Where one's own Avatar begins in the world (will be overwritten if avatar data file is found).
|
// Where one's own Avatar begins in the world (will be overwritten if avatar data file is found).
|
||||||
// This is the start location in the Sandbox (xyz: 6270, 211, 6000).
|
// This is the start location in the Sandbox (xyz: 6270, 211, 6000).
|
||||||
|
|
|
@ -339,7 +339,7 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer<ReceivedMessage> mess
|
||||||
// grab the last trait versions for this avatar
|
// grab the last trait versions for this avatar
|
||||||
auto& lastProcessedVersions = _processedTraitVersions[avatarID];
|
auto& lastProcessedVersions = _processedTraitVersions[avatarID];
|
||||||
|
|
||||||
while (traitType != AvatarTraits::NullTrait) {
|
while (traitType != AvatarTraits::NullTrait && message->getBytesLeftToRead() > 0) {
|
||||||
AvatarTraits::TraitVersion packetTraitVersion;
|
AvatarTraits::TraitVersion packetTraitVersion;
|
||||||
message->readPrimitive(&packetTraitVersion);
|
message->readPrimitive(&packetTraitVersion);
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer<ReceivedMessage> mess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skipBinaryTrait) {
|
if (skipBinaryTrait && traitBinarySize > 0) {
|
||||||
// we didn't read this trait because it was older or because we didn't have an avatar to process it for
|
// we didn't read this trait because it was older or because we didn't have an avatar to process it for
|
||||||
message->seek(message->getPosition() + traitBinarySize);
|
message->seek(message->getPosition() + traitBinarySize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace AvatarTraits {
|
||||||
|
|
||||||
using TraitWireSize = int16_t;
|
using TraitWireSize = int16_t;
|
||||||
const TraitWireSize DELETED_TRAIT_SIZE = -1;
|
const TraitWireSize DELETED_TRAIT_SIZE = -1;
|
||||||
|
const TraitWireSize MAXIMUM_TRAIT_SIZE = INT16_MAX;
|
||||||
|
|
||||||
inline qint64 packInstancedTraitDelete(TraitType traitType, TraitInstanceID instanceID, ExtendedIODevice& destination,
|
inline qint64 packInstancedTraitDelete(TraitType traitType, TraitInstanceID instanceID, ExtendedIODevice& destination,
|
||||||
TraitVersion traitVersion = NULL_TRAIT_VERSION) {
|
TraitVersion traitVersion = NULL_TRAIT_VERSION) {
|
||||||
|
|
|
@ -310,10 +310,10 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
|
||||||
}
|
}
|
||||||
|
|
||||||
auto entityID = entity->getEntityItemID();
|
auto entityID = entity->getEntityItemID();
|
||||||
processedIds.insert(entityID);
|
|
||||||
auto renderable = EntityRenderer::addToScene(*this, entity, scene, transaction);
|
auto renderable = EntityRenderer::addToScene(*this, entity, scene, transaction);
|
||||||
if (renderable) {
|
if (renderable) {
|
||||||
_entitiesInScene.insert({ entityID, renderable });
|
_entitiesInScene.insert({ entityID, renderable });
|
||||||
|
processedIds.insert(entityID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,14 @@ void RenderableModelEntityItem::getCollisionGeometryResource() {
|
||||||
_compoundShapeResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(hullURL);
|
_compoundShapeResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(hullURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RenderableModelEntityItem::computeShapeFailedToLoad() {
|
||||||
|
if (!_compoundShapeResource) {
|
||||||
|
getCollisionGeometryResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (_compoundShapeResource && _compoundShapeResource->isFailed());
|
||||||
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::setShapeType(ShapeType type) {
|
void RenderableModelEntityItem::setShapeType(ShapeType type) {
|
||||||
ModelEntityItem::setShapeType(type);
|
ModelEntityItem::setShapeType(type);
|
||||||
if (getShapeType() == SHAPE_TYPE_COMPOUND) {
|
if (getShapeType() == SHAPE_TYPE_COMPOUND) {
|
||||||
|
@ -343,7 +351,6 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) {
|
||||||
|
|
||||||
bool RenderableModelEntityItem::isReadyToComputeShape() const {
|
bool RenderableModelEntityItem::isReadyToComputeShape() const {
|
||||||
ShapeType type = getShapeType();
|
ShapeType type = getShapeType();
|
||||||
|
|
||||||
auto model = getModel();
|
auto model = getModel();
|
||||||
if (type == SHAPE_TYPE_COMPOUND) {
|
if (type == SHAPE_TYPE_COMPOUND) {
|
||||||
if (!model || getCompoundShapeURL().isEmpty()) {
|
if (!model || getCompoundShapeURL().isEmpty()) {
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
|
|
||||||
virtual bool isReadyToComputeShape() const override;
|
virtual bool isReadyToComputeShape() const override;
|
||||||
virtual void computeShapeInfo(ShapeInfo& shapeInfo) override;
|
virtual void computeShapeInfo(ShapeInfo& shapeInfo) override;
|
||||||
|
bool computeShapeFailedToLoad();
|
||||||
|
|
||||||
virtual bool contains(const glm::vec3& point) const override;
|
virtual bool contains(const glm::vec3& point) const override;
|
||||||
void stopModelOverrideIfNoParent();
|
void stopModelOverrideIfNoParent();
|
||||||
|
|
|
@ -104,6 +104,10 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
|
||||||
_networkTexture.reset();
|
_networkTexture.reset();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withWriteLock([&] {
|
||||||
|
entity->setVisuallyReady(true);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
bool textureNeedsUpdate = resultWithReadLock<bool>([&]{
|
bool textureNeedsUpdate = resultWithReadLock<bool>([&]{
|
||||||
return !_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures);
|
return !_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures);
|
||||||
|
@ -113,6 +117,12 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
|
||||||
_networkTexture = DependencyManager::get<TextureCache>()->getTexture(_particleProperties.textures);
|
_networkTexture = DependencyManager::get<TextureCache>()->getTexture(_particleProperties.textures);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_networkTexture) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
entity->setVisuallyReady(_networkTexture->isFailed() || _networkTexture->isLoaded());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* key = (void*)this;
|
void* key = (void*)this;
|
||||||
|
|
|
@ -104,7 +104,7 @@ protected:
|
||||||
QMutex _dynamicsMutex { QMutex::Recursive };
|
QMutex _dynamicsMutex { QMutex::Recursive };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SetOfEntities _deadEntities;
|
SetOfEntities _deadEntities; // dead entities that might still be in the _entityTree
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void moveSimpleKinematics();
|
void moveSimpleKinematics();
|
||||||
|
|
|
@ -166,6 +166,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte
|
||||||
{
|
{
|
||||||
_type = EntityTypes::ParticleEffect;
|
_type = EntityTypes::ParticleEffect;
|
||||||
setColor(DEFAULT_COLOR);
|
setColor(DEFAULT_COLOR);
|
||||||
|
_visuallyReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleEffectEntityItem::setAlpha(float alpha) {
|
void ParticleEffectEntityItem::setAlpha(float alpha) {
|
||||||
|
@ -777,4 +778,4 @@ particle::Properties ParticleEffectEntityItem::getParticleProperties() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,6 +551,11 @@ QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const FBXTexture& textu
|
||||||
|
|
||||||
graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture,
|
graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture,
|
||||||
image::TextureUsage::Type type, MapChannel channel) {
|
image::TextureUsage::Type type, MapChannel channel) {
|
||||||
|
|
||||||
|
if (baseUrl.isEmpty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const auto url = getTextureUrl(baseUrl, fbxTexture);
|
const auto url = getTextureUrl(baseUrl, fbxTexture);
|
||||||
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, fbxTexture.content, fbxTexture.maxNumPixels);
|
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, fbxTexture.content, fbxTexture.maxNumPixels);
|
||||||
_textures[channel] = Texture { fbxTexture.name, texture };
|
_textures[channel] = Texture { fbxTexture.name, texture };
|
||||||
|
|
|
@ -161,8 +161,14 @@ void AddressManager::storeCurrentAddress() {
|
||||||
// be loaded over http(s)
|
// be loaded over http(s)
|
||||||
// url.scheme() == URL_SCHEME_HTTP ||
|
// url.scheme() == URL_SCHEME_HTTP ||
|
||||||
// url.scheme() == URL_SCHEME_HTTPS ||
|
// url.scheme() == URL_SCHEME_HTTPS ||
|
||||||
|
bool isInErrorState = DependencyManager::get<NodeList>()->getDomainHandler().isInErrorState();
|
||||||
if (isConnected()) {
|
if (isConnected()) {
|
||||||
currentAddressHandle.set(url);
|
if (isInErrorState) {
|
||||||
|
// save the last address visited before the problem url.
|
||||||
|
currentAddressHandle.set(lastAddress());
|
||||||
|
} else {
|
||||||
|
currentAddressHandle.set(url);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(networking) << "Ignoring attempt to save current address because not connected to domain:" << url;
|
qCWarning(networking) << "Ignoring attempt to save current address because not connected to domain:" << url;
|
||||||
}
|
}
|
||||||
|
@ -861,6 +867,10 @@ void AddressManager::goToUser(const QString& username, bool shouldMatchOrientati
|
||||||
QByteArray(), nullptr, requestParams);
|
QByteArray(), nullptr, requestParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AddressManager::canGoBack() const {
|
||||||
|
return (_backStack.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
void AddressManager::refreshPreviousLookup() {
|
void AddressManager::refreshPreviousLookup() {
|
||||||
// if we have a non-empty previous lookup, fire it again now (but don't re-store it in the history)
|
// if we have a non-empty previous lookup, fire it again now (but don't re-store it in the history)
|
||||||
if (!_previousAPILookup.isEmpty()) {
|
if (!_previousAPILookup.isEmpty()) {
|
||||||
|
|
|
@ -254,6 +254,12 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void goToLastAddress() { handleUrl(_lastVisitedURL, LookupTrigger::AttemptedRefresh); }
|
void goToLastAddress() { handleUrl(_lastVisitedURL, LookupTrigger::AttemptedRefresh); }
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Returns if going back is possible.
|
||||||
|
* @function location.canGoBack
|
||||||
|
*/
|
||||||
|
bool canGoBack() const;
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Refresh the current address, e.g., after connecting to a domain in order to position the user to the desired location.
|
* Refresh the current address, e.g., after connecting to a domain in order to position the user to the desired location.
|
||||||
* @function location.refreshPreviousLookup
|
* @function location.refreshPreviousLookup
|
||||||
|
|
|
@ -123,6 +123,7 @@ void DomainHandler::hardReset() {
|
||||||
|
|
||||||
softReset();
|
softReset();
|
||||||
_isInErrorState = false;
|
_isInErrorState = false;
|
||||||
|
emit redirectErrorStateChanged(_isInErrorState);
|
||||||
|
|
||||||
qCDebug(networking) << "Hard reset in NodeList DomainHandler.";
|
qCDebug(networking) << "Hard reset in NodeList DomainHandler.";
|
||||||
_pendingDomainID = QUuid();
|
_pendingDomainID = QUuid();
|
||||||
|
@ -138,6 +139,11 @@ void DomainHandler::hardReset() {
|
||||||
_pendingPath.clear();
|
_pendingPath.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DomainHandler::isHardRefusal(int reasonCode) {
|
||||||
|
return (reasonCode == (int)ConnectionRefusedReason::ProtocolMismatch || reasonCode == (int)ConnectionRefusedReason::NotAuthorized ||
|
||||||
|
reasonCode == (int)ConnectionRefusedReason::TimedOut);
|
||||||
|
}
|
||||||
|
|
||||||
bool DomainHandler::getInterstitialModeEnabled() const {
|
bool DomainHandler::getInterstitialModeEnabled() const {
|
||||||
return _interstitialModeSettingLock.resultWithReadLock<bool>([&] {
|
return _interstitialModeSettingLock.resultWithReadLock<bool>([&] {
|
||||||
return _enableInterstitialMode.get();
|
return _enableInterstitialMode.get();
|
||||||
|
@ -327,6 +333,7 @@ void DomainHandler::setIsConnected(bool isConnected) {
|
||||||
_isConnected = isConnected;
|
_isConnected = isConnected;
|
||||||
|
|
||||||
if (_isConnected) {
|
if (_isConnected) {
|
||||||
|
_lastDomainConnectionError = -1;
|
||||||
emit connectedToDomain(_domainURL);
|
emit connectedToDomain(_domainURL);
|
||||||
|
|
||||||
if (_domainURL.scheme() == URL_SCHEME_HIFI && !_domainURL.host().isEmpty()) {
|
if (_domainURL.scheme() == URL_SCHEME_HIFI && !_domainURL.host().isEmpty()) {
|
||||||
|
@ -358,9 +365,11 @@ void DomainHandler::loadedErrorDomain(std::map<QString, QString> namedPaths) {
|
||||||
|
|
||||||
void DomainHandler::setRedirectErrorState(QUrl errorUrl, QString reasonMessage, int reasonCode, const QString& extraInfo) {
|
void DomainHandler::setRedirectErrorState(QUrl errorUrl, QString reasonMessage, int reasonCode, const QString& extraInfo) {
|
||||||
_lastDomainConnectionError = reasonCode;
|
_lastDomainConnectionError = reasonCode;
|
||||||
if (getInterstitialModeEnabled()) {
|
if (getInterstitialModeEnabled() && isHardRefusal(reasonCode)) {
|
||||||
_errorDomainURL = errorUrl;
|
_errorDomainURL = errorUrl;
|
||||||
_isInErrorState = true;
|
_isInErrorState = true;
|
||||||
|
qCDebug(networking) << "Error connecting to domain: " << reasonMessage;
|
||||||
|
emit redirectErrorStateChanged(_isInErrorState);
|
||||||
emit redirectToErrorDomainURL(_errorDomainURL);
|
emit redirectToErrorDomainURL(_errorDomainURL);
|
||||||
} else {
|
} else {
|
||||||
emit domainConnectionRefused(reasonMessage, reasonCode, extraInfo);
|
emit domainConnectionRefused(reasonMessage, reasonCode, extraInfo);
|
||||||
|
|
|
@ -187,8 +187,6 @@ private slots:
|
||||||
signals:
|
signals:
|
||||||
void domainURLChanged(QUrl domainURL);
|
void domainURLChanged(QUrl domainURL);
|
||||||
|
|
||||||
void domainConnectionErrorChanged(int reasonCode);
|
|
||||||
|
|
||||||
// NOTE: the emission of completedSocketDiscovery does not mean a connection to DS is established
|
// NOTE: the emission of completedSocketDiscovery does not mean a connection to DS is established
|
||||||
// It means that, either from DNS lookup or ICE, we think we have a socket we can talk to DS on
|
// It means that, either from DNS lookup or ICE, we think we have a socket we can talk to DS on
|
||||||
void completedSocketDiscovery();
|
void completedSocketDiscovery();
|
||||||
|
@ -205,6 +203,7 @@ signals:
|
||||||
|
|
||||||
void domainConnectionRefused(QString reasonMessage, int reason, const QString& extraInfo);
|
void domainConnectionRefused(QString reasonMessage, int reason, const QString& extraInfo);
|
||||||
void redirectToErrorDomainURL(QUrl errorDomainURL);
|
void redirectToErrorDomainURL(QUrl errorDomainURL);
|
||||||
|
void redirectErrorStateChanged(bool isInErrorState);
|
||||||
|
|
||||||
void limitOfSilentDomainCheckInsReached();
|
void limitOfSilentDomainCheckInsReached();
|
||||||
|
|
||||||
|
@ -213,6 +212,8 @@ private:
|
||||||
void sendDisconnectPacket();
|
void sendDisconnectPacket();
|
||||||
void hardReset();
|
void hardReset();
|
||||||
|
|
||||||
|
bool isHardRefusal(int reasonCode);
|
||||||
|
|
||||||
QUuid _uuid;
|
QUuid _uuid;
|
||||||
Node::LocalID _localID;
|
Node::LocalID _localID;
|
||||||
QUrl _domainURL;
|
QUrl _domainURL;
|
||||||
|
@ -230,7 +231,7 @@ private:
|
||||||
QString _pendingPath;
|
QString _pendingPath;
|
||||||
QTimer _settingsTimer;
|
QTimer _settingsTimer;
|
||||||
mutable ReadWriteLockable _interstitialModeSettingLock;
|
mutable ReadWriteLockable _interstitialModeSettingLock;
|
||||||
Setting::Handle<bool> _enableInterstitialMode{ "enableInterstitialMode", false };
|
Setting::Handle<bool> _enableInterstitialMode{ "enableInterstitialMode", true };
|
||||||
|
|
||||||
QSet<QString> _domainConnectionRefusals;
|
QSet<QString> _domainConnectionRefusals;
|
||||||
bool _hasCheckedForAccessToken { false };
|
bool _hasCheckedForAccessToken { false };
|
||||||
|
|
|
@ -332,7 +332,6 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
qCDebug(networking) << "Local domain-server port read from shared memory (or default) is" << domainPort;
|
qCDebug(networking) << "Local domain-server port read from shared memory (or default) is" << domainPort;
|
||||||
_domainHandler.setPort(domainPort);
|
_domainHandler.setPort(domainPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we're missing a keypair we need to verify ourselves with the domain-server
|
// check if we're missing a keypair we need to verify ourselves with the domain-server
|
||||||
|
|
|
@ -79,6 +79,9 @@ void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
||||||
_deadEntities.insert(entity);
|
_deadEntities.insert(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (entity->getClientOnly()) {
|
||||||
|
_deadAvatarEntities.insert(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicalEntitySimulation::removeOwnershipData(EntityMotionState* motionState) {
|
void PhysicalEntitySimulation::removeOwnershipData(EntityMotionState* motionState) {
|
||||||
|
@ -123,6 +126,11 @@ void PhysicalEntitySimulation::takeDeadEntities(SetOfEntities& deadEntities) {
|
||||||
_deadEntities.clear();
|
_deadEntities.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicalEntitySimulation::takeDeadAvatarEntities(SetOfEntities& deadEntities) {
|
||||||
|
_deadAvatarEntities.swap(deadEntities);
|
||||||
|
_deadAvatarEntities.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||||
// queue incoming changes: from external sources (script, EntityServer, etc) to physics engine
|
// queue incoming changes: from external sources (script, EntityServer, etc) to physics engine
|
||||||
QMutexLocker lock(&_mutex);
|
QMutexLocker lock(&_mutex);
|
||||||
|
|
|
@ -60,6 +60,7 @@ public:
|
||||||
virtual void applyDynamicChanges() override;
|
virtual void applyDynamicChanges() override;
|
||||||
|
|
||||||
virtual void takeDeadEntities(SetOfEntities& deadEntities) override;
|
virtual void takeDeadEntities(SetOfEntities& deadEntities) override;
|
||||||
|
void takeDeadAvatarEntities(SetOfEntities& deadEntities);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||||
|
@ -112,6 +113,7 @@ private:
|
||||||
|
|
||||||
VectorOfEntityMotionStates _owned;
|
VectorOfEntityMotionStates _owned;
|
||||||
VectorOfEntityMotionStates _bids;
|
VectorOfEntityMotionStates _bids;
|
||||||
|
SetOfEntities _deadAvatarEntities;
|
||||||
workload::SpacePointer _space;
|
workload::SpacePointer _space;
|
||||||
uint64_t _nextBidExpiry;
|
uint64_t _nextBidExpiry;
|
||||||
uint32_t _lastStepSendPackets { 0 };
|
uint32_t _lastStepSendPackets { 0 };
|
||||||
|
|
|
@ -9,10 +9,7 @@
|
||||||
set(TARGET_NAME hifiCodec)
|
set(TARGET_NAME hifiCodec)
|
||||||
setup_hifi_client_server_plugin()
|
setup_hifi_client_server_plugin()
|
||||||
link_hifi_libraries(audio plugins)
|
link_hifi_libraries(audio plugins)
|
||||||
add_dependency_external_projects(hifiAudioCodec)
|
target_hifiAudioCodec()
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS})
|
|
||||||
target_link_libraries(${TARGET_NAME} ${HIFIAUDIOCODEC_LIBRARIES})
|
|
||||||
|
|
||||||
if (BUILD_SERVER)
|
if (BUILD_SERVER)
|
||||||
install_beside_console()
|
install_beside_console()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
|
@ -39,8 +39,9 @@ var DEFAULT_SCRIPTS_SEPARATE = [
|
||||||
//"system/chat.js"
|
//"system/chat.js"
|
||||||
];
|
];
|
||||||
|
|
||||||
if (Settings.getValue("enableInterstitialMode", false)) {
|
if (Window.interstitialModeEnabled) {
|
||||||
DEFAULT_SCRIPTS_SEPARATE.push("system/interstitialPage.js");
|
DEFAULT_SCRIPTS_COMBINED.push("system/interstitialPage.js");
|
||||||
|
DEFAULT_SCRIPTS_COMBINED.push("system/redirectOverlays.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a menu item for debugging
|
// add a menu item for debugging
|
||||||
|
|
|
@ -75,4 +75,4 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,8 +139,8 @@ function AppUi(properties) {
|
||||||
that.isOpen = false;
|
that.isOpen = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.debug(that.buttonName + " app reports: Tablet screen changed.\nNew screen type: " + type +
|
// console.debug(that.buttonName + " app reports: Tablet screen changed.\nNew screen type: " + type +
|
||||||
"\nNew screen URL: " + url + "\nCurrent app open status: " + that.isOpen + "\n");
|
// "\nNew screen URL: " + url + "\nCurrent app open status: " + that.isOpen + "\n");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Overwrite with the given properties:
|
// Overwrite with the given properties:
|
||||||
|
|
|
@ -110,6 +110,8 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
this.reticleMinY = MARGIN;
|
this.reticleMinY = MARGIN;
|
||||||
this.reticleMaxY;
|
this.reticleMaxY;
|
||||||
|
|
||||||
|
this.ignoredEntities = [];
|
||||||
|
|
||||||
var ACTION_TTL = 15; // seconds
|
var ACTION_TTL = 15; // seconds
|
||||||
|
|
||||||
var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object
|
var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object
|
||||||
|
@ -314,6 +316,17 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
return point2d;
|
return point2d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.restoreIgnoredEntities = function() {
|
||||||
|
for (var i = 0; i < this.ignoredEntities; i++) {
|
||||||
|
var data = {
|
||||||
|
action: 'remove',
|
||||||
|
id: this.ignoredEntities[i]
|
||||||
|
};
|
||||||
|
Messages.sendMessage('Hifi-Hand-RayPick-Blacklist', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
this.ignoredEntities = [];
|
||||||
|
};
|
||||||
|
|
||||||
this.notPointingAtEntity = function(controllerData) {
|
this.notPointingAtEntity = function(controllerData) {
|
||||||
var intersection = controllerData.rayPicks[this.hand];
|
var intersection = controllerData.rayPicks[this.hand];
|
||||||
var entityProperty = Entities.getEntityProperties(intersection.objectID);
|
var entityProperty = Entities.getEntityProperties(intersection.objectID);
|
||||||
|
@ -323,6 +336,15 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
if ((intersection.type === Picks.INTERSECTED_ENTITY && entityType === "Web") ||
|
if ((intersection.type === Picks.INTERSECTED_ENTITY && entityType === "Web") ||
|
||||||
intersection.type === Picks.INTERSECTED_OVERLAY || Window.isPointOnDesktopWindow(point2d)) {
|
intersection.type === Picks.INTERSECTED_OVERLAY || Window.isPointOnDesktopWindow(point2d)) {
|
||||||
return true;
|
return true;
|
||||||
|
} else if (intersection.type === Picks.INTERSECTED_ENTITY && !Window.isPhysicsEnabled()) {
|
||||||
|
// add to ignored items.
|
||||||
|
var data = {
|
||||||
|
action: 'add',
|
||||||
|
id: intersection.objectID
|
||||||
|
};
|
||||||
|
Messages.sendMessage('Hifi-Hand-RayPick-Blacklist', JSON.stringify(data));
|
||||||
|
this.ignoredEntities.push(intersection.objectID);
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -383,6 +405,7 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
this.isReady = function (controllerData) {
|
this.isReady = function (controllerData) {
|
||||||
if (HMD.active) {
|
if (HMD.active) {
|
||||||
if (this.notPointingAtEntity(controllerData)) {
|
if (this.notPointingAtEntity(controllerData)) {
|
||||||
|
this.restoreIgnoredEntities();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,9 +417,11 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
return makeRunningValues(true, [], []);
|
return makeRunningValues(true, [], []);
|
||||||
} else {
|
} else {
|
||||||
this.destroyContextOverlay();
|
this.destroyContextOverlay();
|
||||||
|
this.restoreIgnoredEntities();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.restoreIgnoredEntities();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -407,6 +432,7 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
||||||
this.highlightedEntity);
|
this.highlightedEntity);
|
||||||
this.highlightedEntity = null;
|
this.highlightedEntity = null;
|
||||||
|
this.restoreIgnoredEntities();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
this.intersectionDistance = controllerData.rayPicks[this.hand].distance;
|
this.intersectionDistance = controllerData.rayPicks[this.hand].distance;
|
||||||
|
@ -437,6 +463,7 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
if (nearGrabReadiness[k].active && (nearGrabReadiness[k].targets[0] === this.grabbedThingID
|
if (nearGrabReadiness[k].active && (nearGrabReadiness[k].targets[0] === this.grabbedThingID
|
||||||
|| HMD.tabletID && nearGrabReadiness[k].targets[0] === HMD.tabletID)) {
|
|| HMD.tabletID && nearGrabReadiness[k].targets[0] === HMD.tabletID)) {
|
||||||
this.endFarGrabAction();
|
this.endFarGrabAction();
|
||||||
|
this.restoreIgnoredEntities();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,6 +475,7 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
for (var j = 0; j < nearGrabReadiness.length; j++) {
|
for (var j = 0; j < nearGrabReadiness.length; j++) {
|
||||||
if (nearGrabReadiness[j].active) {
|
if (nearGrabReadiness[j].active) {
|
||||||
this.endFarGrabAction();
|
this.endFarGrabAction();
|
||||||
|
this.restoreIgnoredEntities();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,6 +494,7 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
]);
|
]);
|
||||||
if (targetProps.href !== "") {
|
if (targetProps.href !== "") {
|
||||||
AddressManager.handleLookupString(targetProps.href);
|
AddressManager.handleLookupString(targetProps.href);
|
||||||
|
this.restoreIgnoredEntities();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,6 +612,7 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
||||||
this.highlightedEntity);
|
this.highlightedEntity);
|
||||||
this.highlightedEntity = null;
|
this.highlightedEntity = null;
|
||||||
|
this.restoreIgnoredEntities();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
var tablet = null;
|
var tablet = null;
|
||||||
var button = null;
|
var button = null;
|
||||||
|
|
||||||
|
var errorConnectingToDomain = false;
|
||||||
|
|
||||||
// Tips have a character limit of 69
|
// Tips have a character limit of 69
|
||||||
var userTips = [
|
var userTips = [
|
||||||
"Tip: Visit TheSpot to explore featured domains!",
|
"Tip: Visit TheSpot to explore featured domains!",
|
||||||
|
@ -48,7 +50,7 @@
|
||||||
"Tip: Use the Create app to import models and create custom entities.",
|
"Tip: Use the Create app to import models and create custom entities.",
|
||||||
"Tip: We're open source! Feel free to contribute to our code on GitHub!",
|
"Tip: We're open source! Feel free to contribute to our code on GitHub!",
|
||||||
"Tip: What emotes have you used in the Emote app?",
|
"Tip: What emotes have you used in the Emote app?",
|
||||||
"Tip: Take and share your snapshots with the everyone using the Snap app.",
|
"Tip: Take and share your snapshots with everyone using the Snap app.",
|
||||||
"Tip: Did you know you can show websites in-world by creating a web entity?",
|
"Tip: Did you know you can show websites in-world by creating a web entity?",
|
||||||
"Tip: Find out more information about domains by visiting our website!",
|
"Tip: Find out more information about domains by visiting our website!",
|
||||||
"Tip: Did you know you can get cool new apps from the Marketplace?",
|
"Tip: Did you know you can get cool new apps from the Marketplace?",
|
||||||
|
@ -125,7 +127,7 @@
|
||||||
localPosition: { x: 0.0 , y: -1.6, z: 0.0 },
|
localPosition: { x: 0.0 , y: -1.6, z: 0.0 },
|
||||||
text: toolTip,
|
text: toolTip,
|
||||||
textAlpha: 1,
|
textAlpha: 1,
|
||||||
backgroundAlpha: 1,
|
backgroundAlpha: 0.00393,
|
||||||
lineHeight: 0.13,
|
lineHeight: 0.13,
|
||||||
visible: isVisible,
|
visible: isVisible,
|
||||||
ignoreRayIntersection: true,
|
ignoreRayIntersection: true,
|
||||||
|
@ -135,17 +137,47 @@
|
||||||
parentID: anchorOverlay
|
parentID: anchorOverlay
|
||||||
});
|
});
|
||||||
|
|
||||||
var loadingToTheSpotID = Overlays.addOverlay("image3d", {
|
var loadingToTheSpotText = Overlays.addOverlay("text3d", {
|
||||||
name: "Loading-Destination-Card-Text",
|
name: "Loading-Destination-Card-Text",
|
||||||
localPosition: { x: 0.0 , y: -1.5, z: -0.3 },
|
localPosition: { x: 0.0 , y: -1.687, z: -0.3 },
|
||||||
url: Script.resourcesPath() + "images/interstitialPage/goTo_button.png",
|
text: "Go To TheSpot",
|
||||||
|
textAlpha: 1,
|
||||||
|
backgroundAlpha: 0.00393,
|
||||||
|
lineHeight: 0.10,
|
||||||
|
visible: isVisible,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
dimensions: {x: 1, y: 0.17},
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }),
|
||||||
|
parentID: anchorOverlay
|
||||||
|
});
|
||||||
|
|
||||||
|
var loadingToTheSpotID = Overlays.addOverlay("image3d", {
|
||||||
|
name: "Loading-Destination-Card-GoTo-Image",
|
||||||
|
localPosition: { x: 0.0 , y: -1.75, z: -0.3 },
|
||||||
|
url: Script.resourcesPath() + "images/interstitialPage/button.png",
|
||||||
alpha: 1,
|
alpha: 1,
|
||||||
visible: isVisible,
|
visible: isVisible,
|
||||||
emissive: true,
|
emissive: true,
|
||||||
ignoreRayIntersection: false,
|
ignoreRayIntersection: false,
|
||||||
drawInFront: true,
|
drawInFront: true,
|
||||||
grabbable: false,
|
grabbable: false,
|
||||||
localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }),
|
localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }),
|
||||||
|
parentID: anchorOverlay
|
||||||
|
});
|
||||||
|
|
||||||
|
var loadingToTheSpotHoverID = Overlays.addOverlay("image3d", {
|
||||||
|
name: "Loading-Destination-Card-GoTo-Image-Hover",
|
||||||
|
localPosition: { x: 0.0 , y: -1.75, z: -0.3 },
|
||||||
|
url: Script.resourcesPath() + "images/interstitialPage/button_hover.png",
|
||||||
|
alpha: 1,
|
||||||
|
visible: false,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: false,
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }),
|
||||||
parentID: anchorOverlay
|
parentID: anchorOverlay
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -185,10 +217,11 @@
|
||||||
var currentDomain = "no domain";
|
var currentDomain = "no domain";
|
||||||
var timer = null;
|
var timer = null;
|
||||||
var target = 0;
|
var target = 0;
|
||||||
|
var textureMemSizeStabilityCount = 0;
|
||||||
|
var textureMemSizeAtLastCheck = 0;
|
||||||
|
|
||||||
var connectionToDomainFailed = false;
|
var connectionToDomainFailed = false;
|
||||||
|
|
||||||
|
|
||||||
function getAnchorLocalYOffset() {
|
function getAnchorLocalYOffset() {
|
||||||
var loadingSpherePosition = Overlays.getProperty(loadingSphereID, "position");
|
var loadingSpherePosition = Overlays.getProperty(loadingSphereID, "position");
|
||||||
var loadingSphereOrientation = Overlays.getProperty(loadingSphereID, "rotation");
|
var loadingSphereOrientation = Overlays.getProperty(loadingSphereID, "rotation");
|
||||||
|
@ -227,6 +260,8 @@
|
||||||
updateOverlays(false);
|
updateOverlays(false);
|
||||||
startAudio();
|
startAudio();
|
||||||
target = 0;
|
target = 0;
|
||||||
|
textureMemSizeStabilityCount = 0;
|
||||||
|
textureMemSizeAtLastCheck = 0;
|
||||||
currentProgress = 0.1;
|
currentProgress = 0.1;
|
||||||
connectionToDomainFailed = false;
|
connectionToDomainFailed = false;
|
||||||
previousCameraMode = Camera.mode;
|
previousCameraMode = Camera.mode;
|
||||||
|
@ -235,6 +270,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleInterstitialPage(isInErrorState) {
|
||||||
|
errorConnectingToDomain = isInErrorState;
|
||||||
|
if (!errorConnectingToDomain) {
|
||||||
|
domainChanged(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function startAudio() {
|
function startAudio() {
|
||||||
sample = Audio.playSound(tune, {
|
sample = Audio.playSound(tune, {
|
||||||
localOnly: true,
|
localOnly: true,
|
||||||
|
@ -251,11 +293,12 @@
|
||||||
function domainChanged(domain) {
|
function domainChanged(domain) {
|
||||||
if (domain !== currentDomain) {
|
if (domain !== currentDomain) {
|
||||||
MyAvatar.restoreAnimation();
|
MyAvatar.restoreAnimation();
|
||||||
|
resetValues();
|
||||||
var name = location.placename;
|
var name = location.placename;
|
||||||
domainName = name.charAt(0).toUpperCase() + name.slice(1);
|
domainName = name.charAt(0).toUpperCase() + name.slice(1);
|
||||||
var doRequest = true;
|
var doRequest = true;
|
||||||
if (name.length === 0 && location.href === "file:///~/serverless/tutorial.json") {
|
if (name.length === 0 && location.href === "file:///~/serverless/tutorial.json") {
|
||||||
domainName = "Serveless Domain (Tutorial)";
|
domainName = "Serverless Domain (Tutorial)";
|
||||||
doRequest = false;
|
doRequest = false;
|
||||||
}
|
}
|
||||||
var domainNameLeftMargin = getLeftMargin(domainNameTextID, domainName);
|
var domainNameLeftMargin = getLeftMargin(domainNameTextID, domainName);
|
||||||
|
@ -306,8 +349,30 @@
|
||||||
|
|
||||||
var THE_PLACE = (HifiAbout.buildVersion === "dev") ? "hifi://TheSpot-dev": "hifi://TheSpot";
|
var THE_PLACE = (HifiAbout.buildVersion === "dev") ? "hifi://TheSpot-dev": "hifi://TheSpot";
|
||||||
function clickedOnOverlay(overlayID, event) {
|
function clickedOnOverlay(overlayID, event) {
|
||||||
if (loadingToTheSpotID === overlayID) {
|
if (loadingToTheSpotHoverID === overlayID) {
|
||||||
location.handleLookupString(THE_PLACE);
|
location.handleLookupString(THE_PLACE);
|
||||||
|
Overlays.editOverlay(loadingToTheSpotHoverID, {visible: false});
|
||||||
|
Overlays.editOverlay(loadingToTheSpotID, {visible: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEnterOverlay(overlayID, event) {
|
||||||
|
if (currentDomain === "no domain") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (overlayID === loadingToTheSpotID) {
|
||||||
|
Overlays.editOverlay(loadingToTheSpotID, {visible: false});
|
||||||
|
Overlays.editOverlay(loadingToTheSpotHoverID, {visible: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onLeaveOverlay(overlayID, event) {
|
||||||
|
if (currentDomain === "no domain") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (overlayID === loadingToTheSpotHoverID) {
|
||||||
|
Overlays.editOverlay(loadingToTheSpotHoverID, {visible: false});
|
||||||
|
Overlays.editOverlay(loadingToTheSpotID, {visible: true});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,6 +405,7 @@
|
||||||
renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled;
|
renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled;
|
||||||
renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled;
|
renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled;
|
||||||
Overlays.editOverlay(loadingSphereID, mainSphereProperties);
|
Overlays.editOverlay(loadingSphereID, mainSphereProperties);
|
||||||
|
Overlays.editOverlay(loadingToTheSpotText, properties);
|
||||||
Overlays.editOverlay(loadingToTheSpotID, properties);
|
Overlays.editOverlay(loadingToTheSpotID, properties);
|
||||||
Overlays.editOverlay(domainNameTextID, properties);
|
Overlays.editOverlay(domainNameTextID, properties);
|
||||||
Overlays.editOverlay(domainDescription, domainTextProperties);
|
Overlays.editOverlay(domainDescription, domainTextProperties);
|
||||||
|
@ -347,10 +413,11 @@
|
||||||
Overlays.editOverlay(loadingBarPlacard, properties);
|
Overlays.editOverlay(loadingBarPlacard, properties);
|
||||||
Overlays.editOverlay(loadingBarProgress, loadingBarProperties);
|
Overlays.editOverlay(loadingBarProgress, loadingBarProperties);
|
||||||
|
|
||||||
|
if (!DEBUG) {
|
||||||
Menu.setIsOptionChecked("Show Overlays", physicsEnabled);
|
Menu.setIsOptionChecked("Show Overlays", physicsEnabled);
|
||||||
if (!HMD.active) {
|
if (!HMD.active) {
|
||||||
toolbar.writeProperty("visible", physicsEnabled);
|
toolbar.writeProperty("visible", physicsEnabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resetValues();
|
resetValues();
|
||||||
|
@ -360,7 +427,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function scaleInterstitialPage(sensorToWorldScale) {
|
function scaleInterstitialPage(sensorToWorldScale) {
|
||||||
var yOffset = getAnchorLocalYOffset();
|
var yOffset = getAnchorLocalYOffset();
|
||||||
var localPosition = {
|
var localPosition = {
|
||||||
|
@ -372,19 +438,53 @@
|
||||||
Overlays.editOverlay(anchorOverlay, { localPosition: localPosition });
|
Overlays.editOverlay(anchorOverlay, { localPosition: localPosition });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sleep(milliseconds) {
|
||||||
|
var start = new Date().getTime();
|
||||||
|
for (var i = 0; i < 1e7; i++) {
|
||||||
|
if ((new Date().getTime() - start) > milliseconds){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
|
var renderStats = Render.getConfig("Stats");
|
||||||
var physicsEnabled = Window.isPhysicsEnabled();
|
var physicsEnabled = Window.isPhysicsEnabled();
|
||||||
var thisInterval = Date.now();
|
var thisInterval = Date.now();
|
||||||
var deltaTime = (thisInterval - lastInterval);
|
var deltaTime = (thisInterval - lastInterval);
|
||||||
lastInterval = thisInterval;
|
lastInterval = thisInterval;
|
||||||
|
|
||||||
var domainLoadingProgressPercentage = Window.domainLoadingProgress();
|
var domainLoadingProgressPercentage = Window.domainLoadingProgress();
|
||||||
|
var progress = ((TOTAL_LOADING_PROGRESS * 0.4) * domainLoadingProgressPercentage);
|
||||||
var progress = MIN_LOADING_PROGRESS * domainLoadingProgressPercentage;
|
|
||||||
if (progress >= target) {
|
if (progress >= target) {
|
||||||
target = progress;
|
target = progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentProgress >= (TOTAL_LOADING_PROGRESS * 0.4)) {
|
||||||
|
var textureResourceGPUMemSize = renderStats.textureResourceGPUMemSize;
|
||||||
|
var texturePopulatedGPUMemSize = renderStats.textureResourcePopulatedGPUMemSize;
|
||||||
|
|
||||||
|
if (textureMemSizeAtLastCheck === textureResourceGPUMemSize) {
|
||||||
|
textureMemSizeStabilityCount++;
|
||||||
|
} else {
|
||||||
|
textureMemSizeStabilityCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
textureMemSizeAtLastCheck = textureResourceGPUMemSize;
|
||||||
|
|
||||||
|
if (textureMemSizeStabilityCount >= 20) {
|
||||||
|
|
||||||
|
if (textureResourceGPUMemSize > 0) {
|
||||||
|
// print((texturePopulatedGPUMemSize / textureResourceGPUMemSize));
|
||||||
|
var gpuPercantage = (TOTAL_LOADING_PROGRESS * 0.6) * (texturePopulatedGPUMemSize / textureResourceGPUMemSize);
|
||||||
|
var totalProgress = progress + gpuPercantage;
|
||||||
|
if (totalProgress >= target) {
|
||||||
|
target = totalProgress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((physicsEnabled && (currentProgress < TOTAL_LOADING_PROGRESS))) {
|
if ((physicsEnabled && (currentProgress < TOTAL_LOADING_PROGRESS))) {
|
||||||
target = TOTAL_LOADING_PROGRESS;
|
target = TOTAL_LOADING_PROGRESS;
|
||||||
}
|
}
|
||||||
|
@ -399,30 +499,40 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Overlays.editOverlay(loadingBarProgress, properties);
|
Overlays.editOverlay(loadingBarProgress, properties);
|
||||||
if ((physicsEnabled && (currentProgress >= (TOTAL_LOADING_PROGRESS - EPSILON)))) {
|
|
||||||
|
if (errorConnectingToDomain) {
|
||||||
|
updateOverlays(errorConnectingToDomain);
|
||||||
|
// setting hover id to invisible
|
||||||
|
Overlays.editOverlay(loadingToTheSpotHoverID, {visible: false});
|
||||||
|
endAudio();
|
||||||
|
currentDomain = "no domain";
|
||||||
|
timer = null;
|
||||||
|
// The toolbar doesn't become visible in time to match the speed of
|
||||||
|
// the signal handling of redirectErrorStateChanged in both this script
|
||||||
|
// and the redirectOverlays.js script. Use a sleep function to ensure
|
||||||
|
// the toolbar becomes visible again.
|
||||||
|
sleep(300);
|
||||||
|
if (!HMD.active) {
|
||||||
|
toolbar.writeProperty("visible", true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if ((physicsEnabled && (currentProgress >= (TOTAL_LOADING_PROGRESS - EPSILON)))) {
|
||||||
updateOverlays((physicsEnabled || connectionToDomainFailed));
|
updateOverlays((physicsEnabled || connectionToDomainFailed));
|
||||||
|
// setting hover id to invisible
|
||||||
|
Overlays.editOverlay(loadingToTheSpotHoverID, {visible: false});
|
||||||
endAudio();
|
endAudio();
|
||||||
currentDomain = "no domain";
|
currentDomain = "no domain";
|
||||||
timer = null;
|
timer = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS);
|
timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS);
|
||||||
}
|
}
|
||||||
var whiteColor = {red: 255, green: 255, blue: 255};
|
var whiteColor = {red: 255, green: 255, blue: 255};
|
||||||
var greyColor = {red: 125, green: 125, blue: 125};
|
var greyColor = {red: 125, green: 125, blue: 125};
|
||||||
Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay);
|
Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay);
|
||||||
Overlays.hoverEnterOverlay.connect(function(overlayID, event) {
|
Overlays.hoverEnterOverlay.connect(onEnterOverlay);
|
||||||
if (overlayID === loadingToTheSpotID) {
|
|
||||||
Overlays.editOverlay(loadingToTheSpotID, { color: greyColor });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Overlays.hoverLeaveOverlay.connect(function(overlayID, event) {
|
Overlays.hoverLeaveOverlay.connect(onLeaveOverlay);
|
||||||
if (overlayID === loadingToTheSpotID) {
|
|
||||||
Overlays.editOverlay(loadingToTheSpotID, { color: whiteColor });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
location.hostChanged.connect(domainChanged);
|
location.hostChanged.connect(domainChanged);
|
||||||
location.lookupResultsFinished.connect(function() {
|
location.lookupResultsFinished.connect(function() {
|
||||||
|
@ -430,6 +540,7 @@
|
||||||
connectionToDomainFailed = !location.isConnected;
|
connectionToDomainFailed = !location.isConnected;
|
||||||
}, 1200);
|
}, 1200);
|
||||||
});
|
});
|
||||||
|
Window.redirectErrorStateChanged.connect(toggleInterstitialPage);
|
||||||
|
|
||||||
MyAvatar.sensorToWorldScaleChanged.connect(scaleInterstitialPage);
|
MyAvatar.sensorToWorldScaleChanged.connect(scaleInterstitialPage);
|
||||||
MyAvatar.sessionUUIDChanged.connect(function() {
|
MyAvatar.sessionUUIDChanged.connect(function() {
|
||||||
|
@ -448,9 +559,17 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set left margin of text.
|
||||||
|
var loadingTextProperties = {
|
||||||
|
leftMargin: getLeftMargin(loadingToTheSpotText, "Go To TheSpot") + 0.045
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(loadingToTheSpotText, loadingTextProperties);
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
Overlays.deleteOverlay(loadingSphereID);
|
Overlays.deleteOverlay(loadingSphereID);
|
||||||
Overlays.deleteOverlay(loadingToTheSpotID);
|
Overlays.deleteOverlay(loadingToTheSpotID);
|
||||||
|
Overlays.deleteOverlay(loadingToTheSpotHoverID);
|
||||||
Overlays.deleteOverlay(domainNameTextID);
|
Overlays.deleteOverlay(domainNameTextID);
|
||||||
Overlays.deleteOverlay(domainDescription);
|
Overlays.deleteOverlay(domainDescription);
|
||||||
Overlays.deleteOverlay(domainToolTip);
|
Overlays.deleteOverlay(domainToolTip);
|
||||||
|
|
257
scripts/system/redirectOverlays.js
Normal file
257
scripts/system/redirectOverlays.js
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var ERROR_MESSAGE_MAP = [
|
||||||
|
"Oops! Protocol version mismatch.",
|
||||||
|
"Oops! Not authorized to join domain.",
|
||||||
|
"Oops! Connection timed out.",
|
||||||
|
"Oops! Something went wrong."
|
||||||
|
];
|
||||||
|
|
||||||
|
var PROTOCOL_VERSION_MISMATCH = 1;
|
||||||
|
var NOT_AUTHORIZED = 3;
|
||||||
|
var TIMEOUT = 5;
|
||||||
|
var hardRefusalErrors = [PROTOCOL_VERSION_MISMATCH,
|
||||||
|
NOT_AUTHORIZED, TIMEOUT];
|
||||||
|
var timer = null;
|
||||||
|
var isErrorState = false;
|
||||||
|
|
||||||
|
function getOopsText() {
|
||||||
|
var error = Window.getLastDomainConnectionError();
|
||||||
|
var errorMessageMapIndex = hardRefusalErrors.indexOf(error);
|
||||||
|
if (error === -1) {
|
||||||
|
// not an error.
|
||||||
|
return "";
|
||||||
|
} else if (errorMessageMapIndex >= 0) {
|
||||||
|
return ERROR_MESSAGE_MAP[errorMessageMapIndex];
|
||||||
|
} else {
|
||||||
|
// some other text.
|
||||||
|
return ERROR_MESSAGE_MAP[4];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var oopsDimensions = {x: 4.2, y: 0.8};
|
||||||
|
|
||||||
|
var redirectOopsText = Overlays.addOverlay("text3d", {
|
||||||
|
name: "oopsText",
|
||||||
|
position: {x: 0, y: 1.6763916015625, z: 1.45927095413208},
|
||||||
|
rotation: {x: -4.57763671875e-05, y: 0.4957197904586792, z: -7.62939453125e-05, w: 0.8684672117233276},
|
||||||
|
text: getOopsText(),
|
||||||
|
textAlpha: 1,
|
||||||
|
backgroundColor: {x: 0, y: 0, z:0},
|
||||||
|
backgroundAlpha: 0,
|
||||||
|
lineHeight: 0.10,
|
||||||
|
leftMargin: 0.538373570564886,
|
||||||
|
visible: false,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
dimensions: oopsDimensions,
|
||||||
|
grabbable: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
var tryAgainImageNeutral = Overlays.addOverlay("image3d", {
|
||||||
|
name: "tryAgainImage",
|
||||||
|
localPosition: {x: -0.6, y: -0.6, z: 0.0},
|
||||||
|
url: Script.resourcesPath() + "images/interstitialPage/button.png",
|
||||||
|
alpha: 1,
|
||||||
|
visible: false,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: false,
|
||||||
|
grabbable: false,
|
||||||
|
orientation: Overlays.getProperty(redirectOopsText, "orientation"),
|
||||||
|
parentID: redirectOopsText
|
||||||
|
});
|
||||||
|
|
||||||
|
var tryAgainImageHover = Overlays.addOverlay("image3d", {
|
||||||
|
name: "tryAgainImageHover",
|
||||||
|
localPosition: {x: -0.6, y: -0.6, z: 0.0},
|
||||||
|
url: Script.resourcesPath() + "images/interstitialPage/button_hover.png",
|
||||||
|
alpha: 1,
|
||||||
|
visible: false,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: false,
|
||||||
|
grabbable: false,
|
||||||
|
orientation: Overlays.getProperty(redirectOopsText, "orientation"),
|
||||||
|
parentID: redirectOopsText
|
||||||
|
});
|
||||||
|
|
||||||
|
var tryAgainText = Overlays.addOverlay("text3d", {
|
||||||
|
name: "tryAgainText",
|
||||||
|
localPosition: {x: -0.6, y: -0.962, z: 0.0},
|
||||||
|
text: "Try Again",
|
||||||
|
textAlpha: 1,
|
||||||
|
backgroundAlpha: 0.00393,
|
||||||
|
lineHeight: 0.08,
|
||||||
|
visible: false,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
grabbable: false,
|
||||||
|
orientation: Overlays.getProperty(redirectOopsText, "orientation"),
|
||||||
|
parentID: redirectOopsText
|
||||||
|
});
|
||||||
|
|
||||||
|
var backImageNeutral = Overlays.addOverlay("image3d", {
|
||||||
|
name: "backImage",
|
||||||
|
localPosition: {x: 0.6, y: -0.6, z: 0.0},
|
||||||
|
url: Script.resourcesPath() + "images/interstitialPage/button.png",
|
||||||
|
alpha: 1,
|
||||||
|
visible: false,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: false,
|
||||||
|
grabbable: false,
|
||||||
|
orientation: Overlays.getProperty(redirectOopsText, "orientation"),
|
||||||
|
parentID: redirectOopsText
|
||||||
|
});
|
||||||
|
|
||||||
|
var backImageHover = Overlays.addOverlay("image3d", {
|
||||||
|
name: "backImageHover",
|
||||||
|
localPosition: {x: 0.6, y: -0.6, z: 0.0},
|
||||||
|
url: Script.resourcesPath() + "images/interstitialPage/button_hover.png",
|
||||||
|
alpha: 1,
|
||||||
|
visible: false,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: false,
|
||||||
|
grabbable: false,
|
||||||
|
orientation: Overlays.getProperty(redirectOopsText, "orientation"),
|
||||||
|
parentID: redirectOopsText
|
||||||
|
});
|
||||||
|
|
||||||
|
var backText = Overlays.addOverlay("text3d", {
|
||||||
|
name: "backText",
|
||||||
|
localPosition: {x: 0.6, y: -0.962, z: 0.0},
|
||||||
|
text: "Back",
|
||||||
|
textAlpha: 1,
|
||||||
|
backgroundAlpha: 0.00393,
|
||||||
|
lineHeight: 0.08,
|
||||||
|
visible: false,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
grabbable: false,
|
||||||
|
orientation: Overlays.getProperty(redirectOopsText, "orientation"),
|
||||||
|
parentID: redirectOopsText
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggleOverlays(isInErrorState) {
|
||||||
|
isErrorState = isInErrorState;
|
||||||
|
if (!isInErrorState) {
|
||||||
|
var properties = {
|
||||||
|
visible: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(redirectOopsText, properties);
|
||||||
|
Overlays.editOverlay(tryAgainImageNeutral, properties);
|
||||||
|
Overlays.editOverlay(tryAgainImageHover, properties);
|
||||||
|
Overlays.editOverlay(backImageNeutral, properties);
|
||||||
|
Overlays.editOverlay(backImageHover, properties);
|
||||||
|
Overlays.editOverlay(tryAgainText, properties);
|
||||||
|
Overlays.editOverlay(backText, properties);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var oopsText = getOopsText();
|
||||||
|
// if oopsText === "", it was a success.
|
||||||
|
var overlaysVisible = (oopsText !== "");
|
||||||
|
// for catching init or if error state were to be different.
|
||||||
|
isErrorState = overlaysVisible;
|
||||||
|
var properties = {
|
||||||
|
visible: overlaysVisible
|
||||||
|
};
|
||||||
|
|
||||||
|
var textWidth = Overlays.textSize(redirectOopsText, oopsText).width;
|
||||||
|
var textOverlayWidth = oopsDimensions.x;
|
||||||
|
|
||||||
|
var oopsTextProperties = {
|
||||||
|
visible: overlaysVisible,
|
||||||
|
text: oopsText,
|
||||||
|
textAlpha: overlaysVisible,
|
||||||
|
// either visible or invisible. 0 doesn't work in Mac.
|
||||||
|
backgroundAlpha: overlaysVisible * 0.00393,
|
||||||
|
leftMargin: (textOverlayWidth - textWidth) / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
var tryAgainTextWidth = Overlays.textSize(tryAgainText, "Try Again").width;
|
||||||
|
var tryAgainImageWidth = Overlays.getProperty(tryAgainImageNeutral, "dimensions").x;
|
||||||
|
|
||||||
|
var tryAgainTextProperties = {
|
||||||
|
visible: overlaysVisible,
|
||||||
|
leftMargin: (tryAgainImageWidth - tryAgainTextWidth) / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
var backTextWidth = Overlays.textSize(backText, "Back").width;
|
||||||
|
var backImageWidth = Overlays.getProperty(backImageNeutral, "dimensions").x;
|
||||||
|
|
||||||
|
var backTextProperties = {
|
||||||
|
visible: overlaysVisible,
|
||||||
|
leftMargin: (backImageWidth - backTextWidth) / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(redirectOopsText, oopsTextProperties);
|
||||||
|
Overlays.editOverlay(tryAgainImageNeutral, properties);
|
||||||
|
Overlays.editOverlay(backImageNeutral, properties);
|
||||||
|
Overlays.editOverlay(tryAgainImageHover, {visible: false});
|
||||||
|
Overlays.editOverlay(backImageHover, {visible: false});
|
||||||
|
Overlays.editOverlay(tryAgainText, tryAgainTextProperties);
|
||||||
|
Overlays.editOverlay(backText, backTextProperties);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickedOnOverlay(overlayID, event) {
|
||||||
|
if (event.isRightButton) {
|
||||||
|
// don't allow right-clicks.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tryAgainImageHover === overlayID) {
|
||||||
|
location.goToLastAddress();
|
||||||
|
} else if (backImageHover === overlayID && location.canGoBack()) {
|
||||||
|
location.goBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
Script.clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
Overlays.deleteOverlay(redirectOopsText);
|
||||||
|
Overlays.deleteOverlay(tryAgainImageNeutral);
|
||||||
|
Overlays.deleteOverlay(backImageNeutral);
|
||||||
|
Overlays.deleteOverlay(tryAgainImageHover);
|
||||||
|
Overlays.deleteOverlay(backImageHover);
|
||||||
|
Overlays.deleteOverlay(tryAgainText);
|
||||||
|
Overlays.deleteOverlay(backText);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleOverlays(true);
|
||||||
|
|
||||||
|
Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay);
|
||||||
|
Overlays.hoverEnterOverlay.connect(function(overlayID, event) {
|
||||||
|
if (!isErrorState) {
|
||||||
|
// don't allow hover overlay events to get caught if it's not in error state anymore.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (overlayID === backImageNeutral && location.canGoBack()) {
|
||||||
|
Overlays.editOverlay(backImageNeutral, {visible: false});
|
||||||
|
Overlays.editOverlay(backImageHover, {visible: true});
|
||||||
|
}
|
||||||
|
if (overlayID === tryAgainImageNeutral) {
|
||||||
|
Overlays.editOverlay(tryAgainImageNeutral, {visible: false});
|
||||||
|
Overlays.editOverlay(tryAgainImageHover, {visible: true});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Overlays.hoverLeaveOverlay.connect(function(overlayID, event) {
|
||||||
|
if (!isErrorState) {
|
||||||
|
// don't allow hover overlay events to get caught if it's not in error state anymore.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (overlayID === backImageHover) {
|
||||||
|
Overlays.editOverlay(backImageHover, {visible: false});
|
||||||
|
Overlays.editOverlay(backImageNeutral, {visible: true});
|
||||||
|
}
|
||||||
|
if (overlayID === tryAgainImageHover) {
|
||||||
|
Overlays.editOverlay(tryAgainImageHover, {visible: false});
|
||||||
|
Overlays.editOverlay(tryAgainImageNeutral, {visible: true});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Window.redirectErrorStateChanged.connect(toggleOverlays);
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
}());
|
|
@ -4,13 +4,17 @@ if (PRODUCTION_BUILD)
|
||||||
set(PRODUCTION_OPTION "--production")
|
set(PRODUCTION_OPTION "--production")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (CLIENT_ONLY)
|
||||||
|
set(CLIENT_ONLY_OPTION "--client_only")
|
||||||
|
endif()
|
||||||
|
|
||||||
# add a target that will package the console
|
# add a target that will package the console
|
||||||
add_custom_target(${TARGET_NAME}-npm-install
|
add_custom_target(${TARGET_NAME}-npm-install
|
||||||
COMMAND npm install
|
COMMAND npm install
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
)
|
)
|
||||||
add_custom_target(${TARGET_NAME}
|
add_custom_target(${TARGET_NAME}
|
||||||
COMMAND npm run packager -- --out ${CMAKE_CURRENT_BINARY_DIR} ${PRODUCTION_OPTION}
|
COMMAND npm run packager -- --out ${CMAKE_CURRENT_BINARY_DIR} ${PRODUCTION_OPTION} ${CLIENT_ONLY_OPTION}
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
DEPENDS ${TARGET_NAME}-npm-install
|
DEPENDS ${TARGET_NAME}-npm-install
|
||||||
)
|
)
|
||||||
|
@ -19,11 +23,21 @@ set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Server Console")
|
||||||
set_target_properties(${TARGET_NAME}-npm-install PROPERTIES FOLDER "hidden/Server Console")
|
set_target_properties(${TARGET_NAME}-npm-install PROPERTIES FOLDER "hidden/Server Console")
|
||||||
|
|
||||||
# add a dependency from the package target to the server components
|
# add a dependency from the package target to the server components
|
||||||
add_dependencies(${TARGET_NAME} assignment-client domain-server)
|
if (BUILD_CLIENT)
|
||||||
|
add_dependencies(${TARGET_NAME} interface)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (BUILD_SERVER)
|
||||||
|
add_dependencies(${TARGET_NAME} assignment-client domain-server)
|
||||||
|
endif()
|
||||||
|
|
||||||
# set the packaged console folder depending on platform, so we can copy it
|
# set the packaged console folder depending on platform, so we can copy it
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(PACKAGED_CONSOLE_FOLDER "Sandbox-darwin-x64/${CONSOLE_EXEC_NAME}")
|
if (CLIENT_ONLY)
|
||||||
|
set(PACKAGED_CONSOLE_FOLDER "Console-darwin-x64/${CONSOLE_EXEC_NAME}")
|
||||||
|
else ()
|
||||||
|
set(PACKAGED_CONSOLE_FOLDER "Sandbox-darwin-x64/${CONSOLE_EXEC_NAME}")
|
||||||
|
endif()
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
set(PACKAGED_CONSOLE_FOLDER "server-console-win32-x64")
|
set(PACKAGED_CONSOLE_FOLDER "server-console-win32-x64")
|
||||||
elseif (UNIX)
|
elseif (UNIX)
|
||||||
|
@ -33,9 +47,9 @@ endif ()
|
||||||
# install the packaged Server Console in our install directory
|
# install the packaged Server Console in our install directory
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
install(
|
install(
|
||||||
PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGED_CONSOLE_FOLDER}"
|
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGED_CONSOLE_FOLDER}"
|
||||||
|
USE_SOURCE_PERMISSIONS
|
||||||
DESTINATION ${CONSOLE_INSTALL_DIR}
|
DESTINATION ${CONSOLE_INSTALL_DIR}
|
||||||
COMPONENT ${SERVER_COMPONENT}
|
|
||||||
)
|
)
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
set(CONSOLE_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGED_CONSOLE_FOLDER}")
|
set(CONSOLE_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGED_CONSOLE_FOLDER}")
|
||||||
|
@ -43,7 +57,6 @@ elseif (WIN32)
|
||||||
install(
|
install(
|
||||||
DIRECTORY "${CONSOLE_DESTINATION}/"
|
DIRECTORY "${CONSOLE_DESTINATION}/"
|
||||||
DESTINATION ${CONSOLE_INSTALL_DIR}
|
DESTINATION ${CONSOLE_INSTALL_DIR}
|
||||||
COMPONENT ${SERVER_COMPONENT}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# sign the copied server console executable after install
|
# sign the copied server console executable after install
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "HighFidelitySandbox",
|
"name": "HighFidelityConsole",
|
||||||
"description": "High Fidelity Sandbox",
|
"description": "High Fidelity Console",
|
||||||
"author": "High Fidelity",
|
"author": "High Fidelity",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
|
|
@ -27,8 +27,8 @@ var options = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const EXEC_NAME = "server-console";
|
const EXEC_NAME = "server-console";
|
||||||
const SHORT_NAME = "Sandbox";
|
var SHORT_NAME = argv.client_only ? "Console" : "Sandbox";
|
||||||
const FULL_NAME = "High Fidelity Sandbox";
|
var FULL_NAME = argv.client_only ? "High Fidelity Console" : "High Fidelity Sandbox";
|
||||||
|
|
||||||
// setup per OS options
|
// setup per OS options
|
||||||
if (osType == "Darwin") {
|
if (osType == "Darwin") {
|
||||||
|
|
|
@ -60,7 +60,10 @@ const HOME_CONTENT_URL = "http://cdn.highfidelity.com/content-sets/home-tutorial
|
||||||
|
|
||||||
const buildInfo = GetBuildInfo();
|
const buildInfo = GetBuildInfo();
|
||||||
|
|
||||||
|
const NotificationState = {
|
||||||
|
UNNOTIFIED: 'unnotified',
|
||||||
|
NOTIFIED: 'notified'
|
||||||
|
};
|
||||||
|
|
||||||
// Update lock filepath
|
// Update lock filepath
|
||||||
const UPDATER_LOCK_FILENAME = ".updating";
|
const UPDATER_LOCK_FILENAME = ".updating";
|
||||||
|
@ -104,12 +107,21 @@ userConfig.load(configPath);
|
||||||
const ipcMain = electron.ipcMain;
|
const ipcMain = electron.ipcMain;
|
||||||
|
|
||||||
|
|
||||||
function isServerInstalled() {
|
function isInterfaceInstalled () {
|
||||||
return interfacePath && userConfig.get("serverInstalled", true);
|
if (osType == "Darwin") {
|
||||||
|
// In OSX Sierra, the app translocation process moves
|
||||||
|
// the executable to a random location before starting it
|
||||||
|
// which makes finding the interface near impossible using
|
||||||
|
// relative paths. For now, as there are no server-only
|
||||||
|
// installs, we just assume the interface is installed here
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return interfacePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInterfaceInstalled() {
|
function isServerInstalled () {
|
||||||
return dsPath && acPath && userConfig.get("interfaceInstalled", true);
|
return dsPath && acPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isShuttingDown = false;
|
var isShuttingDown = false;
|
||||||
|
@ -259,10 +271,14 @@ var debug = argv.debug;
|
||||||
|
|
||||||
var binaryType = argv.binaryType;
|
var binaryType = argv.binaryType;
|
||||||
|
|
||||||
interfacePath = pathFinder.discoveredPath("Interface", binaryType, buildInfo.releaseType);
|
interfacePath = pathFinder.discoveredPath("interface", binaryType, buildInfo.releaseType);
|
||||||
dsPath = pathFinder.discoveredPath("domain-server", binaryType, buildInfo.releaseType);
|
dsPath = pathFinder.discoveredPath("domain-server", binaryType, buildInfo.releaseType);
|
||||||
acPath = pathFinder.discoveredPath("assignment-client", binaryType, buildInfo.releaseType);
|
acPath = pathFinder.discoveredPath("assignment-client", binaryType, buildInfo.releaseType);
|
||||||
|
|
||||||
|
console.log("Domain Server Path: " + dsPath);
|
||||||
|
console.log("Assignment Client Path: " + acPath);
|
||||||
|
console.log("Interface Path: " + interfacePath);
|
||||||
|
|
||||||
function binaryMissingMessage(displayName, executableName, required) {
|
function binaryMissingMessage(displayName, executableName, required) {
|
||||||
var message = "The " + displayName + " executable was not found.\n";
|
var message = "The " + displayName + " executable was not found.\n";
|
||||||
|
|
||||||
|
@ -286,18 +302,6 @@ function binaryMissingMessage(displayName, executableName, required) {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if at this point any of the paths are null, we're missing something we wanted to find
|
|
||||||
|
|
||||||
if (!dsPath) {
|
|
||||||
dialog.showErrorBox("Domain Server Not Found", binaryMissingMessage("domain-server", "domain-server", true));
|
|
||||||
app.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!acPath) {
|
|
||||||
dialog.showErrorBox("Assignment Client Not Found", binaryMissingMessage("assignment-client", "assignment-client", true));
|
|
||||||
app.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openFileBrowser(path) {
|
function openFileBrowser(path) {
|
||||||
// Add quotes around path
|
// Add quotes around path
|
||||||
path = '"' + path + '"';
|
path = '"' + path + '"';
|
||||||
|
@ -332,12 +336,21 @@ const HifiNotifications = hfNotifications.HifiNotifications;
|
||||||
const HifiNotificationType = hfNotifications.NotificationType;
|
const HifiNotificationType = hfNotifications.NotificationType;
|
||||||
|
|
||||||
var pendingNotifications = {}
|
var pendingNotifications = {}
|
||||||
function notificationCallback(notificationType, pending = true) {
|
var notificationState = NotificationState.UNNOTIFIED;
|
||||||
|
|
||||||
|
function setNotificationState (notificationType, pending = true) {
|
||||||
pendingNotifications[notificationType] = pending;
|
pendingNotifications[notificationType] = pending;
|
||||||
|
notificationState = NotificationState.UNNOTIFIED;
|
||||||
|
for (var key in pendingNotifications) {
|
||||||
|
if (pendingNotifications[key]) {
|
||||||
|
notificationState = NotificationState.NOTIFIED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
updateTrayMenu(homeServer ? homeServer.state : ProcessGroupStates.STOPPED);
|
updateTrayMenu(homeServer ? homeServer.state : ProcessGroupStates.STOPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
var trayNotifications = new HifiNotifications(userConfig, notificationCallback);
|
var trayNotifications = new HifiNotifications(userConfig, setNotificationState);
|
||||||
|
|
||||||
var LogWindow = function(ac, ds) {
|
var LogWindow = function(ac, ds) {
|
||||||
this.ac = ac;
|
this.ac = ac;
|
||||||
|
@ -373,7 +386,7 @@ LogWindow.prototype = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function visitSandboxClicked() {
|
function visitSandboxClicked() {
|
||||||
if (interfacePath) {
|
if (isInterfaceInstalled()) {
|
||||||
StartInterface('hifi://localhost');
|
StartInterface('hifi://localhost');
|
||||||
} else {
|
} else {
|
||||||
// show an error to say that we can't go home without an interface instance
|
// show an error to say that we can't go home without an interface instance
|
||||||
|
@ -397,7 +410,7 @@ var labels = {
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: true,
|
checked: true,
|
||||||
click: function () {
|
click: function () {
|
||||||
trayNotifications.enable(!trayNotifications.enabled(), notificationCallback);
|
trayNotifications.enable(!trayNotifications.enabled(), setNotificationState);
|
||||||
userConfig.save(configPath);
|
userConfig.save(configPath);
|
||||||
updateTrayMenu(homeServer ? homeServer.state : ProcessGroupStates.STOPPED);
|
updateTrayMenu(homeServer ? homeServer.state : ProcessGroupStates.STOPPED);
|
||||||
}
|
}
|
||||||
|
@ -406,32 +419,28 @@ var labels = {
|
||||||
label: 'GoTo',
|
label: 'GoTo',
|
||||||
click: function () {
|
click: function () {
|
||||||
StartInterface("hifiapp:GOTO");
|
StartInterface("hifiapp:GOTO");
|
||||||
pendingNotifications[HifiNotificationType.GOTO] = false;
|
setNotificationState(HifiNotificationType.GOTO, false);
|
||||||
updateTrayMenu(homeServer ? homeServer.state : ProcessGroupStates.STOPPED);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
people: {
|
people: {
|
||||||
label: 'People',
|
label: 'People',
|
||||||
click: function () {
|
click: function () {
|
||||||
StartInterface("hifiapp:PEOPLE");
|
StartInterface("hifiapp:PEOPLE");
|
||||||
pendingNotifications[HifiNotificationType.PEOPLE] = false;
|
setNotificationState(HifiNotificationType.PEOPLE, false);
|
||||||
updateTrayMenu(homeServer ? homeServer.state : ProcessGroupStates.STOPPED);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
wallet: {
|
wallet: {
|
||||||
label: 'Wallet',
|
label: 'Wallet',
|
||||||
click: function () {
|
click: function () {
|
||||||
StartInterface("hifiapp:WALLET");
|
StartInterface("hifiapp:WALLET");
|
||||||
pendingNotifications[HifiNotificationType.WALLET] = false;
|
setNotificationState(HifiNotificationType.WALLET, false);
|
||||||
updateTrayMenu(homeServer ? homeServer.state : ProcessGroupStates.STOPPED);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
marketplace: {
|
marketplace: {
|
||||||
label: 'Market',
|
label: 'Market',
|
||||||
click: function () {
|
click: function () {
|
||||||
StartInterface("hifiapp:MARKET");
|
StartInterface("hifiapp:MARKET");
|
||||||
pendingNotifications[HifiNotificationType.MARKETPLACE] = false;
|
setNotificationState(HifiNotificationType.MARKETPLACE, false);
|
||||||
updateTrayMenu(homeServer ? homeServer.state : ProcessGroupStates.STOPPED);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
restart: {
|
restart: {
|
||||||
|
@ -517,11 +526,13 @@ function buildMenuArray(serverState) {
|
||||||
menuArray.push(labels.share);
|
menuArray.push(labels.share);
|
||||||
menuArray.push(separator);
|
menuArray.push(separator);
|
||||||
if (isInterfaceInstalled()) {
|
if (isInterfaceInstalled()) {
|
||||||
menuArray.push(labels.goto);
|
if (trayNotifications.enabled()) {
|
||||||
menuArray.push(labels.people);
|
menuArray.push(labels.goto);
|
||||||
menuArray.push(labels.wallet);
|
menuArray.push(labels.people);
|
||||||
menuArray.push(labels.marketplace);
|
menuArray.push(labels.wallet);
|
||||||
menuArray.push(separator);
|
menuArray.push(labels.marketplace);
|
||||||
|
menuArray.push(separator);
|
||||||
|
}
|
||||||
menuArray.push(labels.showNotifications);
|
menuArray.push(labels.showNotifications);
|
||||||
menuArray.push(separator);
|
menuArray.push(separator);
|
||||||
}
|
}
|
||||||
|
@ -553,10 +564,6 @@ function updateLabels(serverState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
labels.showNotifications.checked = trayNotifications.enabled();
|
labels.showNotifications.checked = trayNotifications.enabled();
|
||||||
labels.people.visible = trayNotifications.enabled();
|
|
||||||
labels.goto.visible = trayNotifications.enabled();
|
|
||||||
labels.wallet.visible = trayNotifications.enabled();
|
|
||||||
labels.marketplace.visible = trayNotifications.enabled();
|
|
||||||
labels.goto.icon = pendingNotifications[HifiNotificationType.GOTO] ? menuNotificationIcon : null;
|
labels.goto.icon = pendingNotifications[HifiNotificationType.GOTO] ? menuNotificationIcon : null;
|
||||||
labels.people.icon = pendingNotifications[HifiNotificationType.PEOPLE] ? menuNotificationIcon : null;
|
labels.people.icon = pendingNotifications[HifiNotificationType.PEOPLE] ? menuNotificationIcon : null;
|
||||||
labels.wallet.icon = pendingNotifications[HifiNotificationType.WALLET] ? menuNotificationIcon : null;
|
labels.wallet.icon = pendingNotifications[HifiNotificationType.WALLET] ? menuNotificationIcon : null;
|
||||||
|
@ -567,7 +574,7 @@ function updateLabels(serverState) {
|
||||||
function updateTrayMenu(serverState) {
|
function updateTrayMenu(serverState) {
|
||||||
if (tray) {
|
if (tray) {
|
||||||
var menuArray = buildMenuArray(isShuttingDown ? null : serverState);
|
var menuArray = buildMenuArray(isShuttingDown ? null : serverState);
|
||||||
tray.setImage(trayIcons[serverState]);
|
tray.setImage(trayIcons[notificationState]);
|
||||||
tray.setContextMenu(Menu.buildFromTemplate(menuArray));
|
tray.setContextMenu(Menu.buildFromTemplate(menuArray));
|
||||||
if (isShuttingDown) {
|
if (isShuttingDown) {
|
||||||
tray.setToolTip('High Fidelity - Shutting Down');
|
tray.setToolTip('High Fidelity - Shutting Down');
|
||||||
|
@ -787,9 +794,8 @@ function maybeShowSplash() {
|
||||||
|
|
||||||
const trayIconOS = (osType == "Darwin") ? "osx" : "win";
|
const trayIconOS = (osType == "Darwin") ? "osx" : "win";
|
||||||
var trayIcons = {};
|
var trayIcons = {};
|
||||||
trayIcons[ProcessGroupStates.STARTED] = "console-tray-" + trayIconOS + ".png";
|
trayIcons[NotificationState.UNNOTIFIED] = "console-tray-" + trayIconOS + ".png";
|
||||||
trayIcons[ProcessGroupStates.STOPPED] = "console-tray-" + trayIconOS + "-stopped.png";
|
trayIcons[NotificationState.NOTIFIED] = "console-tray-" + trayIconOS + "-stopped.png";
|
||||||
trayIcons[ProcessGroupStates.STOPPING] = "console-tray-" + trayIconOS + "-stopping.png";
|
|
||||||
for (var key in trayIcons) {
|
for (var key in trayIcons) {
|
||||||
var fullPath = path.join(__dirname, '../resources/' + trayIcons[key]);
|
var fullPath = path.join(__dirname, '../resources/' + trayIcons[key]);
|
||||||
var img = nativeImage.createFromPath(fullPath);
|
var img = nativeImage.createFromPath(fullPath);
|
||||||
|
@ -815,33 +821,33 @@ function onContentLoaded() {
|
||||||
// Disable splash window for now.
|
// Disable splash window for now.
|
||||||
// maybeShowSplash();
|
// maybeShowSplash();
|
||||||
|
|
||||||
if (buildInfo.releaseType == 'PRODUCTION' && !argv.noUpdater) {
|
|
||||||
|
|
||||||
const CHECK_FOR_UPDATES_INTERVAL_SECONDS = 60 * 30;
|
|
||||||
var hasShownUpdateNotification = false;
|
|
||||||
const updateChecker = new updater.UpdateChecker(buildInfo, CHECK_FOR_UPDATES_INTERVAL_SECONDS);
|
|
||||||
updateChecker.on('update-available', function(latestVersion, url) {
|
|
||||||
if (!hasShownUpdateNotification) {
|
|
||||||
notifier.notify({
|
|
||||||
icon: notificationIcon,
|
|
||||||
title: 'An update is available!',
|
|
||||||
message: 'High Fidelity version ' + latestVersion + ' is available',
|
|
||||||
wait: true,
|
|
||||||
appID: buildInfo.appUserModelId,
|
|
||||||
url: url
|
|
||||||
});
|
|
||||||
hasShownUpdateNotification = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
notifier.on('click', function(notifierObject, options) {
|
|
||||||
log.debug("Got click", options.url);
|
|
||||||
shell.openExternal(options.url);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteOldFiles(logPath, DELETE_LOG_FILES_OLDER_THAN_X_SECONDS, LOG_FILE_REGEX);
|
|
||||||
|
|
||||||
if (isServerInstalled()) {
|
if (isServerInstalled()) {
|
||||||
|
if (buildInfo.releaseType == 'PRODUCTION' && !argv.noUpdater) {
|
||||||
|
|
||||||
|
const CHECK_FOR_UPDATES_INTERVAL_SECONDS = 60 * 30;
|
||||||
|
var hasShownUpdateNotification = false;
|
||||||
|
const updateChecker = new updater.UpdateChecker(buildInfo, CHECK_FOR_UPDATES_INTERVAL_SECONDS);
|
||||||
|
updateChecker.on('update-available', function(latestVersion, url) {
|
||||||
|
if (!hasShownUpdateNotification) {
|
||||||
|
notifier.notify({
|
||||||
|
icon: notificationIcon,
|
||||||
|
title: 'An update is available!',
|
||||||
|
message: 'High Fidelity version ' + latestVersion + ' is available',
|
||||||
|
wait: true,
|
||||||
|
appID: buildInfo.appUserModelId,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
hasShownUpdateNotification = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
notifier.on('click', function(notifierObject, options) {
|
||||||
|
log.debug("Got click", options.url);
|
||||||
|
shell.openExternal(options.url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteOldFiles(logPath, DELETE_LOG_FILES_OLDER_THAN_X_SECONDS, LOG_FILE_REGEX);
|
||||||
|
|
||||||
var dsArguments = ['--get-temp-name',
|
var dsArguments = ['--get-temp-name',
|
||||||
'--parent-pid', process.pid];
|
'--parent-pid', process.pid];
|
||||||
domainServer = new Process('domain-server', dsPath, dsArguments, logPath);
|
domainServer = new Process('domain-server', dsPath, dsArguments, logPath);
|
||||||
|
@ -902,13 +908,16 @@ app.on('ready', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create tray icon
|
// Create tray icon
|
||||||
tray = new Tray(trayIcons[ProcessGroupStates.STOPPED]);
|
tray = new Tray(trayIcons[NotificationState.UNNOTIFIED]);
|
||||||
tray.setToolTip('High Fidelity');
|
tray.setToolTip('High Fidelity');
|
||||||
|
|
||||||
tray.on('click', function() {
|
tray.on('click', function() {
|
||||||
tray.popUpContextMenu(tray.menu);
|
tray.popUpContextMenu(tray.menu);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (isInterfaceInstalled()) {
|
||||||
|
trayNotifications.startPolling();
|
||||||
|
}
|
||||||
updateTrayMenu(ProcessGroupStates.STOPPED);
|
updateTrayMenu(ProcessGroupStates.STOPPED);
|
||||||
|
|
||||||
maybeInstallDefaultContentSet(onContentLoaded);
|
maybeInstallDefaultContentSet(onContentLoaded);
|
||||||
|
|
|
@ -66,7 +66,7 @@ AccountInfo.prototype = {
|
||||||
case VariantTypes.USER_TYPE:
|
case VariantTypes.USER_TYPE:
|
||||||
//user type
|
//user type
|
||||||
var userTypeName = this._parseByteArray().toString('ascii').slice(0,-1);
|
var userTypeName = this._parseByteArray().toString('ascii').slice(0,-1);
|
||||||
if (userTypeName == "DataServerAccountInfo") {
|
if (userTypeName === "DataServerAccountInfo") {
|
||||||
return this._parseDataServerAccountInfo();
|
return this._parseDataServerAccountInfo();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -77,7 +77,7 @@ AccountInfo.prototype = {
|
||||||
},
|
},
|
||||||
_parseByteArray: function () {
|
_parseByteArray: function () {
|
||||||
var length = this._parseUInt32();
|
var length = this._parseUInt32();
|
||||||
if (length == 0xffffffff) {
|
if (length === 0xffffffff) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var result = this.rawData.slice(this.parseOffset, this.parseOffset+length);
|
var result = this.rawData.slice(this.parseOffset, this.parseOffset+length);
|
||||||
|
@ -91,7 +91,7 @@ AccountInfo.prototype = {
|
||||||
}
|
}
|
||||||
// length in bytes;
|
// length in bytes;
|
||||||
var length = this._parseUInt32();
|
var length = this._parseUInt32();
|
||||||
if (length == 0xFFFFFFFF) {
|
if (length === 0xFFFFFFFF) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ const path = require('path');
|
||||||
const argv = require('yargs').argv;
|
const argv = require('yargs').argv;
|
||||||
const hfprocess = require('./hf-process');
|
const hfprocess = require('./hf-process');
|
||||||
const osHomeDir = require('os-homedir');
|
const osHomeDir = require('os-homedir');
|
||||||
|
const childProcess = require('child_process');
|
||||||
const Process = hfprocess.Process;
|
const Process = hfprocess.Process;
|
||||||
|
|
||||||
const binaryType = argv.binaryType;
|
const binaryType = argv.binaryType;
|
||||||
|
@ -15,9 +16,9 @@ const osType = os.type();
|
||||||
exports.getBuildInfo = function() {
|
exports.getBuildInfo = function() {
|
||||||
var buildInfoPath = null;
|
var buildInfoPath = null;
|
||||||
|
|
||||||
if (osType == 'Windows_NT') {
|
if (osType === 'Windows_NT') {
|
||||||
buildInfoPath = path.join(path.dirname(process.execPath), 'build-info.json');
|
buildInfoPath = path.join(path.dirname(process.execPath), 'build-info.json');
|
||||||
} else if (osType == 'Darwin') {
|
} else if (osType === 'Darwin') {
|
||||||
var contentPath = ".app/Contents/";
|
var contentPath = ".app/Contents/";
|
||||||
var contentEndIndex = __dirname.indexOf(contentPath);
|
var contentEndIndex = __dirname.indexOf(contentPath);
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ exports.getBuildInfo = function() {
|
||||||
buildNumber: "0",
|
buildNumber: "0",
|
||||||
stableBuild: "0",
|
stableBuild: "0",
|
||||||
organization: "High Fidelity - dev",
|
organization: "High Fidelity - dev",
|
||||||
appUserModelId: "com.highfidelity.sandbox-dev"
|
appUserModelId: "com.highfidelity.console"
|
||||||
};
|
};
|
||||||
var buildInfo = DEFAULT_BUILD_INFO;
|
var buildInfo = DEFAULT_BUILD_INFO;
|
||||||
|
|
||||||
|
@ -50,37 +51,59 @@ exports.getBuildInfo = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildInfo = exports.getBuildInfo();
|
const buildInfo = exports.getBuildInfo();
|
||||||
const interfacePath = pathFinder.discoveredPath("Interface", binaryType, buildInfo.releaseType);
|
const interfacePath = pathFinder.discoveredPath("interface", binaryType, buildInfo.releaseType);
|
||||||
|
|
||||||
exports.startInterface = function(url) {
|
exports.startInterface = function(url) {
|
||||||
var argArray = [];
|
|
||||||
|
|
||||||
// check if we have a url parameter to include
|
if (osType === 'Darwin') {
|
||||||
if (url) {
|
if (!url) {
|
||||||
argArray = ["--url", url];
|
log.debug("No URL given for startInterface");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do this as a workaround for app translocation on osx, which makes
|
||||||
|
// it nearly impossible to find the interface executable
|
||||||
|
var bundle_id = 'com.highfidelity.interface-dev';
|
||||||
|
if (buildInfo.releaseType == 'PR') {
|
||||||
|
bundle_id = 'com.highfidelity.interface-pr';
|
||||||
|
} else if (buildInfo.releaseType == 'PRODUCTION') {
|
||||||
|
bundle_id = 'com.highfidelity.interface';
|
||||||
|
}
|
||||||
|
childProcess.exec('open -b ' + bundle_id + ' --args --url ' + url);
|
||||||
|
} else {
|
||||||
|
var argArray = [];
|
||||||
|
|
||||||
|
// check if we have a url parameter to include
|
||||||
|
if (url) {
|
||||||
|
argArray = ["--url", url];
|
||||||
|
}
|
||||||
|
console.log("Starting with " + url);
|
||||||
|
// create a new Interface instance - Interface makes sure only one is running at a time
|
||||||
|
var pInterface = new Process('Interface', interfacePath, argArray);
|
||||||
|
pInterface.detached = true;
|
||||||
|
pInterface.start();
|
||||||
}
|
}
|
||||||
console.log("Starting with " + url);
|
|
||||||
// create a new Interface instance - Interface makes sure only one is running at a time
|
|
||||||
var pInterface = new Process('Interface', interfacePath, argArray);
|
|
||||||
pInterface.detached = true;
|
|
||||||
pInterface.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.isInterfaceRunning = function(done) {
|
exports.isInterfaceRunning = function(done) {
|
||||||
var pInterface = new Process('interface', 'interface.exe');
|
if (osType === 'Windows_NT') {
|
||||||
|
var pInterface = new Process('interface', 'interface.exe');
|
||||||
|
} else if (osType === 'Darwin') {
|
||||||
|
var pInterface = new Process('interface', 'interface');
|
||||||
|
}
|
||||||
return pInterface.isRunning(done);
|
return pInterface.isRunning(done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
exports.getRootHifiDataDirectory = function(local) {
|
exports.getRootHifiDataDirectory = function(local) {
|
||||||
var organization = buildInfo.organization;
|
var organization = buildInfo.organization;
|
||||||
if (osType == 'Windows_NT') {
|
if (osType === 'Windows_NT') {
|
||||||
if (local) {
|
if (local) {
|
||||||
return path.resolve(osHomeDir(), 'AppData/Local', organization);
|
return path.resolve(osHomeDir(), 'AppData/Local', organization);
|
||||||
} else {
|
} else {
|
||||||
return path.resolve(osHomeDir(), 'AppData/Roaming', organization);
|
return path.resolve(osHomeDir(), 'AppData/Roaming', organization);
|
||||||
}
|
}
|
||||||
} else if (osType == 'Darwin') {
|
} else if (osType === 'Darwin') {
|
||||||
return path.resolve(osHomeDir(), 'Library/Application Support', organization);
|
return path.resolve(osHomeDir(), 'Library/Application Support', organization);
|
||||||
} else {
|
} else {
|
||||||
return path.resolve(osHomeDir(), '.local/share/', organization);
|
return path.resolve(osHomeDir(), '.local/share/', organization);
|
||||||
|
|
|
@ -7,12 +7,15 @@ const path = require('path');
|
||||||
const AccountInfo = require('./hf-acctinfo').AccountInfo;
|
const AccountInfo = require('./hf-acctinfo').AccountInfo;
|
||||||
const GetBuildInfo = hfApp.getBuildInfo;
|
const GetBuildInfo = hfApp.getBuildInfo;
|
||||||
const buildInfo = GetBuildInfo();
|
const buildInfo = GetBuildInfo();
|
||||||
|
const osType = os.type();
|
||||||
|
|
||||||
const notificationIcon = path.join(__dirname, '../../resources/console-notification.png');
|
const notificationIcon = path.join(__dirname, '../../resources/console-notification.png');
|
||||||
const STORIES_NOTIFICATION_POLL_TIME_MS = 120 * 1000;
|
const STORIES_NOTIFICATION_POLL_TIME_MS = 120 * 1000;
|
||||||
const PEOPLE_NOTIFICATION_POLL_TIME_MS = 120 * 1000;
|
const PEOPLE_NOTIFICATION_POLL_TIME_MS = 120 * 1000;
|
||||||
const WALLET_NOTIFICATION_POLL_TIME_MS = 600 * 1000;
|
const WALLET_NOTIFICATION_POLL_TIME_MS = 600 * 1000;
|
||||||
const MARKETPLACE_NOTIFICATION_POLL_TIME_MS = 600 * 1000;
|
const MARKETPLACE_NOTIFICATION_POLL_TIME_MS = 600 * 1000;
|
||||||
|
const OSX_CLICK_DELAY_TIMEOUT = 500;
|
||||||
|
|
||||||
|
|
||||||
const METAVERSE_SERVER_URL= process.env.HIFI_METAVERSE_URL ? process.env.HIFI_METAVERSE_URL : 'https://metaverse.highfidelity.com'
|
const METAVERSE_SERVER_URL= process.env.HIFI_METAVERSE_URL ? process.env.HIFI_METAVERSE_URL : 'https://metaverse.highfidelity.com'
|
||||||
const STORIES_URL= '/api/v1/user_stories';
|
const STORIES_URL= '/api/v1/user_stories';
|
||||||
|
@ -33,21 +36,22 @@ const NotificationType = {
|
||||||
MARKETPLACE: 'marketplace'
|
MARKETPLACE: 'marketplace'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function HifiNotification(notificationType, notificationData, menuNotificationCallback) {
|
function HifiNotification(notificationType, notificationData, menuNotificationCallback) {
|
||||||
this.type = notificationType;
|
this.type = notificationType;
|
||||||
this.data = notificationData;
|
this.data = notificationData;
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiNotification.prototype = {
|
HifiNotification.prototype = {
|
||||||
show: function () {
|
show: function (finished) {
|
||||||
var text = "";
|
var text = "";
|
||||||
var message = "";
|
var message = "";
|
||||||
var url = null;
|
var url = null;
|
||||||
var app = null;
|
var app = null;
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case NotificationType.GOTO:
|
case NotificationType.GOTO:
|
||||||
if (typeof(this.data) == "number") {
|
if (typeof(this.data) === "number") {
|
||||||
if (this.data == 1) {
|
if (this.data === 1) {
|
||||||
text = "You have " + this.data + " event invitation pending."
|
text = "You have " + this.data + " event invitation pending."
|
||||||
} else {
|
} else {
|
||||||
text = "You have " + this.data + " event invitations pending."
|
text = "You have " + this.data + " event invitations pending."
|
||||||
|
@ -62,8 +66,8 @@ HifiNotification.prototype = {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NotificationType.PEOPLE:
|
case NotificationType.PEOPLE:
|
||||||
if (typeof(this.data) == "number") {
|
if (typeof(this.data) === "number") {
|
||||||
if (this.data == 1) {
|
if (this.data === 1) {
|
||||||
text = this.data + " of your connections is online."
|
text = this.data + " of your connections is online."
|
||||||
} else {
|
} else {
|
||||||
text = this.data + " of your connections are online."
|
text = this.data + " of your connections are online."
|
||||||
|
@ -78,8 +82,8 @@ HifiNotification.prototype = {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NotificationType.WALLET:
|
case NotificationType.WALLET:
|
||||||
if (typeof(this.data) == "number") {
|
if (typeof(this.data) === "number") {
|
||||||
if (this.data == 1) {
|
if (this.data === 1) {
|
||||||
text = "You have " + this.data + " unread Wallet transaction.";
|
text = "You have " + this.data + " unread Wallet transaction.";
|
||||||
} else {
|
} else {
|
||||||
text = "You have " + this.data + " unread Wallet transactions.";
|
text = "You have " + this.data + " unread Wallet transactions.";
|
||||||
|
@ -94,8 +98,8 @@ HifiNotification.prototype = {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NotificationType.MARKETPLACE:
|
case NotificationType.MARKETPLACE:
|
||||||
if (typeof(this.data) == "number") {
|
if (typeof(this.data) === "number") {
|
||||||
if (this.data == 1) {
|
if (this.data === 1) {
|
||||||
text = this.data + " of your purchased items has an update available.";
|
text = this.data + " of your purchased items has an update available.";
|
||||||
} else {
|
} else {
|
||||||
text = this.data + " of your purchased items have updates available.";
|
text = this.data + " of your purchased items have updates available.";
|
||||||
|
@ -114,8 +118,18 @@ HifiNotification.prototype = {
|
||||||
message: message,
|
message: message,
|
||||||
wait: true,
|
wait: true,
|
||||||
appID: buildInfo.appUserModelId,
|
appID: buildInfo.appUserModelId,
|
||||||
url: url
|
url: url,
|
||||||
});
|
timeout: 5
|
||||||
|
},
|
||||||
|
function (error, reason, metadata) {
|
||||||
|
if (finished) {
|
||||||
|
if (osType === 'Darwin') {
|
||||||
|
setTimeout(finished, OSX_CLICK_DELAY_TIMEOUT);
|
||||||
|
} else {
|
||||||
|
finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +142,8 @@ function HifiNotifications(config, menuNotificationCallback) {
|
||||||
this.walletSince = new Date(this.config.get("walletNotifySince", "1970-01-01T00:00:00.000Z"));
|
this.walletSince = new Date(this.config.get("walletNotifySince", "1970-01-01T00:00:00.000Z"));
|
||||||
this.marketplaceSince = new Date(this.config.get("marketplaceNotifySince", "1970-01-01T00:00:00.000Z"));
|
this.marketplaceSince = new Date(this.config.get("marketplaceNotifySince", "1970-01-01T00:00:00.000Z"));
|
||||||
|
|
||||||
this.enable(this.enabled());
|
this.pendingNotifications = [];
|
||||||
|
|
||||||
|
|
||||||
var _menuNotificationCallback = menuNotificationCallback;
|
var _menuNotificationCallback = menuNotificationCallback;
|
||||||
notifier.on('click', function (notifierObject, options) {
|
notifier.on('click', function (notifierObject, options) {
|
||||||
|
@ -139,7 +154,7 @@ function HifiNotifications(config, menuNotificationCallback) {
|
||||||
|
|
||||||
HifiNotifications.prototype = {
|
HifiNotifications.prototype = {
|
||||||
enable: function (enabled) {
|
enable: function (enabled) {
|
||||||
this.config.set("enableTrayNotifications", enabled);
|
this.config.set("disableTrayNotifications", !enabled);
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
this.storiesPollTimer = setInterval(function () {
|
this.storiesPollTimer = setInterval(function () {
|
||||||
|
@ -170,22 +185,14 @@ HifiNotifications.prototype = {
|
||||||
},
|
},
|
||||||
MARKETPLACE_NOTIFICATION_POLL_TIME_MS);
|
MARKETPLACE_NOTIFICATION_POLL_TIME_MS);
|
||||||
} else {
|
} else {
|
||||||
if (this.storiesPollTimer) {
|
this.stopPolling();
|
||||||
clearInterval(this.storiesPollTimer);
|
|
||||||
}
|
|
||||||
if (this.peoplePollTimer) {
|
|
||||||
clearInterval(this.peoplePollTimer);
|
|
||||||
}
|
|
||||||
if (this.walletPollTimer) {
|
|
||||||
clearInterval(this.walletPollTimer);
|
|
||||||
}
|
|
||||||
if (this.marketplacePollTimer) {
|
|
||||||
clearInterval(this.marketplacePollTimer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled: function () {
|
enabled: function () {
|
||||||
return this.config.get("enableTrayNotifications", true);
|
return !this.config.get("disableTrayNotifications", false);
|
||||||
|
},
|
||||||
|
startPolling: function () {
|
||||||
|
this.enable(this.enabled());
|
||||||
},
|
},
|
||||||
stopPolling: function () {
|
stopPolling: function () {
|
||||||
this.config.set("storiesNotifySince", this.storiesSince.toISOString());
|
this.config.set("storiesNotifySince", this.storiesSince.toISOString());
|
||||||
|
@ -193,7 +200,48 @@ HifiNotifications.prototype = {
|
||||||
this.config.set("walletNotifySince", this.walletSince.toISOString());
|
this.config.set("walletNotifySince", this.walletSince.toISOString());
|
||||||
this.config.set("marketplaceNotifySince", this.marketplaceSince.toISOString());
|
this.config.set("marketplaceNotifySince", this.marketplaceSince.toISOString());
|
||||||
|
|
||||||
this.enable(false);
|
if (this.storiesPollTimer) {
|
||||||
|
clearInterval(this.storiesPollTimer);
|
||||||
|
}
|
||||||
|
if (this.peoplePollTimer) {
|
||||||
|
clearInterval(this.peoplePollTimer);
|
||||||
|
}
|
||||||
|
if (this.walletPollTimer) {
|
||||||
|
clearInterval(this.walletPollTimer);
|
||||||
|
}
|
||||||
|
if (this.marketplacePollTimer) {
|
||||||
|
clearInterval(this.marketplacePollTimer);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_showNotification: function () {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
if (osType === 'Darwin') {
|
||||||
|
this.pendingNotifications[0].show(function () {
|
||||||
|
// For OSX
|
||||||
|
// Don't attempt to show the next notification
|
||||||
|
// until the current is clicked or times out
|
||||||
|
// as the OSX Notifier stuff will dismiss the
|
||||||
|
// previous notification immediately when a
|
||||||
|
// new one is submitted
|
||||||
|
_this.pendingNotifications.shift();
|
||||||
|
if(_this.pendingNotifications.length > 0) {
|
||||||
|
_this._showNotification();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// For Windows
|
||||||
|
// All notifications are sent immediately as they are queued
|
||||||
|
// by windows in Tray Notifications and can be bulk seen and
|
||||||
|
// dismissed
|
||||||
|
_this.pendingNotifications.shift().show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_addNotification: function (notification) {
|
||||||
|
this.pendingNotifications.push(notification);
|
||||||
|
if (this.pendingNotifications.length === 1) {
|
||||||
|
this._showNotification();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_pollToDisableHighlight: function (notifyType, error, data) {
|
_pollToDisableHighlight: function (notifyType, error, data) {
|
||||||
if (error || !data.body) {
|
if (error || !data.body) {
|
||||||
|
@ -248,8 +296,7 @@ HifiNotifications.prototype = {
|
||||||
}
|
}
|
||||||
_this.menuNotificationCallback(notifyType, true);
|
_this.menuNotificationCallback(notifyType, true);
|
||||||
if (content.total_entries >= maxNotificationItemCount) {
|
if (content.total_entries >= maxNotificationItemCount) {
|
||||||
var notification = new HifiNotification(notifyType, content.total_entries);
|
_this._addNotification(new HifiNotification(notifyType, content.total_entries));
|
||||||
notification.show();
|
|
||||||
} else {
|
} else {
|
||||||
var notifyData = []
|
var notifyData = []
|
||||||
switch (notifyType) {
|
switch (notifyType) {
|
||||||
|
@ -268,8 +315,7 @@ HifiNotifications.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyData.forEach(function (notifyDataEntry) {
|
notifyData.forEach(function (notifyDataEntry) {
|
||||||
var notification = new HifiNotification(notifyType, notifyDataEntry);
|
_this._addNotification(new HifiNotification(notifyType, notifyDataEntry));
|
||||||
notification.show();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
finished(true, token);
|
finished(true, token);
|
||||||
|
@ -376,13 +422,11 @@ HifiNotifications.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newUsers.size >= maxNotificationItemCount) {
|
if (newUsers.size >= maxNotificationItemCount) {
|
||||||
var notification = new HifiNotification(NotificationType.PEOPLE, newUsers.size);
|
_this._addNotification(new HifiNotification(NotificationType.PEOPLE, newUsers.size));
|
||||||
notification.show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
newUsers.forEach(function (user) {
|
newUsers.forEach(function (user) {
|
||||||
var notification = new HifiNotification(NotificationType.PEOPLE, user);
|
_this._addNotification(new HifiNotification(NotificationType.PEOPLE, user));
|
||||||
notification.show();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -274,7 +274,9 @@ Process.prototype = extend(Process.prototype, {
|
||||||
done(running);
|
done(running);
|
||||||
});
|
});
|
||||||
} else if (os.type == 'Darwin') {
|
} else if (os.type == 'Darwin') {
|
||||||
console.log("TODO IsRunning Darwin");
|
childProcess.exec('ps cax | grep ' + _command, function (err, stdout, stderr) {
|
||||||
|
done(stdout.length > 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
const { app } = require('electron');
|
||||||
|
|
||||||
function platformExtension(name) {
|
function platformExtension(name) {
|
||||||
if (name == "Interface") {
|
if (name == "interface") {
|
||||||
if (process.platform == "darwin") {
|
if (process.platform == "darwin") {
|
||||||
return ".app/Contents/MacOS/" + name
|
return ".app/Contents/MacOS/" + name
|
||||||
} else if (process.platform == "win32") {
|
} else if (process.platform == "win32") {
|
||||||
|
@ -53,9 +54,9 @@ exports.searchPaths = function(name, binaryType, releaseType) {
|
||||||
var componentsPath = appPath + "/Contents/MacOS/Components.app/Contents/MacOS/";
|
var componentsPath = appPath + "/Contents/MacOS/Components.app/Contents/MacOS/";
|
||||||
paths.push(componentsPath + name + extension);
|
paths.push(componentsPath + name + extension);
|
||||||
|
|
||||||
// check beside the app bundle for the binaries
|
|
||||||
paths.push(path.join(path.dirname(appPath), name + extension));
|
|
||||||
}
|
}
|
||||||
|
// check beside the app bundle for the binaries
|
||||||
|
paths.push(path.join(path.dirname(app.getAppPath()), "../../..", name + extension));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue