mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-07 10:52:37 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into qt-launcher
This commit is contained in:
commit
97644eb335
440 changed files with 14261 additions and 7321 deletions
|
@ -71,9 +71,13 @@ RUN mkdir "$HIFI_BASE" && \
|
|||
mkdir "$HIFI_VCPKG_BASE" && \
|
||||
mkdir "$HIFI_ANDROID_PRECOMPILED"
|
||||
|
||||
RUN git clone https://github.com/jherico/hifi.git && \
|
||||
# Checkout a relatively recent commit from the main repository and use it to cache the
|
||||
# gradle and vcpkg dependencies
|
||||
# This commit ID should be updated whenever someone changes the dependency list
|
||||
# in cmake/ports
|
||||
RUN git clone https://github.com/highfidelity/hifi.git && \
|
||||
cd ~/hifi && \
|
||||
git checkout quest/build
|
||||
git checkout 796bfb5d6715ff14c2e60f3ee8fac1465b7578c6
|
||||
|
||||
WORKDIR /home/jenkins/hifi
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ Agent::Agent(ReceivedMessage& message) :
|
|||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||
|
||||
DependencyManager::set<ResourceManager>();
|
||||
DependencyManager::set<PluginManager>();
|
||||
DependencyManager::set<PluginManager>()->instantiate();
|
||||
|
||||
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
||||
|
||||
|
@ -433,7 +433,7 @@ void Agent::executeScript() {
|
|||
|
||||
using namespace recording;
|
||||
static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::getAudioFrameName());
|
||||
Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &scriptedAvatar](Frame::ConstPointer frame) {
|
||||
Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &player, &scriptedAvatar](Frame::ConstPointer frame) {
|
||||
if (_shouldMuteRecordingAudio) {
|
||||
return;
|
||||
}
|
||||
|
@ -442,9 +442,18 @@ void Agent::executeScript() {
|
|||
|
||||
QByteArray audio(frame->data);
|
||||
|
||||
int16_t* samples = reinterpret_cast<int16_t*>(audio.data());
|
||||
int numSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL;
|
||||
|
||||
auto volume = player->getVolume();
|
||||
if (volume >= 0.0f && volume < 1.0f) {
|
||||
int32_t fract = (int32_t)(volume * (float)(1 << 16)); // Q16
|
||||
for (int i = 0; i < numSamples; i++) {
|
||||
samples[i] = (fract * (int32_t)samples[i]) >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
if (_isNoiseGateEnabled) {
|
||||
int16_t* samples = reinterpret_cast<int16_t*>(audio.data());
|
||||
int numSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL;
|
||||
_audioGate.render(samples, samples, numSamples);
|
||||
}
|
||||
|
||||
|
@ -511,6 +520,7 @@ void Agent::executeScript() {
|
|||
|
||||
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
|
||||
|
||||
DependencyManager::get<ScriptEngines>()->runScriptInitializers(_scriptEngine);
|
||||
_scriptEngine->run();
|
||||
|
||||
Frame::clearFrameHandler(AUDIO_FRAME_TYPE);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <AccountManager.h>
|
||||
#include <AddressManager.h>
|
||||
#include <Assignment.h>
|
||||
#include <CrashAnnotations.h>
|
||||
#include <LogHandler.h>
|
||||
#include <LogUtils.h>
|
||||
#include <LimitedNodeList.h>
|
||||
|
@ -144,6 +145,7 @@ AssignmentClient::~AssignmentClient() {
|
|||
}
|
||||
|
||||
void AssignmentClient::aboutToQuit() {
|
||||
crash::annotations::setShutdownState(true);
|
||||
stopAssignmentClient();
|
||||
}
|
||||
|
||||
|
@ -173,6 +175,7 @@ void AssignmentClient::sendStatusPacketToACM() {
|
|||
|
||||
void AssignmentClient::sendAssignmentRequest() {
|
||||
if (!_currentAssignment && !_isAssigned) {
|
||||
crash::annotations::setShutdownState(false);
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
|
@ -289,6 +292,8 @@ void AssignmentClient::handleAuthenticationRequest() {
|
|||
}
|
||||
|
||||
void AssignmentClient::assignmentCompleted() {
|
||||
crash::annotations::setShutdownState(true);
|
||||
|
||||
// we expect that to be here the previous assignment has completely cleaned up
|
||||
assert(_currentAssignment.isNull());
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <HifiConfigVariantMap.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <ShutdownEventListener.h>
|
||||
#include <shared/ScriptInitializerMixin.h>
|
||||
|
||||
#include "Assignment.h"
|
||||
#include "AssignmentClient.h"
|
||||
|
@ -239,7 +240,11 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
|
||||
QThread::currentThread()->setObjectName("main thread");
|
||||
|
||||
LogHandler::getInstance().moveToThread(thread());
|
||||
LogHandler::getInstance().setupRepeatedMessageFlusher();
|
||||
|
||||
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
||||
DependencyManager::set<ScriptInitializers>();
|
||||
|
||||
if (numForks || minForks || maxForks) {
|
||||
AssignmentClientMonitor* monitor = new AssignmentClientMonitor(numForks, minForks, maxForks,
|
||||
|
|
|
@ -499,6 +499,8 @@ void AvatarMixer::handleAvatarKilled(SharedNodePointer avatarNode) {
|
|||
} else {
|
||||
_sessionDisplayNames.erase(displayNameIter);
|
||||
}
|
||||
|
||||
nodeData->getAvatar().stopChallengeTimer();
|
||||
}
|
||||
|
||||
std::unique_ptr<NLPacket> killPacket;
|
||||
|
|
|
@ -33,12 +33,12 @@ MixerAvatar::MixerAvatar() {
|
|||
_challengeTimer.setSingleShot(true);
|
||||
_challengeTimer.setInterval(CHALLENGE_TIMEOUT_MS);
|
||||
|
||||
_challengeTimer.callOnTimeout([this]() {
|
||||
_challengeTimer.callOnTimeout(this, [this]() {
|
||||
if (_verifyState == challengeClient) {
|
||||
_pendingEvent = false;
|
||||
_verifyState = verificationFailed;
|
||||
_needsIdentityUpdate = true;
|
||||
qCDebug(avatars) << "Dynamic verification TIMED-OUT for " << getDisplayName() << getSessionUUID();
|
||||
qCDebug(avatars) << "Dynamic verification TIMED-OUT for" << getDisplayName() << getSessionUUID();
|
||||
} else {
|
||||
qCDebug(avatars) << "Ignoring timeout of avatar challenge";
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ void MixerAvatar::processCertifyEvents() {
|
|||
<< ":" << _dynamicMarketResponse;
|
||||
}
|
||||
} else {
|
||||
qCDebug(avatars) << "Get owner status failed for " << getDisplayName() << _marketplaceIdFromURL <<
|
||||
qCDebug(avatars) << "Get owner status failed for" << getDisplayName() << _marketplaceIdFromURL <<
|
||||
"message:" << responseJson["message"].toString();
|
||||
_verifyState = error;
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ void MixerAvatar::sendOwnerChallenge() {
|
|||
void MixerAvatar::processChallengeResponse(ReceivedMessage& response) {
|
||||
QByteArray avatarID;
|
||||
QMutexLocker certifyLocker(&_avatarCertifyLock);
|
||||
QMetaObject::invokeMethod(&_challengeTimer, &QTimer::stop);
|
||||
stopChallengeTimer();
|
||||
if (_verifyState == challengeClient) {
|
||||
QByteArray responseData = response.readAll();
|
||||
if (responseData.length() < 8) {
|
||||
|
@ -356,7 +356,7 @@ void MixerAvatar::processChallengeResponse(ReceivedMessage& response) {
|
|||
_verifyState = challengeResult ? verificationSucceeded : verificationFailed;
|
||||
_needsIdentityUpdate = true;
|
||||
if (_verifyState == verificationFailed) {
|
||||
qCDebug(avatars) << "Dynamic verification FAILED for " << getDisplayName() << getSessionUUID();
|
||||
qCDebug(avatars) << "Dynamic verification FAILED for" << getDisplayName() << getSessionUUID();
|
||||
} else {
|
||||
qCDebug(avatars) << "Dynamic verification SUCCEEDED for" << getDisplayName() << getSessionUUID();
|
||||
}
|
||||
|
@ -365,3 +365,11 @@ void MixerAvatar::processChallengeResponse(ReceivedMessage& response) {
|
|||
qCDebug(avatars) << "WARNING: Unexpected avatar challenge-response in state" << stateToName(_verifyState);
|
||||
}
|
||||
}
|
||||
|
||||
void MixerAvatar::stopChallengeTimer() {
|
||||
if (QThread::currentThread() == thread()) {
|
||||
_challengeTimer.stop();
|
||||
} else {
|
||||
QMetaObject::invokeMethod(&_challengeTimer, &QTimer::stop);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ public:
|
|||
void processCertifyEvents();
|
||||
void processChallengeResponse(ReceivedMessage& response);
|
||||
|
||||
void stopChallengeTimer();
|
||||
|
||||
// Avatar certification/verification:
|
||||
enum VerifyState {
|
||||
nonCertified, requestingFST, receivedFST, staticValidation, requestingOwner, ownerResponse,
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
#include <QJsonDocument>
|
||||
|
||||
#include <EntityTree.h>
|
||||
#include <SimpleEntitySimulation.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <ScriptCache.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
#include <EntityEditFilters.h>
|
||||
#include <NetworkingConstants.h>
|
||||
#include <hfm/ModelFormatRegistry.h>
|
||||
|
@ -36,12 +36,13 @@ const char* LOCAL_MODELS_PERSIST_FILE = "resources/models.svo";
|
|||
|
||||
EntityServer::EntityServer(ReceivedMessage& message) :
|
||||
OctreeServer(message),
|
||||
_entitySimulation(NULL),
|
||||
_entitySimulation(nullptr),
|
||||
_dynamicDomainVerificationTimer(this)
|
||||
{
|
||||
DependencyManager::set<ResourceManager>();
|
||||
DependencyManager::set<ResourceCacheSharedItems>();
|
||||
DependencyManager::set<ScriptCache>();
|
||||
DependencyManager::set<PluginManager>()->instantiate();
|
||||
|
||||
DependencyManager::registerInheritance<EntityDynamicFactoryInterface, AssignmentDynamicFactory>();
|
||||
DependencyManager::set<AssignmentDynamicFactory>();
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "EntityItem.h"
|
||||
#include <EntityItem.h>
|
||||
#include <EntityTree.h>
|
||||
#include <SimpleEntitySimulation.h>
|
||||
|
||||
#include "EntityServerConsts.h"
|
||||
#include "EntityTree.h"
|
||||
|
||||
/// Handles assignments of type EntityServer - sending entities to various clients.
|
||||
|
||||
|
@ -27,9 +29,6 @@ struct ViewerSendingStats {
|
|||
quint64 lastEdited;
|
||||
};
|
||||
|
||||
class SimpleEntitySimulation;
|
||||
using SimpleEntitySimulationPointer = std::shared_ptr<SimpleEntitySimulation>;
|
||||
|
||||
class EntityServer : public OctreeServer, public NewlyCreatedEntityHook {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
|
@ -64,7 +64,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
|||
DependencyManager::set<ResourceScriptingInterface>();
|
||||
|
||||
DependencyManager::set<ResourceManager>();
|
||||
DependencyManager::set<PluginManager>();
|
||||
DependencyManager::set<PluginManager>()->instantiate();
|
||||
|
||||
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
||||
|
||||
|
@ -301,10 +301,17 @@ void EntityScriptServer::run() {
|
|||
|
||||
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
||||
|
||||
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
|
||||
auto treePtr = _entityViewer.getTree();
|
||||
DependencyManager::set<AssignmentParentFinder>(treePtr);
|
||||
|
||||
if (!_entitySimulation) {
|
||||
SimpleEntitySimulationPointer simpleSimulation { new SimpleEntitySimulation() };
|
||||
simpleSimulation->setEntityTree(treePtr);
|
||||
treePtr->setSimulation(simpleSimulation);
|
||||
_entitySimulation = simpleSimulation;
|
||||
}
|
||||
|
||||
auto tree = _entityViewer.getTree().get();
|
||||
auto tree = treePtr.get();
|
||||
connect(tree, &EntityTree::deletingEntity, this, &EntityScriptServer::deletingEntity, Qt::QueuedConnection);
|
||||
connect(tree, &EntityTree::addingEntity, this, &EntityScriptServer::addingEntity, Qt::QueuedConnection);
|
||||
connect(tree, &EntityTree::entityServerScriptChanging, this, &EntityScriptServer::entityServerScriptChanging, Qt::QueuedConnection);
|
||||
|
@ -451,10 +458,11 @@ void EntityScriptServer::resetEntitiesScriptEngine() {
|
|||
|
||||
connect(newEngine.data(), &ScriptEngine::update, this, [this] {
|
||||
_entityViewer.queryOctree();
|
||||
_entityViewer.getTree()->preUpdate();
|
||||
_entityViewer.getTree()->update();
|
||||
});
|
||||
|
||||
|
||||
scriptEngines->runScriptInitializers(newEngine);
|
||||
newEngine->runInThread();
|
||||
auto newEngineSP = qSharedPointerCast<EntitiesScriptEngineProvider>(newEngine);
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(newEngineSP);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <EntityEditPacketSender.h>
|
||||
#include <plugins/CodecPlugin.h>
|
||||
#include <ScriptEngine.h>
|
||||
#include <SimpleEntitySimulation.h>
|
||||
#include <ThreadedAssignment.h>
|
||||
#include "../entities/EntityTreeHeadlessViewer.h"
|
||||
|
||||
|
@ -75,6 +76,7 @@ private:
|
|||
|
||||
static int _entitiesScriptEngineCount;
|
||||
ScriptEnginePointer _entitiesScriptEngine;
|
||||
SimpleEntitySimulationPointer _entitySimulation;
|
||||
EntityEditPacketSender _entityEditSender;
|
||||
EntityTreeHeadlessViewer _entityViewer;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ if (WIN32)
|
|||
list(APPEND CMAKE_PREFIX_PATH "${WINDOW_SDK_PATH}")
|
||||
|
||||
# /wd4351 disables warning C4351: new behavior: elements of array will be default initialized
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /wd4351")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP${HIFI_MAX_BUILD_CORES} /wd4351")
|
||||
# /LARGEADDRESSAWARE enables 32-bit apps to use more than 2GB of memory.
|
||||
# Caveats: http://stackoverflow.com/questions/2288728/drawbacks-of-using-largeaddressaware-for-32-bit-windows-executables
|
||||
# TODO: Remove when building 64-bit.
|
||||
|
|
|
@ -38,7 +38,7 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(BUILD_ORGANIZATION "High Fidelity")
|
||||
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")
|
||||
|
||||
# add definition for this release type
|
||||
|
@ -61,7 +61,7 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(PR_BUILD 1)
|
||||
set(BUILD_VERSION "PR${RELEASE_NUMBER}")
|
||||
set(BUILD_ORGANIZATION "High Fidelity - PR${RELEASE_NUMBER}")
|
||||
set(INTERFACE_BUNDLE_NAME "Interface")
|
||||
set(INTERFACE_BUNDLE_NAME "interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface-beta")
|
||||
|
||||
# add definition for this release type
|
||||
|
@ -70,7 +70,7 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(DEV_BUILD 1)
|
||||
set(BUILD_VERSION "dev")
|
||||
set(BUILD_ORGANIZATION "High Fidelity - ${BUILD_VERSION}")
|
||||
set(INTERFACE_BUNDLE_NAME "Interface")
|
||||
set(INTERFACE_BUNDLE_NAME "interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface-beta")
|
||||
|
||||
# add definition for this release type
|
||||
|
@ -192,12 +192,12 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
|
||||
# shortcut names
|
||||
if (PRODUCTION_BUILD)
|
||||
set(INTERFACE_SHORTCUT_NAME "High Fidelity Interface")
|
||||
set(INTERFACE_SHORTCUT_NAME "High Fidelity")
|
||||
set(CONSOLE_SHORTCUT_NAME "Console")
|
||||
set(SANDBOX_SHORTCUT_NAME "Sandbox")
|
||||
set(APP_USER_MODEL_ID "com.highfidelity.console")
|
||||
else ()
|
||||
set(INTERFACE_SHORTCUT_NAME "High Fidelity Interface - ${BUILD_VERSION_NO_SHA}")
|
||||
set(INTERFACE_SHORTCUT_NAME "High Fidelity - ${BUILD_VERSION_NO_SHA}")
|
||||
set(CONSOLE_SHORTCUT_NAME "Console - ${BUILD_VERSION_NO_SHA}")
|
||||
set(SANDBOX_SHORTCUT_NAME "Sandbox - ${BUILD_VERSION_NO_SHA}")
|
||||
endif ()
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
#
|
||||
macro(SETUP_HIFI_CLIENT_SERVER_PLUGIN)
|
||||
set(${TARGET_NAME}_SHARED 1)
|
||||
setup_hifi_library(${ARGV})
|
||||
set(PLUGIN_SUBFOLDER ${ARGN})
|
||||
setup_hifi_library()
|
||||
|
||||
if (BUILD_CLIENT)
|
||||
add_dependencies(interface ${TARGET_NAME})
|
||||
|
@ -27,6 +28,11 @@ macro(SETUP_HIFI_CLIENT_SERVER_PLUGIN)
|
|||
set(SERVER_PLUGIN_PATH "plugins")
|
||||
endif()
|
||||
|
||||
if (PLUGIN_SUBFOLDER)
|
||||
set(CLIENT_PLUGIN_PATH "${CLIENT_PLUGIN_PATH}/${PLUGIN_SUBFOLDER}")
|
||||
set(SERVER_PLUGIN_PATH "${SERVER_PLUGIN_PATH}/${PLUGIN_SUBFOLDER}")
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_GENERATOR STREQUAL "Unix Makefiles")
|
||||
set(CLIENT_PLUGIN_FULL_PATH "${CMAKE_BINARY_DIR}/interface/${CLIENT_PLUGIN_PATH}/")
|
||||
set(SERVER_PLUGIN_FULL_PATH "${CMAKE_BINARY_DIR}/assignment-client/${SERVER_PLUGIN_PATH}/")
|
||||
|
|
|
@ -20,7 +20,7 @@ macro(SETUP_HIFI_LIBRARY)
|
|||
foreach(SRC ${AVX_SRCS})
|
||||
if (WIN32)
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS /arch:AVX)
|
||||
elseif (APPLE OR UNIX)
|
||||
elseif (APPLE OR (UNIX AND NOT ANDROID))
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS -mavx)
|
||||
endif()
|
||||
endforeach()
|
||||
|
@ -30,7 +30,7 @@ macro(SETUP_HIFI_LIBRARY)
|
|||
foreach(SRC ${AVX2_SRCS})
|
||||
if (WIN32)
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS /arch:AVX2)
|
||||
elseif (APPLE OR UNIX)
|
||||
elseif (APPLE OR (UNIX AND NOT ANDROID))
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS "-mavx2 -mfma")
|
||||
endif()
|
||||
endforeach()
|
||||
|
@ -44,7 +44,7 @@ macro(SETUP_HIFI_LIBRARY)
|
|||
if (COMPILER_SUPPORTS_AVX512)
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS /arch:AVX512)
|
||||
endif()
|
||||
elseif (APPLE OR UNIX)
|
||||
elseif (APPLE OR (UNIX AND NOT ANDROID))
|
||||
check_cxx_compiler_flag("-mavx512f" COMPILER_SUPPORTS_AVX512)
|
||||
if (COMPILER_SUPPORTS_AVX512)
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS -mavx512f)
|
||||
|
|
|
@ -15,9 +15,11 @@ macro(TARGET_WEBRTC)
|
|||
# select_library_configurations(WEBRTC)
|
||||
else()
|
||||
set(WEBRTC_INCLUDE_DIRS "${VCPKG_INSTALL_ROOT}/include/webrtc")
|
||||
find_library(WEBRTC_LIBRARY NAMES webrtc PATHS ${VCPKG_INSTALL_ROOT}/lib/ NO_DEFAULT_PATH)
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${WEBRTC_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${WEBRTC_LIBRARY})
|
||||
find_library(WEBRTC_LIBRARY_RELEASE webrtc PATHS ${VCPKG_INSTALL_ROOT}/lib NO_DEFAULT_PATH)
|
||||
find_library(WEBRTC_LIBRARY_DEBUG webrtc PATHS ${VCPKG_INSTALL_ROOT}/debug/lib NO_DEFAULT_PATH)
|
||||
select_library_configurations(WEBRTC)
|
||||
target_link_libraries(${TARGET_NAME} ${WEBRTC_LIBRARIES})
|
||||
endif()
|
||||
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#
|
||||
# FindiViewHMD.cmake
|
||||
#
|
||||
# Try to find the SMI iViewHMD eye tracker library
|
||||
#
|
||||
# You must provide a IVIEWHMD_ROOT_DIR which contains 3rdParty, include, and libs directories
|
||||
#
|
||||
# Once done this will define
|
||||
#
|
||||
# IVIEWHMD_FOUND - system found iViewHMD
|
||||
# IVIEWHMD_INCLUDE_DIRS - the iViewHMD include directory
|
||||
# IVIEWHMD_LIBRARIES - link this to use iViewHMD
|
||||
#
|
||||
# Created on 27 Jul 2015 by David Rowe
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
#
|
||||
|
||||
if (WIN32)
|
||||
|
||||
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||
hifi_library_search_hints("iViewHMD")
|
||||
|
||||
find_path(IVIEWHMD_INCLUDE_DIRS iViewHMDAPI.h PATH_SUFFIXES include HINTS ${IVIEWHMD_SEARCH_DIRS})
|
||||
find_library(IVIEWHMD_LIBRARIES NAMES iViewHMDAPI PATH_SUFFIXES libs/x86 HINTS ${IVIEWHMD_SEARCH_DIRS})
|
||||
find_path(IVIEWHMD_API_DLL_PATH iViewHMDAPI.dll PATH_SUFFIXES libs/x86 HINTS ${IVIEWHMD_SEARCH_DIRS})
|
||||
list(APPEND IVIEWHMD_REQUIREMENTS IVIEWHMD_INCLUDE_DIRS IVIEWHMD_LIBRARIES IVIEWHMD_API_DLL_PATH)
|
||||
|
||||
find_path(IVIEWHMD_DLL_PATH_3RD_PARTY libiViewNG.dll PATH_SUFFIXES 3rdParty HINTS ${IVIEWHMD_SEARCH_DIRS})
|
||||
list(APPEND IVIEWHMD_REQUIREMENTS IVIEWHMD_DLL_PATH_3RD_PARTY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(IVIEWHMD DEFAULT_MSG ${IVIEWHMD_REQUIREMENTS})
|
||||
|
||||
add_paths_to_fixup_libs(${IVIEWHMD_API_DLL_PATH} ${IVIEWHMD_DLL_PATH_3RD_PARTY})
|
||||
|
||||
mark_as_advanced(IVIEWHMD_INCLUDE_DIRS IVIEWHMD_LIBRARIES IVIEWHMD_SEARCH_DIRS)
|
||||
|
||||
endif()
|
|
@ -1156,7 +1156,17 @@ FunctionEnd
|
|||
|
||||
Section "-Core installation"
|
||||
|
||||
;The following delete blocks are temporary and can be removed once users who had the initial installer have updated
|
||||
; 2016-02-25 - The following delete blocks are temporary and can be removed once users who had the initial installer have updated
|
||||
; 2019-09-10 - (3 and a half years later) Sure they are buddy. Sure they are.
|
||||
|
||||
; MessageBox MB_OK|MB_ICONEXCLAMATION "installer type is @INSTALLER_TYPE@"
|
||||
|
||||
;Delete any server executables that might have been installed by bad versions of the client-only installer, but ONLY if we are a client-only installer
|
||||
${If} "@INSTALLER_TYPE@" == "client_only"
|
||||
; MessageBox MB_OK|MB_ICONEXCLAMATION "trying to delete server binaries"
|
||||
Delete "$INSTDIR\assignment-client.exe"
|
||||
Delete "$INSTDIR\domain-server.exe"
|
||||
${EndIf}
|
||||
|
||||
;Delete any server-console files installed before it was placed in sub-folder
|
||||
Delete "$INSTDIR\server-console.exe"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": 2.3,
|
||||
"version": 2.4,
|
||||
"settings": [
|
||||
{
|
||||
"name": "metaverse",
|
||||
|
@ -1705,6 +1705,114 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "oauth",
|
||||
"label": "OAuth",
|
||||
"show_on_enable": true,
|
||||
"settings": [
|
||||
{
|
||||
"name": "enable",
|
||||
"type": "checkbox",
|
||||
"default": false,
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "admin-users",
|
||||
"label": "Admin Users",
|
||||
"type": "table",
|
||||
"can_add_new_rows": true,
|
||||
"help": "Any of these users can administer the domain.",
|
||||
"numbered": false,
|
||||
"backup": false,
|
||||
"advanced": false,
|
||||
"columns": [
|
||||
{
|
||||
"name": "username",
|
||||
"label": "Username",
|
||||
"can_set": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "admin-roles",
|
||||
"label": "Admin Roles",
|
||||
"type": "table",
|
||||
"can_add_new_rows": true,
|
||||
"help": "Any user with any of these metaverse roles can administer the domain.",
|
||||
"numbered": false,
|
||||
"backup": false,
|
||||
"advanced": true,
|
||||
"columns": [
|
||||
{
|
||||
"name": "role",
|
||||
"label": "Role",
|
||||
"can_set": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "client-id",
|
||||
"label": "Client ID",
|
||||
"help": "OAuth client ID.",
|
||||
"default": "",
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
},
|
||||
{
|
||||
"name": "client-secret",
|
||||
"label": "Client Secret",
|
||||
"help": "OAuth client secret.",
|
||||
"type": "password",
|
||||
"password_placeholder": "******",
|
||||
"value-hidden": true,
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
},
|
||||
{
|
||||
"name": "provider",
|
||||
"label": "Provider",
|
||||
"help": "OAuth provider URL.",
|
||||
"default": "https://metaverse.highfidelity.com",
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
},
|
||||
{
|
||||
"name": "hostname",
|
||||
"label": "Hostname",
|
||||
"help": "OAuth hostname.",
|
||||
"default": "",
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
},
|
||||
{
|
||||
"name": "key-passphrase",
|
||||
"label": "SSL Private Key Passphrase",
|
||||
"help": "SSL Private Key Passphrase",
|
||||
"type": "password",
|
||||
"password_placeholder": "******",
|
||||
"value-hidden": true,
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
},
|
||||
{
|
||||
"name": "cert-fingerprint",
|
||||
"type": "hidden",
|
||||
"readonly": true,
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
},
|
||||
{
|
||||
"name": "cert",
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
},
|
||||
{
|
||||
"name": "key",
|
||||
"advanced": true,
|
||||
"backup": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "automatic_content_archives",
|
||||
"label": "Automatic Content Archives",
|
||||
|
|
|
@ -2,6 +2,9 @@ var DomainInfo = null;
|
|||
|
||||
var viewHelpers = {
|
||||
getFormGroup: function(keypath, setting, values, isAdvanced) {
|
||||
if (setting.hidden) {
|
||||
return "";
|
||||
}
|
||||
form_group = "<div class='form-group " +
|
||||
(isAdvanced ? Settings.ADVANCED_CLASS : "") + " " +
|
||||
(setting.deprecated ? Settings.DEPRECATED_CLASS : "" ) + "' " +
|
||||
|
@ -82,8 +85,9 @@ var viewHelpers = {
|
|||
"placeholder='" + (_.has(setting, 'placeholder') ? setting.placeholder : "") +
|
||||
"' value='" + (_.has(setting, 'password_placeholder') ? setting.password_placeholder : setting_value) + "'/>"
|
||||
}
|
||||
|
||||
form_group += "<span class='help-block'>" + setting.help + "</span>"
|
||||
if (setting.help) {
|
||||
form_group += "<span class='help-block'>" + setting.help + "</span>"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,12 +118,17 @@ function reloadSettings(callback) {
|
|||
data.descriptions.push(Settings.extraGroupsAtEnd[endGroupIndex]);
|
||||
}
|
||||
|
||||
data.descriptions = data.descriptions.map(function(x) {
|
||||
x.hidden = x.hidden || (x.show_on_enable && data.values[x.name] && !data.values[x.name].enable);
|
||||
return x;
|
||||
});
|
||||
|
||||
$('#panels').html(Settings.panelsTemplate(data));
|
||||
|
||||
Settings.data = data;
|
||||
Settings.initialValues = form2js('settings-form', ".", false, cleanupFormValues, true);
|
||||
|
||||
Settings.afterReloadActions();
|
||||
Settings.afterReloadActions(data);
|
||||
|
||||
// setup any bootstrap switches
|
||||
$('.toggle-checkbox').bootstrapSwitch();
|
||||
|
@ -129,10 +138,14 @@ function reloadSettings(callback) {
|
|||
Settings.pendingChanges = 0;
|
||||
|
||||
// call the callback now that settings are loaded
|
||||
callback(true);
|
||||
if (callback) {
|
||||
callback(true);
|
||||
}
|
||||
}).fail(function() {
|
||||
// call the failure object since settings load faild
|
||||
callback(false)
|
||||
if (callback) {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -237,14 +250,14 @@ $(document).ready(function(){
|
|||
|
||||
// set focus to the first input in the new row
|
||||
$target.closest('table').find('tr.inputs input:first').focus();
|
||||
}
|
||||
} else {
|
||||
var tableRows = sibling.parent();
|
||||
var tableBody = tableRows.parent();
|
||||
|
||||
var tableRows = sibling.parent();
|
||||
var tableBody = tableRows.parent();
|
||||
|
||||
// if theres no more siblings, we should jump to a new row
|
||||
if (sibling.next().length == 0 && tableRows.nextAll().length == 1) {
|
||||
tableBody.find("." + Settings.ADD_ROW_BUTTON_CLASS).click();
|
||||
// if theres no more siblings, we should jump to a new row
|
||||
if (sibling.next().length == 0 && tableRows.nextAll().length == 1) {
|
||||
tableBody.find("." + Settings.ADD_ROW_BUTTON_CLASS).click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,19 @@ $(document).ready(function(){
|
|||
Settings.extraGroupsAtIndex = Settings.extraDomainGroupsAtIndex;
|
||||
var METAVERSE_URL = URLs.METAVERSE_URL;
|
||||
|
||||
Settings.afterReloadActions = function() {
|
||||
var SSL_PRIVATE_KEY_FILE_ID = 'ssl-private-key-file';
|
||||
var SSL_PRIVATE_KEY_CONTENTS_ID = 'key-contents';
|
||||
var SSL_PRIVATE_KEY_CONTENTS_NAME = 'oauth.key-contents';
|
||||
var SSL_CERT_UPLOAD_ID = 'ssl-cert-button';
|
||||
var SSL_CERT_FILE_ID = 'ssl-cert-file';
|
||||
var SSL_CERT_FINGERPRINT_ID = 'cert-fingerprint';
|
||||
var SSL_CERT_FINGERPRINT_SPAN_ID = 'cert-fingerprint-span-id';
|
||||
var SSL_CERT_CONTENTS_ID = 'cert-contents';
|
||||
var SSL_CERT_CONTENTS_NAME = 'oauth.cert-contents';
|
||||
var SSL_PRIVATE_KEY_PATH = 'oauth.key';
|
||||
var SSL_CERT_PATH = 'oauth.cert';
|
||||
|
||||
Settings.afterReloadActions = function(data) {
|
||||
|
||||
getMetaverseUrl(function(metaverse_url) {
|
||||
METAVERSE_URL = metaverse_url;
|
||||
|
@ -32,6 +44,8 @@ $(document).ready(function(){
|
|||
setupDomainNetworkingSettings();
|
||||
// setupDomainLabelSetting();
|
||||
|
||||
setupSettingsOAuth(data);
|
||||
|
||||
setupSettingsBackup();
|
||||
|
||||
if (domainIDIsSet()) {
|
||||
|
@ -124,6 +138,48 @@ $(document).ready(function(){
|
|||
}
|
||||
}
|
||||
|
||||
if (formJSON["oauth"]) {
|
||||
var private_key = formJSON["oauth"]["key-contents"];
|
||||
var cert = formJSON["oauth"]["cert-contents"];
|
||||
var oauthErrors = "";
|
||||
if (private_key != undefined) {
|
||||
var pattern = /-+BEGIN PRIVATE KEY-+[A-Za-z0-9+/\n=]*-+END PRIVATE KEY-+/m;
|
||||
if (!pattern.test(private_key)) {
|
||||
oauthErrors += "Private key must be in PEM format<BR/>";
|
||||
}
|
||||
}
|
||||
if (cert != undefined) {
|
||||
var pattern = /-+BEGIN CERTIFICATE-+[A-Za-z0-9+/\n=]*-+END CERTIFICATE-+/m;
|
||||
if (!pattern.test(cert)) {
|
||||
oauthErrors += "Certificate must be in PEM format<BR/>";
|
||||
}
|
||||
}
|
||||
if ($('#oauth.panel').length) {
|
||||
if (!$('input[name="oauth.client-id"]').val()) {
|
||||
oauthErrors += "OAuth requires a client Id.<BR/>";
|
||||
}
|
||||
if (!$('input[name="oauth.provider"]').val()) {
|
||||
oauthErrors += "OAuth requires a provider.<BR/>";
|
||||
}
|
||||
if (!$('input[name="oauth.hostname"]').val()) {
|
||||
oauthErrors += "OAuth requires a hostname.<BR/>";
|
||||
}
|
||||
if (!$('input[name="' + SSL_PRIVATE_KEY_PATH + '"]').val() && !$('input[name="' + SSL_PRIVATE_KEY_CONTENTS_NAME + '"]').val()) {
|
||||
oauthErrors += "OAuth requires an SSL Private Key.<BR/>";
|
||||
}
|
||||
if (!$('input[name="' + SSL_CERT_PATH + '"]').val() && !$('input[name="' + SSL_CERT_CONTENTS_NAME + '"]').val()) {
|
||||
oauthErrors += "OAuth requires an SSL Certificate.<BR/>";
|
||||
}
|
||||
if (!$("table[name='oauth.admin-users'] tr.value-row").length &&
|
||||
!$("table[name='oauth.admin-roles'] tr.value-row").length) {
|
||||
oauthErrors += "OAuth must have at least one admin user or admin role.<BR/>";
|
||||
}
|
||||
}
|
||||
if (oauthErrors) {
|
||||
bootbox.alert({ "message": oauthErrors, "title": "OAuth Configuration Error" });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
postSettings(formJSON);
|
||||
};
|
||||
|
||||
|
@ -1035,6 +1091,67 @@ $(document).ready(function(){
|
|||
});
|
||||
}
|
||||
|
||||
function setupSettingsOAuth(data) {
|
||||
// construct the HTML needed for the settings backup panel
|
||||
var html = "<div class='form-group undefined'>";
|
||||
html += "<label class='control-label'>SSL Private Key</label><BR/>";
|
||||
html += "<label id='key-path-label'class='control-label'>Path</label>";
|
||||
html += "<input id='" + SSL_PRIVATE_KEY_FILE_ID + "' type='file' accept='.key'/>";
|
||||
html += "<input id='" + SSL_PRIVATE_KEY_CONTENTS_ID + "' name='" + SSL_PRIVATE_KEY_CONTENTS_NAME + "' type='hidden'/>";
|
||||
html += "</div>";
|
||||
html += "<div class='form-group undefined'>";
|
||||
html += "<label class='control-label'>SSL Cert</label>";
|
||||
html += "<div id='cert-fingerprint'><b>Fingerprint:</b><span id='" + SSL_CERT_FINGERPRINT_SPAN_ID + "'>" + data.values.oauth["cert-fingerprint"] + "</span></div>";
|
||||
html += "<label id='cert-path-label' class='control-label'>Path</label>";
|
||||
html += "<input id='" + SSL_CERT_FILE_ID + "' type='file' accept='.cer,.crt'/>";
|
||||
html += "<input id='" + SSL_CERT_CONTENTS_ID + "' name='" + SSL_CERT_CONTENTS_NAME + "' type='hidden'/>";
|
||||
html += "</div>";
|
||||
|
||||
$('#oauth-advanced').append(html);
|
||||
|
||||
$('#key-path-label').after($('[data-keypath="' + SSL_PRIVATE_KEY_PATH + '"]'));
|
||||
$('#cert-path-label').after($('[data-keypath="' + SSL_CERT_PATH + '"]'));
|
||||
$('[name="' + SSL_PRIVATE_KEY_PATH + '"]').val(data.values.oauth.key);
|
||||
$('[name="' + SSL_CERT_PATH + '"]').val(data.values.oauth.cert);
|
||||
|
||||
$('body').on('change input propertychange', '#' + SSL_PRIVATE_KEY_FILE_ID, function(e){
|
||||
var f = e.target.files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
$('#' + SSL_PRIVATE_KEY_CONTENTS_ID).val(reader.result);
|
||||
$('#' + SSL_PRIVATE_KEY_CONTENTS_ID).attr('data-changed', true);
|
||||
$('[name="' + SSL_PRIVATE_KEY_PATH + '"]').val('');
|
||||
badgeForDifferences($('#' + SSL_PRIVATE_KEY_CONTENTS_ID));
|
||||
}
|
||||
reader.readAsText(f);
|
||||
});
|
||||
$('body').on('change input propertychange', '#' + SSL_CERT_FILE_ID, function(e){
|
||||
var f = e.target.files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
$('#' + SSL_CERT_CONTENTS_ID).val(reader.result);
|
||||
$('#' + SSL_CERT_CONTENTS_ID).attr('data-changed', true);
|
||||
$('[name="' + SSL_CERT_PATH + '"]').val('');
|
||||
$('#' + SSL_CERT_FINGERPRINT_SPAN_ID).text('');
|
||||
badgeForDifferences($('#' + SSL_CERT_CONTENTS_ID));
|
||||
}
|
||||
reader.readAsText(f);
|
||||
});
|
||||
|
||||
$('body').on('change input propertychange', '[name="' + SSL_PRIVATE_KEY_PATH + '"]', function(e){
|
||||
$('#' + SSL_PRIVATE_KEY_FILE_ID).val('');
|
||||
$('#' + SSL_PRIVATE_KEY_CONTENTS_ID).val('');
|
||||
badgeForDifferences($('[name="' + SSL_PRIVATE_KEY_PATH + '"]').attr('data-changed', true));
|
||||
});
|
||||
|
||||
$('body').on('change input propertychange', '[name="' + SSL_CERT_PATH + '"]', function(e){
|
||||
$('#' + SSL_CERT_FILE_ID).val('');
|
||||
$('#' + SSL_CERT_CONTENTS_ID).val('');
|
||||
$('#' + SSL_CERT_FINGERPRINT_SPAN_ID).text('');
|
||||
badgeForDifferences($('[name="' + SSL_CERT_PATH + '"]').attr('data-changed', true));
|
||||
});
|
||||
}
|
||||
|
||||
var RESTORE_SETTINGS_UPLOAD_ID = 'restore-settings-button';
|
||||
var RESTORE_SETTINGS_FILE_ID = 'restore-settings-file';
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <AccountManager.h>
|
||||
#include <AssetClient.h>
|
||||
#include <BuildInfo.h>
|
||||
#include <CrashAnnotations.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <HifiConfigVariantMap.h>
|
||||
#include <HTTPConnection.h>
|
||||
|
@ -174,6 +175,9 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
|
||||
LogUtils::init();
|
||||
|
||||
LogHandler::getInstance().moveToThread(thread());
|
||||
LogHandler::getInstance().setupRepeatedMessageFlusher();
|
||||
|
||||
qDebug() << "Setting up domain-server";
|
||||
qDebug() << "[VERSION] Build sequence:" << qPrintable(applicationVersion());
|
||||
qDebug() << "[VERSION] MODIFIED_ORGANIZATION:" << BuildInfo::MODIFIED_ORGANIZATION;
|
||||
|
@ -182,6 +186,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
qDebug() << "[VERSION] BUILD_GLOBAL_SERVICES:" << BuildInfo::BUILD_GLOBAL_SERVICES;
|
||||
qDebug() << "[VERSION] We will be using this name to find ICE servers:" << _iceServerAddr;
|
||||
|
||||
connect(this, &QCoreApplication::aboutToQuit, this, &DomainServer::aboutToQuit);
|
||||
|
||||
// make sure we have a fresh AccountManager instance
|
||||
// (need this since domain-server can restart itself and maintain static variables)
|
||||
|
@ -226,9 +231,10 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
|
||||
setupGroupCacheRefresh();
|
||||
|
||||
// if we were given a certificate/private key or oauth credentials they must succeed
|
||||
if (!(optionallyReadX509KeyAndCertificate() && optionallySetupOAuth())) {
|
||||
return;
|
||||
optionallySetupOAuth();
|
||||
|
||||
if (_oauthEnable) {
|
||||
_oauthEnable = optionallyReadX509KeyAndCertificate();
|
||||
}
|
||||
|
||||
_settingsManager.apiRefreshGroupInformation();
|
||||
|
@ -319,7 +325,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
|
||||
connect(_contentManager.get(), &DomainContentBackupManager::recoveryCompleted, this, &DomainServer::restart);
|
||||
|
||||
static const int NODE_PING_MONITOR_INTERVAL_MSECS = 1 * MSECS_PER_SECOND;
|
||||
static const int NODE_PING_MONITOR_INTERVAL_MSECS = 1 * MSECS_PER_SECOND;
|
||||
_nodePingMonitorTimer = new QTimer{ this };
|
||||
connect(_nodePingMonitorTimer, &QTimer::timeout, this, &DomainServer::nodePingMonitor);
|
||||
_nodePingMonitorTimer->start(NODE_PING_MONITOR_INTERVAL_MSECS);
|
||||
|
@ -428,6 +434,10 @@ DomainServer::~DomainServer() {
|
|||
DependencyManager::destroy<LimitedNodeList>();
|
||||
}
|
||||
|
||||
void DomainServer::aboutToQuit() {
|
||||
crash::annotations::setShutdownState(true);
|
||||
}
|
||||
|
||||
void DomainServer::queuedQuit(QString quitMessage, int exitCode) {
|
||||
if (!quitMessage.isEmpty()) {
|
||||
qWarning() << qPrintable(quitMessage);
|
||||
|
@ -447,8 +457,9 @@ QUuid DomainServer::getID() {
|
|||
}
|
||||
|
||||
bool DomainServer::optionallyReadX509KeyAndCertificate() {
|
||||
const QString X509_CERTIFICATE_OPTION = "cert";
|
||||
const QString X509_PRIVATE_KEY_OPTION = "key";
|
||||
const QString X509_CERTIFICATE_OPTION = "oauth.cert";
|
||||
const QString X509_PRIVATE_KEY_OPTION = "oauth.key";
|
||||
const QString X509_PRIVATE_KEY_PASSPHRASE_OPTION = "oauth.key-passphrase";
|
||||
const QString X509_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE";
|
||||
|
||||
QString certPath = _settingsManager.valueForKeyPath(X509_CERTIFICATE_OPTION).toString();
|
||||
|
@ -459,7 +470,12 @@ bool DomainServer::optionallyReadX509KeyAndCertificate() {
|
|||
// this is used for Oauth callbacks when authorizing users against a data server
|
||||
// let's make sure we can load the key and certificate
|
||||
|
||||
QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV);
|
||||
QString keyPassphraseEnv = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV);
|
||||
QString keyPassphraseString = _settingsManager.valueForKeyPath(X509_PRIVATE_KEY_PASSPHRASE_OPTION).toString();
|
||||
|
||||
if (!keyPassphraseEnv.isEmpty()) {
|
||||
keyPassphraseString = keyPassphraseEnv;
|
||||
}
|
||||
|
||||
qDebug() << "Reading certificate file at" << certPath << "for HTTPS.";
|
||||
qDebug() << "Reading key file at" << keyPath << "for HTTPS.";
|
||||
|
@ -473,16 +489,15 @@ bool DomainServer::optionallyReadX509KeyAndCertificate() {
|
|||
QSslCertificate sslCertificate(&certFile);
|
||||
QSslKey privateKey(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, keyPassphraseString.toUtf8());
|
||||
|
||||
if (privateKey.isNull()) {
|
||||
qCritical() << "SSL Private Key Not Loading. Bad password or key format?";
|
||||
}
|
||||
|
||||
_httpsManager.reset(new HTTPSManager(QHostAddress::AnyIPv4, DOMAIN_SERVER_HTTPS_PORT, sslCertificate, privateKey, QString(), this));
|
||||
|
||||
qDebug() << "TCP server listening for HTTPS connections on" << DOMAIN_SERVER_HTTPS_PORT;
|
||||
|
||||
} else if (!certPath.isEmpty() || !keyPath.isEmpty()) {
|
||||
static const QString MISSING_CERT_ERROR_MSG = "Missing certificate or private key. domain-server will now quit.";
|
||||
static const int MISSING_CERT_ERROR_CODE = 3;
|
||||
|
||||
QMetaObject::invokeMethod(this, "queuedQuit", Qt::QueuedConnection,
|
||||
Q_ARG(QString, MISSING_CERT_ERROR_MSG), Q_ARG(int, MISSING_CERT_ERROR_CODE));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -490,10 +505,12 @@ bool DomainServer::optionallyReadX509KeyAndCertificate() {
|
|||
}
|
||||
|
||||
bool DomainServer::optionallySetupOAuth() {
|
||||
const QString OAUTH_PROVIDER_URL_OPTION = "oauth-provider";
|
||||
const QString OAUTH_CLIENT_ID_OPTION = "oauth-client-id";
|
||||
const QString OAUTH_ENABLE_OPTION = "oauth.enable";
|
||||
const QString OAUTH_PROVIDER_URL_OPTION = "oauth.provider";
|
||||
const QString OAUTH_CLIENT_ID_OPTION = "oauth.client-id";
|
||||
const QString OAUTH_CLIENT_SECRET_ENV = "DOMAIN_SERVER_CLIENT_SECRET";
|
||||
const QString REDIRECT_HOSTNAME_OPTION = "hostname";
|
||||
const QString OAUTH_CLIENT_SECRET_OPTION = "oauth.client-secret";
|
||||
const QString REDIRECT_HOSTNAME_OPTION = "oauth.hostname";
|
||||
|
||||
_oauthProviderURL = QUrl(_settingsManager.valueForKeyPath(OAUTH_PROVIDER_URL_OPTION).toString());
|
||||
|
||||
|
@ -502,22 +519,24 @@ bool DomainServer::optionallySetupOAuth() {
|
|||
_oauthProviderURL = NetworkingConstants::METAVERSE_SERVER_URL();
|
||||
}
|
||||
|
||||
_oauthClientSecret = QProcessEnvironment::systemEnvironment().value(OAUTH_CLIENT_SECRET_ENV);
|
||||
if (_oauthClientSecret.isEmpty()) {
|
||||
_oauthClientSecret = _settingsManager.valueForKeyPath(OAUTH_CLIENT_SECRET_OPTION).toString();
|
||||
}
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
accountManager->setAuthURL(_oauthProviderURL);
|
||||
|
||||
_oauthClientID = _settingsManager.valueForKeyPath(OAUTH_CLIENT_ID_OPTION).toString();
|
||||
_oauthClientSecret = QProcessEnvironment::systemEnvironment().value(OAUTH_CLIENT_SECRET_ENV);
|
||||
_hostname = _settingsManager.valueForKeyPath(REDIRECT_HOSTNAME_OPTION).toString();
|
||||
|
||||
if (!_oauthClientID.isEmpty()) {
|
||||
_oauthEnable = _settingsManager.valueForKeyPath(OAUTH_ENABLE_OPTION).toBool();
|
||||
|
||||
if (_oauthEnable) {
|
||||
if (_oauthProviderURL.isEmpty()
|
||||
|| _hostname.isEmpty()
|
||||
|| _oauthClientID.isEmpty()
|
||||
|| _oauthClientSecret.isEmpty()) {
|
||||
static const QString MISSING_OAUTH_INFO_MSG = "Missing OAuth provider URL, hostname, client ID, or client secret. domain-server will now quit.";
|
||||
static const int MISSING_OAUTH_INFO_ERROR_CODE = 4;
|
||||
QMetaObject::invokeMethod(this, "queuedQuit", Qt::QueuedConnection,
|
||||
Q_ARG(QString, MISSING_OAUTH_INFO_MSG), Q_ARG(int, MISSING_OAUTH_INFO_ERROR_CODE));
|
||||
_oauthEnable = false;
|
||||
return false;
|
||||
} else {
|
||||
qDebug() << "OAuth will be used to identify clients using provider at" << _oauthProviderURL.toString();
|
||||
|
@ -1746,8 +1765,8 @@ void DomainServer::nodePingMonitor() {
|
|||
}
|
||||
|
||||
void DomainServer::processOctreeDataPersistMessage(QSharedPointer<ReceivedMessage> message) {
|
||||
qDebug() << "Received octree data persist message";
|
||||
auto data = message->readAll();
|
||||
qDebug() << "Received octree data persist message" << (data.size() / 1000) << "kbytes.";
|
||||
auto filePath = getEntitiesFilePath();
|
||||
|
||||
QDir dir(getEntitiesDirPath());
|
||||
|
@ -1759,12 +1778,16 @@ void DomainServer::processOctreeDataPersistMessage(QSharedPointer<ReceivedMessag
|
|||
QFile f(filePath);
|
||||
if (f.open(QIODevice::WriteOnly)) {
|
||||
f.write(data);
|
||||
#ifdef EXPENSIVE_NETWORK_DIAGNOSTICS
|
||||
// These diagnostics take take more than 200ms (depending on content size),
|
||||
// causing Socket::readPendingDatagrams to overrun its timebox.
|
||||
OctreeUtils::RawEntityData entityData;
|
||||
if (entityData.readOctreeDataInfoFromData(data)) {
|
||||
qCDebug(domain_server) << "Wrote new entities file" << entityData.id << entityData.dataVersion;
|
||||
} else {
|
||||
qCDebug(domain_server) << "Failed to read new octree data info";
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
qCDebug(domain_server) << "Failed to write new entities file:" << filePath;
|
||||
}
|
||||
|
@ -2689,8 +2712,8 @@ void DomainServer::profileRequestFinished() {
|
|||
std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* connection) {
|
||||
|
||||
static const QByteArray HTTP_COOKIE_HEADER_KEY = "Cookie";
|
||||
static const QString ADMIN_USERS_CONFIG_KEY = "admin-users";
|
||||
static const QString ADMIN_ROLES_CONFIG_KEY = "admin-roles";
|
||||
static const QString ADMIN_USERS_CONFIG_KEY = "oauth.admin-users";
|
||||
static const QString ADMIN_ROLES_CONFIG_KEY = "oauth.admin-roles";
|
||||
static const QString BASIC_AUTH_USERNAME_KEY_PATH = "security.http_username";
|
||||
static const QString BASIC_AUTH_PASSWORD_KEY_PATH = "security.http_password";
|
||||
const QString COOKIE_UUID_REGEX_STRING = HIFI_SESSION_COOKIE_KEY + "=([\\d\\w-]+)($|;)";
|
||||
|
@ -2700,8 +2723,7 @@ std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* c
|
|||
QVariant adminUsersVariant = _settingsManager.valueForKeyPath(ADMIN_USERS_CONFIG_KEY);
|
||||
QVariant adminRolesVariant = _settingsManager.valueForKeyPath(ADMIN_ROLES_CONFIG_KEY);
|
||||
|
||||
if (!_oauthProviderURL.isEmpty()
|
||||
&& (adminUsersVariant.isValid() || adminRolesVariant.isValid())) {
|
||||
if (_oauthEnable) {
|
||||
QString cookieString = connection->requestHeader(HTTP_COOKIE_HEADER_KEY);
|
||||
|
||||
QRegExp cookieUUIDRegex(COOKIE_UUID_REGEX_STRING);
|
||||
|
|
|
@ -136,6 +136,8 @@ private slots:
|
|||
void tokenGrantFinished();
|
||||
void profileRequestFinished();
|
||||
|
||||
void aboutToQuit();
|
||||
|
||||
signals:
|
||||
void iceServerChanged();
|
||||
void userConnected();
|
||||
|
@ -236,6 +238,7 @@ private:
|
|||
|
||||
bool _isUsingDTLS { false };
|
||||
|
||||
bool _oauthEnable { false };
|
||||
QUrl _oauthProviderURL;
|
||||
QString _oauthClientID;
|
||||
QString _oauthClientSecret;
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
#include <QtCore/QThread>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QUrlQuery>
|
||||
#include <QtNetwork/QSslKey>
|
||||
#include <QSaveFile>
|
||||
#include <QPair>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <Assignment.h>
|
||||
|
@ -46,10 +48,14 @@ const QString DESCRIPTION_SETTINGS_KEY = "settings";
|
|||
const QString SETTING_DEFAULT_KEY = "default";
|
||||
const QString DESCRIPTION_NAME_KEY = "name";
|
||||
const QString DESCRIPTION_GROUP_LABEL_KEY = "label";
|
||||
const QString DESCRIPTION_GROUP_SHOW_ON_ENABLE_KEY = "show_on_enable";
|
||||
const QString DESCRIPTION_ENABLE_KEY = "enable";
|
||||
const QString DESCRIPTION_BACKUP_FLAG_KEY = "backup";
|
||||
const QString SETTING_DESCRIPTION_TYPE_KEY = "type";
|
||||
const QString DESCRIPTION_COLUMNS_KEY = "columns";
|
||||
const QString CONTENT_SETTING_FLAG_KEY = "content_setting";
|
||||
static const QString SPLIT_MENU_GROUPS_DOMAIN_SETTINGS_KEY = "domain_settings";
|
||||
static const QString SPLIT_MENU_GROUPS_CONTENT_SETTINGS_KEY = "content_settings";
|
||||
|
||||
const QString SETTINGS_VIEWPOINT_KEY = "viewpoint";
|
||||
|
||||
|
@ -136,6 +142,10 @@ void DomainServerSettingsManager::splitSettingsDescription() {
|
|||
|
||||
settingsDropdownGroup[DESCRIPTION_GROUP_LABEL_KEY] = groupObject[DESCRIPTION_GROUP_LABEL_KEY];
|
||||
|
||||
if (groupObject.contains(DESCRIPTION_GROUP_SHOW_ON_ENABLE_KEY)) {
|
||||
settingsDropdownGroup[DESCRIPTION_GROUP_SHOW_ON_ENABLE_KEY] = groupObject[DESCRIPTION_GROUP_SHOW_ON_ENABLE_KEY];
|
||||
}
|
||||
|
||||
static const QString DESCRIPTION_GROUP_HTML_ID_KEY = "html_id";
|
||||
if (groupObject.contains(DESCRIPTION_GROUP_HTML_ID_KEY)) {
|
||||
settingsDropdownGroup[DESCRIPTION_GROUP_HTML_ID_KEY] = groupObject[DESCRIPTION_GROUP_HTML_ID_KEY];
|
||||
|
@ -170,9 +180,6 @@ void DomainServerSettingsManager::splitSettingsDescription() {
|
|||
|
||||
// populate the settings menu groups with what we've collected
|
||||
|
||||
static const QString SPLIT_MENU_GROUPS_DOMAIN_SETTINGS_KEY = "domain_settings";
|
||||
static const QString SPLIT_MENU_GROUPS_CONTENT_SETTINGS_KEY = "content_settings";
|
||||
|
||||
_settingsMenuGroups[SPLIT_MENU_GROUPS_DOMAIN_SETTINGS_KEY] = domainSettingsMenuGroups;
|
||||
_settingsMenuGroups[SPLIT_MENU_GROUPS_CONTENT_SETTINGS_KEY] = contentSettingsMenuGroups;
|
||||
}
|
||||
|
@ -448,6 +455,77 @@ void DomainServerSettingsManager::setupConfigMap(const QString& userConfigFilena
|
|||
packPermissions();
|
||||
}
|
||||
|
||||
if (oldVersion < 2.4) {
|
||||
// migrate oauth settings to their own group
|
||||
const QString ADMIN_USERS = "admin-users";
|
||||
const QString OAUTH_ADMIN_USERS = "oauth.admin-users";
|
||||
const QString OAUTH_CLIENT_ID = "oauth.client-id";
|
||||
const QString ALT_ADMIN_USERS = "admin.users";
|
||||
const QString ADMIN_ROLES = "admin-roles";
|
||||
const QString OAUTH_ADMIN_ROLES = "oauth.admin-roles";
|
||||
const QString OAUTH_ENABLE = "oauth.enable";
|
||||
|
||||
QVector<QPair<const char*, const char*> > conversionMap = {
|
||||
{"key", "oauth.key"},
|
||||
{"cert", "oauth.cert"},
|
||||
{"hostname", "oauth.hostname"},
|
||||
{"oauth-client-id", "oauth.client-id"},
|
||||
{"oauth-provider", "oauth.provider"}
|
||||
};
|
||||
|
||||
for (auto & conversion : conversionMap) {
|
||||
QVariant* prevValue = _configMap.valueForKeyPath(conversion.first);
|
||||
if (prevValue) {
|
||||
auto newValue = _configMap.valueForKeyPath(conversion.second, true);
|
||||
*newValue = *prevValue;
|
||||
}
|
||||
}
|
||||
|
||||
QVariant* client_id = _configMap.valueForKeyPath(OAUTH_CLIENT_ID);
|
||||
if (client_id) {
|
||||
QVariant* oauthEnable = _configMap.valueForKeyPath(OAUTH_ENABLE, true);
|
||||
|
||||
*oauthEnable = QVariant(true);
|
||||
}
|
||||
|
||||
QVariant* oldAdminUsers = _configMap.valueForKeyPath(ADMIN_USERS);
|
||||
QVariant* newAdminUsers = _configMap.valueForKeyPath(OAUTH_ADMIN_USERS, true);
|
||||
QVariantList adminUsers(newAdminUsers->toList());
|
||||
if (oldAdminUsers) {
|
||||
QStringList adminUsersList = oldAdminUsers->toStringList();
|
||||
for (auto & user : adminUsersList) {
|
||||
if (!adminUsers.contains(user)) {
|
||||
adminUsers.append(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
QVariant* altAdminUsers = _configMap.valueForKeyPath(ALT_ADMIN_USERS);
|
||||
if (altAdminUsers) {
|
||||
QStringList adminUsersList = altAdminUsers->toStringList();
|
||||
for (auto & user : adminUsersList) {
|
||||
if (!adminUsers.contains(user)) {
|
||||
adminUsers.append(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*newAdminUsers = adminUsers;
|
||||
|
||||
QVariant* oldAdminRoles = _configMap.valueForKeyPath(ADMIN_ROLES);
|
||||
QVariant* newAdminRoles = _configMap.valueForKeyPath(OAUTH_ADMIN_ROLES, true);
|
||||
QVariantList adminRoles(newAdminRoles->toList());
|
||||
if (oldAdminRoles) {
|
||||
QStringList adminRoleList = oldAdminRoles->toStringList();
|
||||
for (auto & role : adminRoleList) {
|
||||
if (!adminRoles.contains(role)) {
|
||||
adminRoles.append(role);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*newAdminRoles = adminRoles;
|
||||
}
|
||||
|
||||
|
||||
// write the current description version to our settings
|
||||
*versionVariant = _descriptionVersion;
|
||||
|
@ -1185,7 +1263,24 @@ bool DomainServerSettingsManager::handleAuthenticatedHTTPRequest(HTTPConnection
|
|||
|
||||
return true;
|
||||
} else if (url.path() == SETTINGS_MENU_GROUPS_PATH) {
|
||||
connection->respond(HTTPConnection::StatusCode200, QJsonDocument(_settingsMenuGroups).toJson(), "application/json");
|
||||
|
||||
QJsonObject settings;
|
||||
for (auto & key : _settingsMenuGroups.keys()) {
|
||||
const QJsonArray& settingGroups = _settingsMenuGroups[key].toArray();
|
||||
QJsonArray groups;
|
||||
foreach (const QJsonValue& group, settingGroups) {
|
||||
QJsonObject groupObject = group.toObject();
|
||||
QVariant* enableKey = _configMap.valueForKeyPath(groupObject[DESCRIPTION_NAME_KEY].toString() + "." + DESCRIPTION_ENABLE_KEY);
|
||||
|
||||
if (!groupObject.contains(DESCRIPTION_GROUP_SHOW_ON_ENABLE_KEY)
|
||||
|| (groupObject[DESCRIPTION_GROUP_SHOW_ON_ENABLE_KEY].toBool() && enableKey && enableKey->toBool() )) {
|
||||
groups.append(groupObject);
|
||||
}
|
||||
}
|
||||
settings[key] = groups;
|
||||
}
|
||||
|
||||
connection->respond(HTTPConnection::StatusCode200, QJsonDocument(settings).toJson(), "application/json");
|
||||
|
||||
return true;
|
||||
} else if (url.path() == SETTINGS_BACKUP_PATH) {
|
||||
|
@ -1446,6 +1541,28 @@ QJsonObject DomainServerSettingsManager::settingsResponseObjectForType(const QSt
|
|||
}
|
||||
}
|
||||
|
||||
// add 'derived' values used primarily for UI
|
||||
|
||||
const QString X509_CERTIFICATE_OPTION = "oauth.cert";
|
||||
|
||||
QString certPath = valueForKeyPath(X509_CERTIFICATE_OPTION).toString();
|
||||
if (!certPath.isEmpty()) {
|
||||
// the user wants to use the following cert and key for HTTPS
|
||||
// this is used for Oauth callbacks when authorizing users against a data server
|
||||
// let's make sure we can load the key and certificate
|
||||
|
||||
qDebug() << "Reading certificate file at" << certPath << "for HTTPS.";
|
||||
|
||||
QFile certFile(certPath);
|
||||
certFile.open(QIODevice::ReadOnly);
|
||||
|
||||
QSslCertificate sslCertificate(&certFile);
|
||||
QString digest = sslCertificate.digest().toHex(':');
|
||||
auto groupObject = responseObject["oauth"].toObject();
|
||||
groupObject["cert-fingerprint"] = digest;
|
||||
responseObject["oauth"] = groupObject;
|
||||
}
|
||||
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
|
@ -1551,23 +1668,65 @@ QJsonObject DomainServerSettingsManager::settingDescriptionFromGroup(const QJson
|
|||
return QJsonObject();
|
||||
}
|
||||
|
||||
bool DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject,
|
||||
bool DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedSettingsObject,
|
||||
SettingsType settingsType) {
|
||||
|
||||
// take a write lock since we're about to overwrite settings in the config map
|
||||
QWriteLocker locker(&_settingsLock);
|
||||
|
||||
QJsonObject postedObject(postedSettingsObject);
|
||||
|
||||
static const QString SECURITY_ROOT_KEY = "security";
|
||||
static const QString AC_SUBNET_WHITELIST_KEY = "ac_subnet_whitelist";
|
||||
static const QString BROADCASTING_KEY = "broadcasting";
|
||||
static const QString WIZARD_KEY = "wizard";
|
||||
static const QString DESCRIPTION_ROOT_KEY = "descriptors";
|
||||
static const QString OAUTH_ROOT_KEY = "oauth";
|
||||
static const QString OAUTH_KEY_CONTENTS = "key-contents";
|
||||
static const QString OAUTH_CERT_CONTENTS = "cert-contents";
|
||||
static const QString OAUTH_CERT_PATH = "cert";
|
||||
static const QString OAUTH_KEY_PASSPHRASE = "key-passphrase";
|
||||
static const QString OAUTH_KEY_PATH = "key";
|
||||
|
||||
auto& settingsVariant = _configMap.getConfig();
|
||||
bool needRestart = false;
|
||||
|
||||
auto& filteredDescriptionArray = settingsType == DomainSettings ? _domainSettingsDescription : _contentSettingsDescription;
|
||||
|
||||
auto oauthObject = postedObject[OAUTH_ROOT_KEY].toObject();
|
||||
if (oauthObject.contains(OAUTH_CERT_CONTENTS)) {
|
||||
QSslCertificate cert(oauthObject[OAUTH_CERT_CONTENTS].toString().toUtf8());
|
||||
if (!cert.isNull()) {
|
||||
static const QString CERT_FILE_NAME = "certificate.crt";
|
||||
auto certPath = PathUtils::getAppDataFilePath(CERT_FILE_NAME);
|
||||
QFile file(certPath);
|
||||
if (file.open(QFile::WriteOnly)) {
|
||||
file.write(cert.toPem());
|
||||
file.close();
|
||||
}
|
||||
oauthObject[OAUTH_CERT_PATH] = certPath;
|
||||
}
|
||||
oauthObject.remove(OAUTH_CERT_CONTENTS);
|
||||
}
|
||||
if (oauthObject.contains(OAUTH_KEY_CONTENTS)) {
|
||||
QString keyPassphraseString = oauthObject[OAUTH_KEY_PASSPHRASE].toString();
|
||||
QSslKey key(oauthObject[OAUTH_KEY_CONTENTS].toString().toUtf8(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, keyPassphraseString.toUtf8());
|
||||
if (!key.isNull()) {
|
||||
static const QString KEY_FILE_NAME = "certificate.key";
|
||||
auto keyPath = PathUtils::getAppDataFilePath(KEY_FILE_NAME);
|
||||
QFile file(keyPath);
|
||||
if (file.open(QFile::WriteOnly)) {
|
||||
file.write(key.toPem());
|
||||
file.close();
|
||||
file.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
|
||||
}
|
||||
oauthObject[OAUTH_KEY_PATH] = keyPath;
|
||||
}
|
||||
oauthObject.remove(OAUTH_KEY_CONTENTS);
|
||||
}
|
||||
|
||||
postedObject[OAUTH_ROOT_KEY] = oauthObject;
|
||||
|
||||
// Iterate on the setting groups
|
||||
foreach(const QString& rootKey, postedObject.keys()) {
|
||||
const QJsonValue& rootValue = postedObject[rootKey];
|
||||
|
@ -1752,6 +1911,8 @@ void DomainServerSettingsManager::persistToFile() {
|
|||
_configMap.loadConfig();
|
||||
return; // defend against future code
|
||||
}
|
||||
|
||||
QFile(settingsFilename).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner);
|
||||
}
|
||||
|
||||
QStringList DomainServerSettingsManager::getAllKnownGroupNames() {
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <BuildInfo.h>
|
||||
#include <CrashAnnotations.h>
|
||||
#include <LogHandler.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <BuildInfo.h>
|
||||
|
||||
#include "DomainServer.h"
|
||||
|
||||
|
@ -32,6 +33,7 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
// use a do-while to handle domain-server restart
|
||||
do {
|
||||
crash::annotations::setShutdownState(false);
|
||||
DomainServer domainServer(argc, argv);
|
||||
currentExitCode = domainServer.exec();
|
||||
} while (currentExitCode == DomainServer::EXIT_CODE_REBOOT);
|
||||
|
@ -39,4 +41,3 @@ int main(int argc, char* argv[]) {
|
|||
qInfo() << "Quitting.";
|
||||
return currentExitCode;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,12 +70,16 @@ file(GLOB_RECURSE INTERFACE_SRCS "src/*.cpp" "src/*.h")
|
|||
GroupSources("src")
|
||||
list(APPEND INTERFACE_SRCS ${RESOURCES_RCC})
|
||||
|
||||
# grab the Objective-C sources on OS X
|
||||
if (APPLE)
|
||||
file(GLOB_RECURSE INTERFACE_OBJCPP_SRCS "src/*.m" "src/*.mm")
|
||||
list(APPEND INTERFACE_SRCS ${INTERFACE_OBJCPP_SRCS})
|
||||
endif ()
|
||||
|
||||
# Add SpeechRecognizer if on Windows or OS X, otherwise remove
|
||||
if (WIN32)
|
||||
# Use .cpp and .h files as is.
|
||||
elseif (APPLE)
|
||||
file(GLOB INTERFACE_OBJCPP_SRCS "src/SpeechRecognizer.mm")
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} ${INTERFACE_OBJCPP_SRCS})
|
||||
get_filename_component(SPEECHRECOGNIZER_CPP "src/SpeechRecognizer.cpp" ABSOLUTE)
|
||||
list(REMOVE_ITEM INTERFACE_SRCS ${SPEECHRECOGNIZER_CPP})
|
||||
else ()
|
||||
|
@ -117,6 +121,7 @@ if (APPLE)
|
|||
# configure CMake to use a custom Info.plist
|
||||
set_target_properties(${this_target} PROPERTIES MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in)
|
||||
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "High Fidelity")
|
||||
if (PRODUCTION_BUILD)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.interface)
|
||||
else ()
|
||||
|
@ -151,7 +156,7 @@ elseif (WIN32)
|
|||
set(CONFIGURE_ICON_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Icon.rc")
|
||||
configure_file("${HF_CMAKE_DIR}/templates/Icon.rc.in" ${CONFIGURE_ICON_RC_OUTPUT})
|
||||
|
||||
set(APP_FULL_NAME "High Fidelity Interface")
|
||||
set(APP_FULL_NAME "High Fidelity")
|
||||
set(CONFIGURE_VERSION_INFO_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc")
|
||||
configure_file("${HF_CMAKE_DIR}/templates/VersionInfo.rc.in" ${CONFIGURE_VERSION_INFO_RC_OUTPUT})
|
||||
|
||||
|
|
14
interface/external/iViewHMD/readme.txt
vendored
14
interface/external/iViewHMD/readme.txt
vendored
|
@ -1,14 +0,0 @@
|
|||
|
||||
Instructions for adding SMI HMD Eye Tracking to Interface on Windows
|
||||
David Rowe, 27 Jul 2015.
|
||||
|
||||
1. Download and install the SMI HMD Eye Tracking software from http://update.smivision.com/iViewNG-HMD.exe.
|
||||
|
||||
2. Copy the SDK folders (3rdParty, include, libs) from the SDK installation folder C:\Program Files (x86)\SMI\iViewNG-HMD\SDK
|
||||
into the interface/externals/iViewHMD folder. This readme.txt should be there as well.
|
||||
|
||||
You may optionally choose to copy the SDK folders to a location outside the repository (so you can re-use with different
|
||||
checkouts and different projects). If so, set the ENV variable "HIFI_LIB_DIR" to a directory containing a subfolder
|
||||
"iViewHMD" that contains the folders mentioned above.
|
||||
|
||||
3. Clear your build directory, run cmake and build, and you should be all set.
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 26 KiB |
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 26 KiB |
20
interface/interface.entitlements
Normal file
20
interface/interface.entitlements
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>high-fidelity.hifi</string>
|
||||
</array>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
interface/resources/avatar/animations/idle_aimoffsets.fbx
Normal file
BIN
interface/resources/avatar/animations/idle_aimoffsets.fbx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
interface/resources/avatar/animations/sitting_idle02.fbx
Normal file
BIN
interface/resources/avatar/animations/sitting_idle02.fbx
Normal file
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue