Merge branch 'master' into fix/cmdline-discovery

This commit is contained in:
Kalila 2021-07-15 22:21:47 -04:00 committed by GitHub
commit 35948d7467
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
179 changed files with 2546 additions and 1233 deletions

12
.github/stale.yml vendored
View file

@ -1,17 +1,11 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 120
daysUntilStale: 180
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 60
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
daysUntilClose: false
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had recent activity.
It will be closed if no further activity occurs.
Thank you for your contributions.
Hello! Is this still an issue?
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View file

@ -101,8 +101,8 @@ jobs:
working-directory: ${{runner.workspace}}
run: rm -rf ./*
- uses: actions/checkout@v1
with:
submodules: true
with:
submodules: false
fetch-depth: 1
- name: Install dependencies
if: startsWith(matrix.os, 'ubuntu')

View file

@ -25,6 +25,8 @@ env:
# WIN32 specific variables
PreferredToolArchitecture: X64
# Ensure XZ always runs with muticore support
XZ_OPT: -T0
jobs:
build:
@ -118,8 +120,8 @@ jobs:
working-directory: ${{runner.workspace}}
run: rm -rf ./*
- uses: actions/checkout@v1
with:
submodules: true
with:
submodules: false
fetch-depth: 1
- name: Install dependencies
shell: bash
@ -140,6 +142,24 @@ jobs:
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DVCPKG_BUILD_TYPE=release $CMAKE_EXTRA
- name: Compress cmake logs
if: always()
shell: bash
run: |
if [ "${{ matrix.os }}" == "macOS-latest" ]; then
TAR=gtar
else
TAR=tar
fi
find "$HOME/vircadia-files/vcpkg" -name '*log' -type f -print0 | $TAR --null --force-local -T - -c --xz -v -f "${{ runner.workspace }}/cmake-logs-${{ matrix.os }}-${{ github.event.number }}.tar.xz"
- name: Archive cmake logs
if: always()
uses: actions/upload-artifact@v2
with:
name: cmake-logs-${{ matrix.os }}-${{ github.event.number }}.tar.xz
path: ${{ runner.workspace }}/cmake-logs-${{ matrix.os }}-${{ github.event.number }}.tar.xz
if-no-files-found: error
- name: Build Application
if: matrix.build_type == 'full' || matrix.build_type == 'client'
working-directory: ${{runner.workspace}}/build
@ -231,4 +251,4 @@ jobs:
if [[ "${{ matrix.build_type }}" == "android" ]]; then
cd $GITHUB_WORKSPACE/android
fi
$PYTHON_EXEC "$GITHUB_WORKSPACE/tools/ci-scripts/upload_to_publish_server.py"
$PYTHON_EXEC "$GITHUB_WORKSPACE/tools/ci-scripts/upload_to_publish_server.py"

View file

@ -93,13 +93,16 @@ git checkout master
### Using a custom Qt build
Qt binaries are only provided for Ubuntu. In order to build on other distributions, a Qt5 install needs to be provided as follows:
Qt binaries are only provided for Ubuntu. In order to build on other distributions, a Qt5 install
needs to be provided by setting the `VIRCADIA_QT_PATH` environment variable to a directory containing
a Qt install.
* Set `VIRCADIA_USE_PREBUILT_QT=1`
* Set `VIRCADIA_USE_QT_VERSION` to the Qt version (defaults to `5.12.3`)
* Set `HIFI_QT_BASE=/path/to/qt`
### Using the system's Qt
Qt must be installed in `$HIFI_QT_BASE/$VIRCADIA_USE_QT_VERSION/qt5-install`.
The system's Qt can be used, if the development packages are installed, by setting the
`VIRCADIA_USE_SYSTEM_QT` environment variable. The minimum recommended version is Qt 5.15.2, which is
also the last version available in the Qt 5 branch. It is expected that Linux distributions will have
Qt 5.15.2 available for a long time.
### Compiling

View file

@ -57,7 +57,7 @@ MESSAGE(STATUS "GLES_OPTION: ${GLES_OPTION}")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros/TargetPython.cmake")
target_python()
if (WIN32 AND NOT HIFI_ANDROID)
if (WIN32 AND NOT HIFI_ANDROID AND NOT (CMAKE_GENERATOR STREQUAL "Ninja"))
# Force x64 toolset
set(CMAKE_GENERATOR_TOOLSET "host=x64" CACHE STRING "64-bit toolset" FORCE)
endif()
@ -77,7 +77,7 @@ endif()
if (HIFI_ANDROID)
execute_process(
COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_CURRENT_SOURCE_DIR}/prebuild.py --release-type ${RELEASE_TYPE} --android ${HIFI_ANDROID_APP} --build-root ${CMAKE_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} RESULTS_VARIABLE PREBUILD_RET
)
else()
set(VCPKG_BUILD_TYPE_PARAM "")
@ -86,7 +86,7 @@ else()
endif()
execute_process(
COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_CURRENT_SOURCE_DIR}/prebuild.py --release-type ${RELEASE_TYPE} --build-root ${CMAKE_BINARY_DIR} ${VCPKG_BUILD_TYPE_PARAM}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} RESULTS_VARIABLE PREBUILD_RET
)
# squelch the Policy CMP0074 warning without requiring an update to cmake 3.12.
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
@ -94,6 +94,9 @@ else()
endif()
endif()
if (PREBUILD_RET GREATER 0)
message(FATAL_ERROR "prebuild.py failed with error ${PREBUILD_RET}")
endif()
if(NOT EXISTS "${CMAKE_BINARY_DIR}/vcpkg.cmake")
message(FATAL_ERROR "vcpkg configuration missing.")
endif()
@ -101,11 +104,16 @@ include("${CMAKE_BINARY_DIR}/vcpkg.cmake")
if (HIFI_ANDROID)
set(QT_CMAKE_PREFIX_PATH "$ENV{HIFI_ANDROID_PRECOMPILED}/qt/lib/cmake")
else()
if(NOT EXISTS "${CMAKE_BINARY_DIR}/qt.cmake")
message(FATAL_ERROR "qt configuration missing.")
else()
if ("$ENV{VIRCADIA_USE_SYSTEM_QT}" STREQUAL "")
if(NOT EXISTS "${CMAKE_BINARY_DIR}/qt.cmake")
message(FATAL_ERROR "qt configuration missing.")
endif()
include("${CMAKE_BINARY_DIR}/qt.cmake")
message(STATUS "${CMAKE_BINARY_DIR}/qt.cmake included!")
else()
message(STATUS "System Qt in use, not including qt.cmake!")
endif()
include("${CMAKE_BINARY_DIR}/qt.cmake")
endif()
option(VCPKG_APPLOCAL_DEPS OFF)
@ -290,7 +298,10 @@ set_packaging_parameters()
# Locate the required Qt build on the filesystem
setup_qt()
list(APPEND CMAKE_PREFIX_PATH "${QT_CMAKE_PREFIX_PATH}")
if ("$ENV{VIRCADIA_USE_SYSTEM_QT}" STREQUAL "")
list(APPEND CMAKE_PREFIX_PATH "${QT_CMAKE_PREFIX_PATH}")
endif()
find_package( Threads )

View file

@ -72,3 +72,9 @@ Vircadia consists of many projects and codebases with its unifying structure's g
### Contribution
There are many contributors to Vircadia. Code writers, reviewers, testers, documentation writers, modelers, and general supporters of the project are all integral to its development and success towards its goals. Find out how you can [contribute](CONTRIBUTING.md)!
### [Supporters](https://github.com/sponsors/digisomni/)
| [Karol Suprynowicz - 74hc595](https://github.com/ksuprynowicz) |
| --- |
| <p align="center">[![ksuprynowicz](https://avatars.githubusercontent.com/u/11568651?s=64&v=4)](https://github.com/ksuprynowicz)</p>

View file

@ -142,7 +142,7 @@ void unpackAndroidAssets() {
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
throw std::runtime_error("Can't write date stamp");
}
QTextStream(&file) << "touch" << endl;
QTextStream(&file) << "touch" << Qt::endl;
file.close();
}
}

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 11/25/2013.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -83,7 +84,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
_assignmentServerHostname = assignmentServerHostname;
}
_assignmentServerSocket = HifiSockAddr(_assignmentServerHostname, assignmentServerPort, true);
_assignmentServerSocket = SockAddr(_assignmentServerHostname, assignmentServerPort, true);
if (_assignmentServerSocket.isNull()) {
qCCritical(assignment_client) << "PAGE: Couldn't resolve domain server address" << _assignmentServerHostname;
}
@ -118,7 +119,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
// did we get an assignment-client monitor port?
if (assignmentMonitorPort > 0) {
_assignmentClientMonitorSocket = HifiSockAddr(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME, assignmentMonitorPort);
_assignmentClientMonitorSocket = SockAddr(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME, assignmentMonitorPort);
_assignmentClientMonitorSocket.setObjectName("AssignmentClientMonitor");
qCDebug(assignment_client) << "Assignment-client monitor socket is" << _assignmentClientMonitorSocket;
@ -277,7 +278,7 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer<ReceivedMessa
}
void AssignmentClient::handleStopNodePacket(QSharedPointer<ReceivedMessage> message) {
const HifiSockAddr& senderSockAddr = message->getSenderSockAddr();
const SockAddr& senderSockAddr = message->getSenderSockAddr();
if (senderSockAddr.getAddress() == QHostAddress::LocalHost ||
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 11/25/2013.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -49,14 +50,14 @@ private:
QPointer<ThreadedAssignment> _currentAssignment;
bool _isAssigned { false };
QString _assignmentServerHostname;
HifiSockAddr _assignmentServerSocket;
SockAddr _assignmentServerSocket;
QTimer _requestTimer; // timer for requesting and assignment
QTimer _statsTimerACM; // timer for sending stats to assignment client monitor
QUuid _childAssignmentUUID = QUuid::createUuid();
bool _disableDomainPortAutoDiscovery { false };
protected:
HifiSockAddr _assignmentClientMonitorSocket;
SockAddr _assignmentClientMonitorSocket;
};
#endif // hifi_AssignmentClient_h

View file

@ -337,7 +337,7 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer<ReceivedMes
auto nodeList = DependencyManager::get<NodeList>();
SharedNodePointer matchingNode = nodeList->nodeWithUUID(senderID);
const HifiSockAddr& senderSockAddr = message->getSenderSockAddr();
const SockAddr& senderSockAddr = message->getSenderSockAddr();
AssignmentClientChildData* childData = nullptr;

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 9/5/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -113,7 +114,7 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) :
});
}
SharedNodePointer addOrUpdateReplicatedNode(const QUuid& nodeID, const HifiSockAddr& senderSockAddr) {
SharedNodePointer addOrUpdateReplicatedNode(const QUuid& nodeID, const SockAddr& senderSockAddr) {
auto replicatedNode = DependencyManager::get<NodeList>()->addOrUpdateNode(nodeID, NodeType::Agent,
senderSockAddr,
senderSockAddr,
@ -976,7 +977,7 @@ void AvatarMixer::domainSettingsRequestComplete() {
start();
}
void AvatarMixer::handlePacketVersionMismatch(PacketType type, const HifiSockAddr& senderSockAddr, const QUuid& senderUUID) {
void AvatarMixer::handlePacketVersionMismatch(PacketType type, const SockAddr& senderSockAddr, const QUuid& senderUUID) {
// if this client is using packet versions we don't expect.
if ((type == PacketTypeEnum::Value::AvatarIdentity || type == PacketTypeEnum::Value::AvatarData) && !senderUUID.isNull()) {
// Echo an empty AvatarData packet back to that client.

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 9/5/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// The avatar mixer receives head, hand and positional data from all connected
// nodes, and broadcasts that data back to them, every BROADCAST_INTERVAL ms.
@ -63,7 +64,7 @@ private slots:
void handleReplicatedPacket(QSharedPointer<ReceivedMessage> message);
void handleReplicatedBulkAvatarPacket(QSharedPointer<ReceivedMessage> message);
void domainSettingsRequestComplete();
void handlePacketVersionMismatch(PacketType type, const HifiSockAddr& senderSockAddr, const QUuid& senderUUID);
void handlePacketVersionMismatch(PacketType type, const SockAddr& senderSockAddr, const QUuid& senderUUID);
void handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
void start();

View file

@ -35,6 +35,25 @@ elseif (APPLE)
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
set(BIN_RELEASE_PATH "${SOURCE_DIR}/out/Release")
set(BIN_EXT "")
set(LIB_RELEASE_PATH "${SOURCE_DIR}/out/Release/lib")
set(LIB_DEBUG_PATH "${SOURCE_DIR}/out/Debug/lib")
set(LIB_PREFIX "lib")
set(LIB_EXT "a")
elseif (UNIX)
ExternalProject_Add(
${EXTERNAL_NAME}
URL "${EXTERNAL_BUILD_ASSETS}/dependencies/crashpad_linux_f1943fcb.tar.bz2"
URL_MD5 e0949e5988905471c63c399833879482
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
LOG_DOWNLOAD 1
)
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
set(BIN_RELEASE_PATH "${SOURCE_DIR}/out/Release")
set(BIN_EXT "")
set(LIB_RELEASE_PATH "${SOURCE_DIR}/out/Release/lib")
@ -43,8 +62,7 @@ elseif (APPLE)
set(LIB_EXT "a")
endif ()
if (WIN32 OR APPLE)
if (WIN32 OR APPLE OR UNIX)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE PATH "List of Crashpad include directories")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${LIB_RELEASE_PATH}/${LIB_PREFIX}crashpad_client.${LIB_EXT} CACHE FILEPATH "Path to Crashpad release library")

View file

@ -11,24 +11,29 @@
macro(add_crashpad)
set (USE_CRASHPAD TRUE)
message(STATUS "Checking crashpad config")
if ("$ENV{CMAKE_BACKTRACE_URL}" STREQUAL "")
message(STATUS "Checking crashpad config - CMAKE_BACKTRACE_URL is not set, disabled.")
set(USE_CRASHPAD FALSE)
else()
set(CMAKE_BACKTRACE_URL $ENV{CMAKE_BACKTRACE_URL})
endif()
if ("$ENV{CMAKE_BACKTRACE_TOKEN}" STREQUAL "")
message(STATUS "Checking crashpad config - CMAKE_BACKTRACE_TOKEN is not set, disabled.")
set(USE_CRASHPAD FALSE)
else()
set(CMAKE_BACKTRACE_TOKEN $ENV{CMAKE_BACKTRACE_TOKEN})
endif()
if ((WIN32 OR APPLE) AND USE_CRASHPAD)
if (USE_CRASHPAD)
message(STATUS "Checking crashpad config - enabled.")
get_property(CRASHPAD_CHECKED GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE)
if (NOT CRASHPAD_CHECKED)
add_dependency_external_projects(crashpad)
find_package(crashpad REQUIRED)
find_package(Crashpad REQUIRED)
set_property(GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE TRUE)
endif()
@ -38,7 +43,7 @@ macro(add_crashpad)
add_definitions(-DCMAKE_BACKTRACE_TOKEN=\"${CMAKE_BACKTRACE_TOKEN}\")
target_include_directories(${TARGET_NAME} PRIVATE ${CRASHPAD_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${CRASHPAD_LIBRARY} ${CRASHPAD_BASE_LIBRARY} ${CRASHPAD_UTIL_LIBRARY})
target_link_libraries(${TARGET_NAME} ${CRASHPAD_LIBRARY} ${CRASHPAD_UTIL_LIBRARY} ${CRASHPAD_BASE_LIBRARY})
if (WIN32)
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099")

View file

@ -5,6 +5,9 @@
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
# For understanding the execution flow followed by the Qt setup,
# please look at the comment on top of hifi_qt.py
function(get_sub_directories result curdir)
file(GLOB children RELATIVE ${curdir} ${curdir}/*)
set(dirlist "")
@ -25,6 +28,9 @@ function(calculate_qt5_version result _QT_DIR)
set(_QT_CORE_DIR "${_QT_DIR}/lib/QtCore.framework/Versions/5/Headers")
else()
set(_QT_CORE_DIR "${_QT_DIR}/include/QtCore")
if(NOT EXISTS "${_QT_CORE_DIR}")
set(_QT_CORE_DIR "${_QT_DIR}/include/qt5/QtCore")
endif()
endif()
if(NOT EXISTS "${_QT_CORE_DIR}")
message(FATAL_ERROR "Could not find 'include/QtCore' in '${_QT_DIR}'")
@ -45,49 +51,64 @@ endfunction()
# Sets the QT_CMAKE_PREFIX_PATH and QT_DIR variables
# Also enables CMAKE_AUTOMOC and CMAKE_AUTORCC
macro(setup_qt)
# if we are in a development build and QT_CMAKE_PREFIX_PATH is specified
# then use it,
# otherwise, use the vcpkg'ed version
if(NOT DEFINED QT_CMAKE_PREFIX_PATH)
message(FATAL_ERROR "QT_CMAKE_PREFIX_PATH should have been set by hifi_qt.py")
endif()
if (DEV_BUILD)
if (DEFINED ENV{QT_CMAKE_PREFIX_PATH})
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
endif()
endif()
if ($ENV{VIRCADIA_USE_SYSTEM_QT})
message(STATUS "Using system Qt")
else()
# if we are in a development build and QT_CMAKE_PREFIX_PATH is specified
# then use it,
# otherwise, use the vcpkg'ed version
if(NOT DEFINED QT_CMAKE_PREFIX_PATH)
# Note: This comes from qt.cmake generated by hifi_qt.py
# See the comment on top of hifi_qt.py for details.
message(FATAL_ERROR "QT_CMAKE_PREFIX_PATH should have been set by hifi_qt.py through qt.cmake")
endif()
if (DEV_BUILD)
if (DEFINED ENV{QT_CMAKE_PREFIX_PATH})
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
endif()
endif()
message("QT_CMAKE_PREFIX_PATH = " ${QT_CMAKE_PREFIX_PATH})
# figure out where the qt dir is
get_filename_component(QT_DIR "${QT_CMAKE_PREFIX_PATH}/../../" ABSOLUTE)
set(QT_VERSION "unknown")
calculate_qt5_version(QT_VERSION "${QT_DIR}")
if (QT_VERSION STREQUAL "unknown")
message(FATAL_ERROR "Could not determine QT_VERSION")
endif()
if(WIN32)
# windows shell does not like backslashes expanded on the command line,
# so convert all backslashes in the QT path to forward slashes
string(REPLACE \\ / QT_CMAKE_PREFIX_PATH ${QT_CMAKE_PREFIX_PATH})
string(REPLACE \\ / QT_DIR ${QT_DIR})
endif()
if(NOT EXISTS "${QT_CMAKE_PREFIX_PATH}/Qt5Core/Qt5CoreConfig.cmake")
message(FATAL_ERROR "Unable to locate Qt5CoreConfig.cmake in '${QT_CMAKE_PREFIX_PATH}'")
endif()
set(RCC_BINARY "${QT_DIR}/bin/rcc${CMAKE_EXECUTABLE_SUFFIX}")
if(NOT EXISTS "${RCC_BINARY}")
set(RCC_BINARY "${QT_DIR}/bin/rcc-qt5${CMAKE_EXECUTABLE_SUFFIX}")
endif()
if(NOT EXISTS "${RCC_BINARY}")
message(FATAL_ERROR "Unable to locate rcc. Last looked in '${RCC_BINARY}'")
endif()
message(STATUS "Using Qt build in : '${QT_DIR}' with version ${QT_VERSION}")
if (WIN32)
add_paths_to_fixup_libs("${QT_DIR}/bin")
endif ()
# figure out where the qt dir is
get_filename_component(QT_DIR "${QT_CMAKE_PREFIX_PATH}/../../" ABSOLUTE)
set(QT_VERSION "unknown")
calculate_qt5_version(QT_VERSION "${QT_DIR}")
if (QT_VERSION STREQUAL "unknown")
message(FATAL_ERROR "Could not determine QT_VERSION")
endif()
if(WIN32)
# windows shell does not like backslashes expanded on the command line,
# so convert all backslashes in the QT path to forward slashes
string(REPLACE \\ / QT_CMAKE_PREFIX_PATH ${QT_CMAKE_PREFIX_PATH})
string(REPLACE \\ / QT_DIR ${QT_DIR})
endif()
if(NOT EXISTS "${QT_CMAKE_PREFIX_PATH}/Qt5Core/Qt5CoreConfig.cmake")
message(FATAL_ERROR "Unable to locate Qt5CoreConfig.cmake in '${QT_CMAKE_PREFIX_PATH}'")
endif()
message(STATUS "Using Qt build in : '${QT_DIR}' with version ${QT_VERSION}")
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Instruct CMake to run rcc automatically when needed
set(CMAKE_AUTORCC ON)
if (WIN32)
add_paths_to_fixup_libs("${QT_DIR}/bin")
endif ()
endmacro()

View file

@ -38,4 +38,4 @@ select_library_configurations(CRASHPAD_BASE)
select_library_configurations(CRASHPAD_UTIL)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CRASHPAD DEFAULT_MSG CRASHPAD_INCLUDE_DIRS CRASHPAD_LIBRARY CRASHPAD_BASE_LIBRARY CRASHPAD_UTIL_LIBRARY)
find_package_handle_standard_args(Crashpad DEFAULT_MSG CRASHPAD_INCLUDE_DIRS CRASHPAD_LIBRARY CRASHPAD_BASE_LIBRARY CRASHPAD_UTIL_LIBRARY)

View file

@ -21,6 +21,6 @@ hifi_library_search_hints("GIFCREATOR")
find_path(GIFCREATOR_INCLUDE_DIRS "GifCreator/GifCreator.h" HINTS ${GIFCREATOR_SEARCH_DIRS})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GIFCREATOR DEFAULT_MSG GIFCREATOR_INCLUDE_DIRS)
find_package_handle_standard_args(GifCreator DEFAULT_MSG GIFCREATOR_INCLUDE_DIRS)
mark_as_advanced(GIFCREATOR_INCLUDE_DIRS GIFCREATOR_SEARCH_DIRS)

View file

@ -1,37 +0,0 @@
commit 8909ba06ea1893a6e028836fbade28fd115ee1cc
Author: Julian Groß <julian.g@posteo.de>
Date: Wed Feb 17 04:51:49 2021 +0100
Enable building on aarch64 according to https://github.com/castano/nvidia-texture-tools/pull/309 and https://github.com/castano/nvidia-texture-tools/pull/322
diff --git a/src/nvcore/Debug.cpp b/src/nvcore/Debug.cpp
index 9ab4525..e335f97 100644
--- a/src/nvcore/Debug.cpp
+++ b/src/nvcore/Debug.cpp
@@ -1008,6 +1008,13 @@ void debug::dumpInfo()
#endif
}
+static va_list getEmptyVAList(va_list list, ...)
+{
+ va_start(list, list);
+ va_end(list);
+ return list;
+}
+
/// Dump callstack using the specified handler.
void debug::dumpCallstack(MessageHandler *messageHandler, int callstackLevelsToSkip /*= 0*/)
{
@@ -1020,8 +1027,11 @@ void debug::dumpCallstack(MessageHandler *messageHandler, int callstackLevelsToS
Array<const char *> lines;
writeStackTrace(trace, size, callstackLevelsToSkip + 1, lines); // + 1 to skip the call to dumpCallstack
+ va_list empty;
+ empty = getEmptyVAList(empty);
+
for (uint i = 0; i < lines.count(); i++) {
- messageHandler->log(lines[i], NULL);
+ messageHandler->log(lines[i], empty);
delete lines[i];
}
}

View file

@ -1,25 +0,0 @@
From 84dc6af45b1176a2b82d089239665cb3dc1584de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julian=20Gro=C3=9F?= <firedefender1@googlemail.com>
Date: Wed, 23 Dec 2020 07:33:39 +0100
Subject: [PATCH] Hack: remove #include <sys/sysctl.h> to build on
linux-aarch64
---
src/nvthread/nvthread.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/nvthread/nvthread.cpp b/src/nvthread/nvthread.cpp
index 2b3abe6..cec9f4f 100644
--- a/src/nvthread/nvthread.cpp
+++ b/src/nvthread/nvthread.cpp
@@ -11,7 +11,6 @@
#include <unistd.h>
#elif NV_OS_UNIX
#include <sys/types.h>
-#include <sys/sysctl.h>
#include <unistd.h>
#elif NV_OS_DARWIN
#import <stdio.h>
--
2.17.1

View file

@ -10,18 +10,11 @@ include(vcpkg_common_functions)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO vircadia/nvidia-texture-tools
REF 330c4d56274a0f602a5c70596e2eb670a4ed56c2
SHA512 4c0bc2f369120d696cc27710b6d33086b27eef55f537ec66b9a5c8b1839bc2426c0413670b0f65be52c5d353468f0126dfe024be1f0690611d4d7e33ac530127
REF d8b7a98aeb177b5eddb76571183bbd2f95d54e6c
SHA512 ea15ffd19eb1e14c8ebd62f8d7de3df1ecf6c18a339025f4a0e13419717d510903fc126ec6d1bdfbb5a2f4525a922412b72318bc8dd55dd000481a3924fbfcd4
HEAD_REF master
)
if(VCPKG_TARGET_ARCHITECTURE STREQUAL arm64)
vcpkg_apply_patches(
SOURCE_PATH ${SOURCE_PATH}
PATCHES "${CMAKE_CURRENT_LIST_DIR}/0001-Build-on-aarch64.patch" "${CMAKE_CURRENT_LIST_DIR}/0002-Hack-remove-include-sysctl.h-to-build-on-linux-a.patch"
)
endif()
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS

View file

@ -1,6 +1,15 @@
include(vcpkg_common_functions)
file(READ "${VCPKG_ROOT_DIR}/_env/QT_CMAKE_PREFIX_PATH.txt" QT_CMAKE_PREFIX_PATH)
if(EXISTS "${VCPKG_ROOT_DIR}/_env/QT_CMAKE_PREFIX_PATH.txt")
# This environment var file only exists if we're overridding the default Qt location,
# which happens when using Qt from vcpkg, or using Qt from custom location
file(READ "${VCPKG_ROOT_DIR}/_env/QT_CMAKE_PREFIX_PATH.txt" QT_CMAKE_PREFIX_PATH)
set(QUAZIP_EXTRA_OPTS "-DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH}")
else()
# In the case of using system Qt, don't pass anything.
set(QUAZIP_EXTRA_OPTS "")
endif()
file(READ "${VCPKG_ROOT_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" EXTERNAL_BUILD_ASSETS)
vcpkg_download_distfile(
@ -19,7 +28,7 @@ vcpkg_extract_source_archive_ex(
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
PREFER_NINJA
OPTIONS -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DBUILD_WITH_QT4=OFF
OPTIONS -DCMAKE_POSITION_INDEPENDENT_CODE=ON ${QUAZIP_EXTRA_OPTS} -DBUILD_WITH_QT4=OFF
)
vcpkg_install_cmake()

View file

@ -24,7 +24,7 @@
<div class="row">
<div class="col-md-12">
<span class='step-description'>
<a target='_blank' href='https://docs.vircadia.dev/create-and-explore/start-working-in-your-sandbox/place-names'>Place names</a> are similar to web addresses. Users who want to visit your domain can
<a target='_blank' href='https://docs.vircadia.com/create-and-explore/start-working-in-your-sandbox/place-names'>Place names</a> are similar to web addresses. Users who want to visit your domain can
enter its Place Name in Vircadia's Interface. You can choose a Place Name for your domain.</br>
Your domain may also be reachable by <b>IP address</b>.
</span>
@ -196,8 +196,8 @@
<div class="row">
<div class="col-md-12">
<span class='step-description'>
Would you like use automatic threading for your server's avatars and audio?
If you are hosting this server on your local computer and it is not very powerful, then consider leaving this off because the server will use more resources if it is being utilized extensively, thereby slowing down your computer.
Would you like use automatic threading for your server's avatars and audio?
If you are hosting this server on your local computer and it is not very powerful, then consider leaving this off because the server will use more resources if it is being utilized extensively, thereby slowing down your computer.
If you are running this server on a powerful system and intend to have a large audience, then turn this setting on.
</span>
</div>

View file

@ -357,7 +357,7 @@ void DomainGatekeeper::updateNodePermissions() {
} else {
// at this point we don't have a sending socket for packets from this node - assume it is the active socket
// or the public socket if we haven't activated a socket for the node yet
HifiSockAddr connectingAddr = node->getActiveSocket() ? *node->getActiveSocket() : node->getPublicSocket();
SockAddr connectingAddr = node->getActiveSocket() ? *node->getActiveSocket() : node->getPublicSocket();
QString hardwareAddress;
QUuid machineFingerprint;
@ -651,7 +651,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
}
SharedNodePointer DomainGatekeeper::addVerifiedNodeFromConnectRequest(const NodeConnectionData& nodeConnection) {
HifiSockAddr discoveredSocket = nodeConnection.senderSockAddr;
SockAddr discoveredSocket = nodeConnection.senderSockAddr;
SharedNetworkPeer connectedPeer = _icePeers.value(nodeConnection.connectUUID);
if (connectedPeer && connectedPeer->getActiveSocket()) {
@ -690,7 +690,7 @@ void DomainGatekeeper::cleanupICEPeerForNode(const QUuid& nodeID) {
bool DomainGatekeeper::verifyUserSignature(const QString& username,
const QByteArray& usernameSignature,
const HifiSockAddr& senderSockAddr) {
const SockAddr& senderSockAddr) {
// it's possible this user can be allowed to connect, but we need to check their username signature
auto lowerUsername = username.toLower();
KeyFlagPair publicKeyPair = _userPublicKeys.value(lowerUsername);
@ -773,7 +773,7 @@ bool DomainGatekeeper::needToVerifyDomainUserIdentity(const QString& username, c
}
bool DomainGatekeeper::verifyDomainUserIdentity(const QString& username, const QString& accessToken,
const QString& refreshToken, const HifiSockAddr& senderSockAddr) {
const QString& refreshToken, const SockAddr& senderSockAddr) {
if (_verifiedDomainUserIdentities.contains(username)
&& _verifiedDomainUserIdentities.value(username) == QPair<QString, QString>(accessToken, refreshToken)) {
return true;
@ -871,7 +871,7 @@ void DomainGatekeeper::publicKeyJSONErrorCallback(QNetworkReply* requestReply) {
_inFlightPublicKeyRequests.remove(username);
}
void DomainGatekeeper::sendProtocolMismatchConnectionDenial(const HifiSockAddr& senderSockAddr) {
void DomainGatekeeper::sendProtocolMismatchConnectionDenial(const SockAddr& senderSockAddr) {
QString protocolVersionError = "Protocol version mismatch - Domain version: " + QCoreApplication::applicationVersion();
qDebug() << "Protocol Version mismatch - denying connection.";
@ -880,7 +880,7 @@ void DomainGatekeeper::sendProtocolMismatchConnectionDenial(const HifiSockAddr&
DomainHandler::ConnectionRefusedReason::ProtocolMismatch);
}
void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr,
void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const SockAddr& senderSockAddr,
DomainHandler::ConnectionRefusedReason reasonCode,
QString extraInfo) {
// this is an agent and we've decided we won't let them connect - send them a packet to deny connection
@ -910,7 +910,7 @@ void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const H
DependencyManager::get<LimitedNodeList>()->sendPacket(std::move(connectionDeniedPacket), senderSockAddr);
}
void DomainGatekeeper::sendConnectionTokenPacket(const QString& username, const HifiSockAddr& senderSockAddr) {
void DomainGatekeeper::sendConnectionTokenPacket(const QString& username, const SockAddr& senderSockAddr) {
// get the existing connection token or create a new one
QUuid& connectionToken = _connectionTokenHash[username.toLower()];

View file

@ -47,7 +47,7 @@ public:
Node::LocalID findOrCreateLocalID(const QUuid& uuid);
static void sendProtocolMismatchConnectionDenial(const HifiSockAddr& senderSockAddr);
static void sendProtocolMismatchConnectionDenial(const SockAddr& senderSockAddr);
public slots:
void processConnectRequestPacket(QSharedPointer<ReceivedMessage> message);
void processICEPingPacket(QSharedPointer<ReceivedMessage> message);
@ -90,19 +90,19 @@ private:
SharedNodePointer addVerifiedNodeFromConnectRequest(const NodeConnectionData& nodeConnection);
bool verifyUserSignature(const QString& username, const QByteArray& usernameSignature,
const HifiSockAddr& senderSockAddr);
const SockAddr& senderSockAddr);
bool needToVerifyDomainUserIdentity(const QString& username, const QString& accessToken, const QString& refreshToken);
bool verifyDomainUserIdentity(const QString& username, const QString& accessToken, const QString& refreshToken,
const HifiSockAddr& senderSockAddr);
const SockAddr& senderSockAddr);
bool isWithinMaxCapacity();
bool shouldAllowConnectionFromNode(const QString& username, const QByteArray& usernameSignature,
const HifiSockAddr& senderSockAddr);
const SockAddr& senderSockAddr);
void sendConnectionTokenPacket(const QString& username, const HifiSockAddr& senderSockAddr);
static void sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr,
void sendConnectionTokenPacket(const QString& username, const SockAddr& senderSockAddr);
static void sendConnectionDeniedPacket(const QString& reason, const SockAddr& senderSockAddr,
DomainHandler::ConnectionRefusedReason reasonCode = DomainHandler::ConnectionRefusedReason::Unknown,
QString extraInfo = QString());

View file

@ -777,7 +777,7 @@ void DomainServer::setupNodeListAndAssignments() {
connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded);
connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled);
connect(nodeList.data(), &LimitedNodeList::localSockAddrChanged, this,
[this](const HifiSockAddr& localSockAddr) {
[this](const SockAddr& localSockAddr) {
DependencyManager::get<LimitedNodeList>()->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, localSockAddr.getPort());
});
@ -1225,7 +1225,7 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode, quint64 reques
broadcastNewNode(newNode);
}
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr &senderSockAddr, bool newConnection) {
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const SockAddr &senderSockAddr, bool newConnection) {
const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID +
NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + 4;
@ -1501,7 +1501,7 @@ void DomainServer::transactionJSONCallback(const QJsonObject& data) {
}
}
QJsonObject jsonForDomainSocketUpdate(const HifiSockAddr& socket) {
QJsonObject jsonForDomainSocketUpdate(const SockAddr& socket) {
const QString SOCKET_NETWORK_ADDRESS_KEY = "network_address";
const QString SOCKET_PORT_KEY = "port";
@ -1512,7 +1512,7 @@ QJsonObject jsonForDomainSocketUpdate(const HifiSockAddr& socket) {
return socketObject;
}
void DomainServer::performIPAddressPortUpdate(const HifiSockAddr& newPublicSockAddr) {
void DomainServer::performIPAddressPortUpdate(const SockAddr& newPublicSockAddr) {
const QString& DOMAIN_SERVER_SETTINGS_KEY = "domain_server";
const QString& publicSocketAddress = newPublicSockAddr.getAddress().toString();
const int publicSocketPort = newPublicSockAddr.getPort();
@ -1770,7 +1770,7 @@ void DomainServer::sendHeartbeatToIceServer() {
QDataStream heartbeatStream(_iceServerHeartbeatPacket.get());
QUuid senderUUID;
HifiSockAddr publicSocket, localSocket;
SockAddr publicSocket, localSocket;
heartbeatStream >> senderUUID >> publicSocket >> localSocket;
if (senderUUID != limitedNodeList->getSessionUUID()
@ -1928,7 +1928,7 @@ void DomainServer::processNodeJSONStatsPacket(QSharedPointer<ReceivedMessage> pa
}
}
QJsonObject DomainServer::jsonForSocket(const HifiSockAddr& socket) {
QJsonObject DomainServer::jsonForSocket(const SockAddr& socket) {
QJsonObject socketJSON;
socketJSON["ip"] = socket.getAddress().toString();
@ -3017,7 +3017,7 @@ static const QString BROADCASTING_SETTINGS_KEY = "broadcasting";
struct ReplicationServerInfo {
NodeType_t nodeType;
HifiSockAddr sockAddr;
SockAddr sockAddr;
};
ReplicationServerInfo serverInformationFromSettings(QVariantMap serverMap, ReplicationServerDirection direction) {
@ -3038,7 +3038,7 @@ ReplicationServerInfo serverInformationFromSettings(QVariantMap serverMap, Repli
serverInfo.nodeType = NodeType::downstreamType(nodeType);
}
// read the address and port and construct a HifiSockAddr from them
// read the address and port and construct a SockAddr from them
serverInfo.sockAddr = {
serverMap[REPLICATION_SERVER_ADDRESS].toString(),
(quint16) serverMap[REPLICATION_SERVER_PORT].toString().toInt()
@ -3047,7 +3047,7 @@ ReplicationServerInfo serverInformationFromSettings(QVariantMap serverMap, Repli
return serverInfo;
}
return { NodeType::Unassigned, HifiSockAddr() };
return { NodeType::Unassigned, SockAddr() };
}
void DomainServer::updateReplicationNodes(ReplicationServerDirection direction) {
@ -3056,7 +3056,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
if (broadcastSettingsVariant.isValid()) {
auto nodeList = DependencyManager::get<LimitedNodeList>();
std::vector<HifiSockAddr> replicationNodesInSettings;
std::vector<SockAddr> replicationNodesInSettings;
auto replicationSettings = broadcastSettingsVariant.toMap();
@ -3066,7 +3066,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
if (replicationSettings.contains(serversKey)) {
auto serversSettings = replicationSettings.value(serversKey).toList();
std::vector<HifiSockAddr> knownReplicationNodes;
std::vector<SockAddr> knownReplicationNodes;
nodeList->eachNode([direction, &knownReplicationNodes](const SharedNodePointer& otherNode) {
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
@ -3620,7 +3620,7 @@ void DomainServer::randomizeICEServerAddress(bool shouldTriggerHostLookup) {
indexToTry = distribution(generator);
}
_iceServerSocket = HifiSockAddr { candidateICEAddresses[indexToTry], ICE_SERVER_DEFAULT_PORT };
_iceServerSocket = SockAddr { candidateICEAddresses[indexToTry], ICE_SERVER_DEFAULT_PORT };
qCInfo(domain_server_ice) << "Set candidate ice-server socket to" << _iceServerSocket;
// clear our number of hearbeat denials, this should be re-set on ice-server change

View file

@ -113,7 +113,7 @@ private slots:
void setupPendingAssignmentCredits();
void sendPendingTransactionsToServer();
void performIPAddressPortUpdate(const HifiSockAddr& newPublicSockAddr);
void performIPAddressPortUpdate(const SockAddr& newPublicSockAddr);
void sendHeartbeatToMetaverse() { sendHeartbeatToMetaverse(QString(), int()); }
void sendHeartbeatToIceServer();
void nodePingMonitor();
@ -186,7 +186,7 @@ private:
void handleKillNode(SharedNodePointer nodeToKill);
void broadcastNodeDisconnect(const SharedNodePointer& disconnnectedNode);
void sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr& senderSockAddr, bool newConnection);
void sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const SockAddr& senderSockAddr, bool newConnection);
bool isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB);
@ -212,7 +212,7 @@ private:
QNetworkReply* profileRequestGivenTokenReply(QNetworkReply* tokenReply);
Headers setupCookieHeadersFromProfileReply(QNetworkReply* profileReply);
QJsonObject jsonForSocket(const HifiSockAddr& socket);
QJsonObject jsonForSocket(const SockAddr& socket);
QJsonObject jsonObjectForNode(const SharedNodePointer& node);
bool shouldReplicateNode(const Node& node);
@ -270,7 +270,7 @@ private:
DomainServerSettingsManager _settingsManager;
HifiSockAddr _iceServerSocket;
SockAddr _iceServerSocket;
std::unique_ptr<NLPacket> _iceServerHeartbeatPacket;
// These will be parented to this, they are not dangling

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2/6/2014.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -17,7 +18,7 @@
#include <QtCore/QUuid>
#include <QtCore/QJsonObject>
#include <HifiSockAddr.h>
#include <SockAddr.h>
#include <NLPacket.h>
#include <NodeData.h>
#include <NodeType.h>
@ -41,8 +42,8 @@ public:
QElapsedTimer& getPaymentIntervalTimer() { return _paymentIntervalTimer; }
void setSendingSockAddr(const HifiSockAddr& sendingSockAddr) { _sendingSockAddr = sendingSockAddr; }
const HifiSockAddr& getSendingSockAddr() { return _sendingSockAddr; }
void setSendingSockAddr(const SockAddr& sendingSockAddr) { _sendingSockAddr = sendingSockAddr; }
const SockAddr& getSendingSockAddr() { return _sendingSockAddr; }
void setIsAuthenticated(bool isAuthenticated) { _isAuthenticated = isAuthenticated; }
bool isAuthenticated() const { return _isAuthenticated; }
@ -90,7 +91,7 @@ private:
QJsonObject _statsJSONObject;
static StringPairHash _overrideHash;
HifiSockAddr _sendingSockAddr;
SockAddr _sendingSockAddr;
bool _isAuthenticated = true;
NodeSet _nodeInterestSet;
QString _nodeVersion;

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2015-08-24.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -13,7 +14,7 @@
#include <QtCore/QDataStream>
NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, const HifiSockAddr& senderSockAddr,
NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, const SockAddr& senderSockAddr,
bool isConnectRequest) {
NodeConnectionData newHeader;

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2015-08-24.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -18,15 +19,15 @@
class NodeConnectionData {
public:
static NodeConnectionData fromDataStream(QDataStream& dataStream, const HifiSockAddr& senderSockAddr,
static NodeConnectionData fromDataStream(QDataStream& dataStream, const SockAddr& senderSockAddr,
bool isConnectRequest = true);
QUuid connectUUID;
quint64 lastPingTimestamp{ 0 }; // client-side send time of last connect/domain list request
NodeType_t nodeType;
HifiSockAddr publicSockAddr;
HifiSockAddr localSockAddr;
HifiSockAddr senderSockAddr;
SockAddr publicSockAddr;
SockAddr localSockAddr;
SockAddr senderSockAddr;
QList<NodeType_t> interestList;
QString placeName;
QString hardwareAddress;

View file

@ -10,6 +10,31 @@ import json
import xml.etree.ElementTree as ET
import functools
# The way Qt is handled is a bit complicated, so I'm documenting it here.
#
# 1. User runs cmake
# 2. cmake calls prebuild.py, which is referenced in /CMakeLists.txt
# 3. prebuild.py calls this code.
# 4. hifi_qt.py determines how to handle cmake: do we need to download a package, and which?
# 4.a - Using system Qt
# No download, most special paths are turned off.
# We build in the same way a normal Qt program would.
# 4.b - Using an user-provided Qt build in a custom directory.
# We just need to set the cmakePath to the right dir (qt5-install/lib/cmake)
# 4.c - Using a premade package.
# We check the OS and distro and set qtUrl to the URL to download.
# After this, it works on the same pathway as 4.b.
# 5. We write /qt.cmake, which contains paths that are passed down to SetupQt.cmake
# The template for this file is in CMAKE_TEMPLATE just below this comment
# and it sets the QT_CMAKE_PREFIX_PATH variable used by SetupQt.cmake.
# 6. cmake includes /qt.cmake receiving our information
# In the case of system Qt, this step is skipped.
# 7. cmake runs SetupQt.cmake which takes care of the cmake parts of the Qt configuration.
# In the case of system Qt, SetupQt.cmake is a no-op. It runs but exits immediately.
#
# The format for a prebuilt qt is a package containing a top-level directory named
# 'qt5-install', which contains the result of a "make install" from a build of the Qt source.
print = functools.partial(print, flush=True)
# Encapsulates the vcpkg system
@ -28,32 +53,85 @@ endif()
self.args = args
self.configFilePath = os.path.join(args.build_root, 'qt.cmake')
self.version = os.getenv('VIRCADIA_USE_QT_VERSION', '5.15.2')
self.assets_url = hifi_utils.readEnviromentVariableFromFile(args.build_root, 'EXTERNAL_BUILD_ASSETS')
defaultBasePath = os.path.expanduser('~/hifi/qt')
self.basePath = os.getenv('HIFI_QT_BASE', defaultBasePath)
if (not os.path.isdir(self.basePath)):
os.makedirs(self.basePath)
self.path = os.path.join(self.basePath, self.version)
self.fullPath = os.path.join(self.path, 'qt5-install')
self.cmakePath = os.path.join(self.fullPath, 'lib/cmake')
print("Using qt path {}".format(self.path))
lockDir, lockName = os.path.split(self.path)
lockName += '.lock'
if not os.path.isdir(lockDir):
os.makedirs(lockDir)
self.lockFile = os.path.join(lockDir, lockName)
if (os.getenv('VIRCADIA_USE_PREBUILT_QT')):
print("Using pre-built Qt5")
return
# OS dependent information
system = platform.system()
cpu_architecture = platform.machine()
qt_found = False
system_qt = False
# Here we handle the 3 possible cases of dealing with Qt:
if os.getenv('VIRCADIA_USE_SYSTEM_QT', "") != "":
# 1. Using the system provided Qt. This is only recommended for Qt 5.15.0 and above,
# as it includes a required fix on Linux.
#
# This path only works on Linux as neither Windows nor OSX ship Qt.
if system != "Linux":
raise Exception("Using the system Qt is only supported on Linux")
self.path = None
self.cmakePath = None
qt_found = True
system_qt = True
print("Using system Qt")
elif os.getenv('VIRCADIA_QT_PATH', "") != "":
# 2. Using an user-provided directory.
# VIRCADIA_QT_PATH must point to a directory with a Qt install in it.
self.path = os.getenv('VIRCADIA_QT_PATH')
self.fullPath = self.path
self.cmakePath = os.path.join(self.fullPath, 'lib', 'cmake')
qt_found = True
print("Using Qt from " + self.fullPath)
else:
# 3. Using a pre-built Qt.
#
# This works somewhat differently from above, notice how path and fullPath are
# used differently in this case.
#
# In the case of an user-provided directory, we just use the user-supplied directory.
#
# For a pre-built qt, however, we have to unpack it. The archive is required to contain
# a qt5-install directory in it.
self.path = os.path.expanduser("~/vircadia-files/qt")
self.fullPath = os.path.join(self.path, 'qt5-install')
self.cmakePath = os.path.join(self.fullPath, 'lib', 'cmake')
if (not os.path.isdir(self.path)):
os.makedirs(self.path)
qt_found = os.path.isdir(self.fullPath)
print("Using a packaged Qt")
if not system_qt:
if qt_found:
# Sanity check, ensure we have a good cmake directory
qt5_dir = os.path.join(self.cmakePath, "Qt5")
if not os.path.isdir(qt5_dir):
raise Exception("Failed to find Qt5 directory under " + self.cmakePath + ". There should be a " + qt5_dir)
else:
print("Qt5 check passed, found " + qt5_dir)
# I'm not sure why this is needed. It's used by hifi_singleton.
# Perhaps it stops multiple build processes from interferring?
lockDir, lockName = os.path.split(self.path)
lockName += '.lock'
if not os.path.isdir(lockDir):
os.makedirs(lockDir)
self.lockFile = os.path.join(lockDir, lockName)
if qt_found:
print("Found pre-built Qt5")
return
if 'Windows' == system:
self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.15.2-windows.tar.gz'
@ -61,7 +139,7 @@ endif()
self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.15.2-macos.tar.gz'
elif 'Linux' == system:
import distro
dist = distro.linux_distribution()
cpu_architecture = platform.machine()
if 'x86_64' == cpu_architecture:
if distro.id() == 'ubuntu':
@ -71,16 +149,12 @@ endif()
if u_major == 18:
self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.15.2-ubuntu-18.04-amd64.tar.xz'
elif u_major > 19:
print("We don't support " + distro.name(pretty=True) + " yet. Perhaps consider helping us out?")
raise Exception('LINUX DISTRO IS NOT SUPPORTED YET!!!')
self.__no_qt_package_error()
else:
print("Sorry, " + distro.name(pretty=True) + " is old and won't be officially supported. Please consider upgrading.");
raise Exception('UNKNOWN LINUX DISTRO VERSION!!!')
self.__unsupported_error()
else:
print("Sorry, " + distro.name(pretty=True) + " is not supported on x86_64. Please consider helping us out.")
print("It's also possible to build Qt for your distribution, please see the documentation at:")
print("https://github.com/vircadia/vircadia/tree/master/tools/qt-builder")
raise Exception('UNKNOWN LINUX VERSION!!!')
self.__no_qt_package_error()
elif 'aarch64' == cpu_architecture:
if distro.id() == 'ubuntu':
u_major = int( distro.major_version() )
@ -89,11 +163,9 @@ endif()
if u_major == 18:
self.qtUrl = 'http://motofckr9k.ddns.net/vircadia_packages/qt5-install-5.15.2-ubuntu-18.04-aarch64_test.tar.xz'
elif u_major > 19:
print("We don't support " + distro.name(pretty=True) + " on aarch64 yet. Perhaps consider helping us out?")
raise Exception('LINUX DISTRO IS NOT SUPPORTED YET!!!')
self.__no_qt_package_error()
else:
print("Sorry, " + distro.name(pretty=True) + " is old and won't be officially supported. Please consider upgrading.");
raise Exception('UNKNOWN LINUX DISTRO VERSION!!!')
self.__unsupported_error()
elif distro.id() == 'debian':
u_major = int( distro.major_version() )
@ -101,20 +173,14 @@ endif()
if u_major == 10:
#self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz'
print("We don't support " + distro.name(pretty=True) + " on aarch64 yet. Perhaps consider helping us out?")
raise Exception('LINUX DISTRO IS NOT SUPPORTED YET!!!')
self.__no_qt_package_error()
elif u_major > 10:
print("We don't support " + distro.name(pretty=True) + " on aarch64 yet. Perhaps consider helping us out?")
raise Exception('LINUX DISTRO IS NOT SUPPORTED YET!!!')
self.__no_qt_package_error()
else:
print("Sorry, " + distro.name(pretty=True) + " is old and won't be officially supported. Please consider upgrading.");
raise Exception('UNKNOWN LINUX DISTRO VERSION!!!')
self.__unsupported_error()
else:
print("Sorry, " + distro.name(pretty=True) + " is not supported on aarch64. Please consider helping us out.")
print("It's also possible to build Qt for your distribution, please see the documentation at:")
print("https://github.com/vircadia/vircadia/tree/master/tools/qt-builder")
raise Exception('UNKNOWN LINUX VERSION!!!')
self.__no_qt_package_error()
else:
raise Exception('UNKNOWN CPU ARCHITECTURE!!!')
@ -124,6 +190,14 @@ endif()
print("Machine : " + platform.machine())
raise Exception('UNKNOWN OPERATING SYSTEM!!!')
def showQtBuildInfo(self):
print("")
print("It's also possible to build Qt for your distribution, please see the documentation at:")
print("https://github.com/vircadia/vircadia/tree/master/tools/qt-builder")
print("")
print("Alternatively, you can try building against the system Qt by setting the VIRCADIA_USE_SYSTEM_QT environment variable.")
print("You'll need to install the development packages, and to have Qt 5.15.0 or newer. ")
def writeConfig(self):
print("Writing cmake config to {}".format(self.configFilePath))
# Write out the configuration for use by CMake
@ -138,3 +212,40 @@ endif()
hifi_utils.downloadAndExtract(self.qtUrl, self.path)
else:
print ('Qt has already been downloaded')
def __unsupported_error(self):
import distro
cpu_architecture = platform.machine()
print('')
hifi_utils.color('red')
print("Sorry, " + distro.name(pretty=True) + " on " + cpu_architecture + " is too old and won't be officially supported.")
hifi_utils.color('white')
print("Please upgrade to a more recent Linux distribution.")
hifi_utils.color('clear')
print('')
raise hifi_utils.SilentFatalError(3)
def __no_qt_package_error(self):
import distro
cpu_architecture = platform.machine()
print('')
hifi_utils.color('red')
print("Sorry, we don't have a prebuilt Qt package for " + distro.name(pretty=True) + " on " + cpu_architecture + ".")
hifi_utils.color('white')
print('')
print("If this is a recent distribution, dating from 2021 or so, you can try building")
print("against the system Qt by running this command, and trying again:")
print(" export VIRCADIA_USE_SYSTEM_QT=1")
print("")
hifi_utils.color('clear')
print("If you'd like to try to build Qt from source either for building Vircadia, or")
print("to contribute a prebuilt package for your distribution, please see the")
print("documentation at: ", end='')
hifi_utils.color('blue')
print("https://github.com/vircadia/vircadia/tree/master/tools/qt-builder")
hifi_utils.color('clear')
print('')
raise hifi_utils.SilentFatalError(2)

View file

@ -16,6 +16,18 @@ import functools
print = functools.partial(print, flush=True)
ansi_colors = {
'black' : 30,
'red': 31,
'green': 32,
'yellow': 33,
'blue': 34,
'magenta': 35,
'cyan': 36,
'white': 37,
'clear': 0
}
def scriptRelative(*paths):
scriptdir = os.path.dirname(os.path.realpath(sys.argv[0]))
result = os.path.join(scriptdir, *paths)
@ -125,3 +137,17 @@ def downloadAndExtract(url, destPath, hash=None, hasher=hashlib.sha512(), isZip=
def readEnviromentVariableFromFile(buildRootDir, var):
with open(os.path.join(buildRootDir, '_env', var + ".txt")) as fp:
return fp.read()
class SilentFatalError(Exception):
"""Thrown when some sort of fatal condition happened, and we already reported it to the user.
This excecption exists to give a chance to run any cleanup needed before exiting.
It should be handled at the bottom of the call stack, where the only action is to call
sys.exit(ex.exit_code)
"""
def __init__(self, exit_code):
self.exit_code = exit_code
def color(color_name):
# Ideally we'd use the termcolor module, but this avoids adding it as a dependency.
print("\033[1;{}m".format(ansi_colors[color_name]), end='')

View file

@ -60,7 +60,7 @@ endif()
self.path = args.vcpkg_root
self.noClean = True
else:
defaultBasePath = os.path.expanduser('~/hifi/vcpkg')
defaultBasePath = os.path.expanduser('~/vircadia-files/vcpkg')
self.basePath = os.getenv('HIFI_VCPKG_BASE', defaultBasePath)
if self.args.android:
self.basePath = os.path.join(self.basePath, 'android')

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2014-10-01.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -97,7 +98,7 @@ void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) {
heartbeatStream >> senderUUID;
// pull the public and private sock addrs for this peer
HifiSockAddr publicSocket, localSocket;
SockAddr publicSocket, localSocket;
heartbeatStream >> publicSocket >> localSocket;
// check if this node also included a UUID that they would like to connect to
@ -129,7 +130,7 @@ SharedNetworkPeer IceServer::addOrUpdateHeartbeatingPeer(NLPacket& packet) {
// pull the UUID, public and private sock addrs for this peer
QUuid senderUUID;
HifiSockAddr publicSocket, localSocket;
SockAddr publicSocket, localSocket;
QByteArray signature;
QDataStream heartbeatStream(&packet);
@ -288,7 +289,7 @@ void IceServer::publicKeyReplyFinished(QNetworkReply* reply) {
reply->deleteLater();
}
void IceServer::sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr) {
void IceServer::sendPeerInformationPacket(const NetworkPeer& peer, const SockAddr* destinationSockAddr) {
auto peerPacket = NLPacket::create(PacketType::ICEServerPeerInformation);
// get the byte array for this peer

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2014-10-01.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -40,7 +41,7 @@ private:
void processPacket(std::unique_ptr<udt::Packet> packet);
SharedNetworkPeer addOrUpdateHeartbeatingPeer(NLPacket& incomingPacket);
void sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr);
void sendPeerInformationPacket(const NetworkPeer& peer, const SockAddr* destinationSockAddr);
bool isVerifiedHeartbeat(const QUuid& domainID, const QByteArray& plaintext, const QByteArray& signature);
void requestDomainPublicKey(const QUuid& domainID);

View file

@ -34,14 +34,14 @@ if (ANDROID)
add_custom_command(
OUTPUT ${RESOURCES_RCC}
DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS}
COMMAND "${QT_DIR}/bin/rcc"
COMMAND "${RCC_BINARY}"
ARGS ${RESOURCES_QRC} -no-compress -binary -o ${RESOURCES_RCC}
)
else ()
add_custom_command(
OUTPUT ${RESOURCES_RCC}
DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS}
COMMAND "${QT_DIR}/bin/rcc"
COMMAND "${RCC_BINARY}"
ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC}
)
endif()
@ -435,18 +435,20 @@ else()
endif()
endif()
if (DEV_BUILD AND (APPLE OR UNIX))
# create a qt.conf file to override hard-coded search paths in Qt libs
set(QT_LIB_PATH "${QT_CMAKE_PREFIX_PATH}/../..")
if (APPLE)
set(QT_CONF_FILE "${RESOURCES_DEV_DIR}/../Resources/qt.conf")
else ()
set(QT_CONF_FILE "${INTERFACE_EXEC_DIR}/qt.conf")
endif ()
file(GENERATE
OUTPUT "${QT_CONF_FILE}"
CONTENT "[Paths]\nPrefix=${QT_LIB_PATH}\n"
)
if ("$ENV{VIRCADIA_USE_SYSTEM_QT}" STREQUAL "")
if (DEV_BUILD AND (APPLE OR UNIX))
# create a qt.conf file to override hard-coded search paths in Qt libs
set(QT_LIB_PATH "${QT_CMAKE_PREFIX_PATH}/../..")
if (APPLE)
set(QT_CONF_FILE "${RESOURCES_DEV_DIR}/../Resources/qt.conf")
else ()
set(QT_CONF_FILE "${INTERFACE_EXEC_DIR}/qt.conf")
endif ()
file(GENERATE
OUTPUT "${QT_CONF_FILE}"
CONTENT "[Paths]\nPrefix=${QT_LIB_PATH}\n"
)
endif()
endif()
if (SCRIPTS_INSTALL_DIR)

View file

@ -53,7 +53,7 @@
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
#image_button {
position: absolute;
width: 463;
@ -77,13 +77,13 @@
var handControllerImageURL = null;
var index = 0;
var count = 3;
var handControllerRefURL = "https://docs.vircadia.dev/explore/get-started/vr-controls.html#vr-controls";
var keyboardRefURL = "https://docs.vircadia.dev/explore/get-started/desktop.html#movement-controls";
var gamepadRefURL = "https://docs.vircadia.dev/explore/get-started/vr-controls.html#gamepad";
var handControllerRefURL = "https://docs.vircadia.com/explore/get-started/vr-controls.html#vr-controls";
var keyboardRefURL = "https://docs.vircadia.com/explore/get-started/desktop.html#movement-controls";
var gamepadRefURL = "https://docs.vircadia.com/explore/get-started/vr-controls.html#gamepad";
function showKbm() {
document.getElementById("main_image").setAttribute("src", "img/tablet-help-keyboard.jpg");
document.getElementById("image_button").setAttribute("href", keyboardRefURL);
document.getElementById("image_button").setAttribute("href", keyboardRefURL);
}
function showHandControllers() {
@ -107,7 +107,7 @@
}
function chooseIcon() {
switch (index)
switch (index)
{
case 0:
showGamepad();

View file

@ -229,7 +229,7 @@ Item {
}
function openDocs() {
Qt.openUrlExternally("https://docs.vircadia.dev/create/avatars/package-avatar.html");
Qt.openUrlExternally("https://docs.vircadia.com/create/avatars/package-avatar.html");
}
function openVideo() {

View file

@ -150,7 +150,7 @@ Item {
id: uploadingItemFooter
anchors.fill: parent
anchors.topMargin: 1
anchors.topMargin: 1
visible: !!root.uploader && !root.finished && root.uploader.state === 4
color: "#00B4EF"
@ -205,7 +205,7 @@ Item {
function showConfirmUploadPopup() {
popup.titleText = 'Overwrite Avatar';
popup.bodyText = 'You have previously uploaded the avatar file from this project.' +
popup.bodyText = 'You have previously uploaded the avatar file from this project.' +
' This will overwrite that avatar and you wont be able to access the older version.';
popup.button1text = 'CREATE NEW';
@ -318,7 +318,7 @@ Item {
text: "This item is not for sale yet, <a href='#'>learn more</a>."
onLinkActivated: {
Qt.openUrlExternally("https://docs.vircadia.dev/sell/add-item/upload-avatar.html");
Qt.openUrlExternally("https://docs.vircadia.com/sell/add-item/upload-avatar.html");
}
}

View file

@ -7,7 +7,7 @@ MessageBox {
popup.onButton2Clicked = callback;
popup.titleText = 'Specify Avatar URL'
popup.bodyText = 'This will not overwrite your existing favorite if you are wearing one.<br>' +
'<a href="https://docs.vircadia.dev/create/avatars/create-avatars.html">' +
'<a href="https://docs.vircadia.com/create/avatars/create-avatars.html">' +
'Learn to make a custom avatar by opening this link on your desktop.' +
'</a>'
popup.inputText.visible = true;

View file

@ -6,6 +6,7 @@
//
// Created by Zach Fox on 2017-08-25
// Copyright 2017 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -196,7 +197,7 @@ Rectangle {
root.availableUpdatesReceived = false;
root.currentUpdatesPage = 1;
Commerce.getAvailableUpdates(root.itemId);
var MARKETPLACE_API_URL = Account.metaverseServerURL + "/api/v1/marketplace/items/";
http.request({uri: MARKETPLACE_API_URL + root.itemId}, updateCheckoutQMLFromHTTP);
}
@ -327,7 +328,7 @@ Rectangle {
}
}
}
}
}
HifiCommerceCommon.FirstUseTutorial {
id: firstUseTutorial;
@ -374,7 +375,7 @@ Rectangle {
hoverEnabled: true;
propagateComposedEvents: false;
}
AnimatedImage {
id: loadingImage;
source: "../common/images/loader-blue.gif"
@ -397,7 +398,7 @@ Rectangle {
color: hifi.colors.black;
size: 28;
}
HifiControlsUit.Separator {
id: separator;
colorScheme: 1;
@ -475,7 +476,7 @@ Rectangle {
}
FiraSansSemiBold {
id: itemPriceText;
text: isTradingIn ? "FREE\nUPDATE" :
text: isTradingIn ? "FREE\nUPDATE" :
(isStocking ? "Free for creator" :
((root.itemPrice === -1) ? "--" : ((root.itemPrice > 0) ? root.itemPrice : "FREE")));
// Text size
@ -491,7 +492,7 @@ Rectangle {
}
}
}
HifiControlsUit.Separator {
id: separator2;
colorScheme: 1;
@ -728,7 +729,7 @@ Rectangle {
sendToScript({method: 'checkout_itemLinkClicked', itemId: itemId});
}
}
Rectangle {
id: rezzedNotifContainer;
z: 997;
@ -778,7 +779,7 @@ Rectangle {
lightboxPopup.bodyText = "Rezzing this content set will replace the existing environment and all of the items in this domain. " +
"If you want to save the state of the content in this domain, create a backup before proceeding.<br><br>" +
"For more information about backing up and restoring content, " +
"<a href='https://docs.vircadia.dev/host/maintain-domain/backup-domain.html'>" +
"<a href='https://docs.vircadia.com/host/maintain-domain/backup-domain.html'>" +
"click here to open info on your desktop browser.";
lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = function() {
@ -1069,7 +1070,7 @@ Rectangle {
buyButton.color = hifi.buttons.red;
root.shouldBuyWithControlledFailure = true;
} else {
buyButton.text = (root.isCertified ?
buyButton.text = (root.isCertified ?
(dataReady ?
(root.alreadyOwned ? "Buy Another" : "Buy") :
"--") :
@ -1079,7 +1080,7 @@ Rectangle {
}
}
}
HifiCommon.RootHttpRequest {
id: http;
@ -1211,7 +1212,7 @@ Rectangle {
// Else if the user HAS NOT selected a specific edition to update...
} else {
handleBuyAgainLogic();
}
}
// If the user IS NOT on the checkout page for the updated verison of an owned item...
// (i.e. they are checking out an item "normally")
} else {

View file

@ -6,6 +6,7 @@
//
// Created by Zach Fox on 2017-08-25
// Copyright 2017 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -115,7 +116,7 @@ Rectangle {
Component.onCompleted: {
isStandalone = PlatformInfo.isStandalone();
}
HifiCommerceCommon.CommerceLightbox {
id: lightboxPopup;
z: 999;
@ -174,7 +175,7 @@ Rectangle {
Commerce.getWalletStatus();
}
}
Item {
id: installedAppsContainer;
z: 998;
@ -210,7 +211,7 @@ Rectangle {
delegate: Item {
width: parent.width;
height: 40;
RalewayRegular {
text: model.appUrl;
// Text size
@ -251,7 +252,7 @@ Rectangle {
Commerce.openApp(model.appUrl);
}
}
HiFiGlyphs {
id: uninstallGlyph;
text: hifi.glyphs.close;
@ -292,7 +293,7 @@ Rectangle {
height: 40;
text: "SIDELOAD APP FROM LOCAL DISK";
onClicked: {
Window.browseChanged.connect(onFileOpenChanged);
Window.browseChanged.connect(onFileOpenChanged);
Window.browseAsync("Locate your app's .app.json file", "", "*.app.json");
}
}
@ -602,7 +603,7 @@ Rectangle {
lightboxPopup.bodyText = "Rezzing this content set will replace the existing environment and all of the items in this domain. " +
"If you want to save the state of the content in this domain, create a backup before proceeding.<br><br>" +
"For more information about backing up and restoring content, " +
"<a href='https://docs.vircadia.dev/host/maintain-domain/backup-domain.html'>" +
"<a href='https://docs.vircadia.com/host/maintain-domain/backup-domain.html'>" +
"click here to open info on your desktop browser.";
lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = function() {
@ -823,7 +824,7 @@ Rectangle {
anchors.right: parent.right;
height: 75;
color: "#B5EAFF";
Rectangle {
id: updatesAvailableGlyph;
anchors.verticalCenter: parent.verticalCenter;
@ -991,7 +992,7 @@ Rectangle {
//
// FUNCTION DEFINITIONS START
//
function updateCurrentlyWornWearables(wearables) {
for (var i = 0; i < purchasesModel.count; i++) {
for (var j = 0; j < wearables.length; j++) {

View file

@ -6,6 +6,7 @@
//
// Created by Zach Fox on 2017-08-18
// Copyright 2017 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -207,7 +208,7 @@ At the moment, there is currently no way to convert HFC to other currencies. Sta
if (link === "#privateKeyPath") {
Qt.openUrlExternally("file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/')));
} else if (link === "#blockchain") {
Qt.openUrlExternally("https://docs.vircadia.dev/explore/shop.html");
Qt.openUrlExternally("https://docs.vircadia.com/explore/shop.html");
} else if (link === "#bank") {
if ((Account.metaverseServerURL).toString().indexOf("staging") >= 0) {
Qt.openUrlExternally("hifi://hifiqa-master-metaverse-staging"); // So that we can test in staging.

View file

@ -164,6 +164,7 @@
#include <RenderableWebEntityItem.h>
#include <StencilMaskPass.h>
#include <procedural/ProceduralMaterialCache.h>
#include <procedural/ReferenceMaterial.h>
#include "recording/ClipCache.h"
#include "AudioClient.h"
@ -1972,7 +1973,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
loadSettings();
updateVerboseLogging();
setCachebustRequire();
// Make sure we don't time out during slow operations at startup
@ -2158,6 +2159,32 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
return QSizeF(0.0f, 0.0f);
});
Texture::setUnboundTextureForUUIDOperator([this](const QUuid& entityID) -> gpu::TexturePointer {
if (_aboutToQuit) {
return nullptr;
}
auto renderable = getEntities()->renderableForEntityId(entityID);
if (renderable) {
return renderable->getTexture();
}
return nullptr;
});
ReferenceMaterial::setMaterialForUUIDOperator([this](const QUuid& entityID) -> graphics::MaterialPointer {
if (_aboutToQuit) {
return nullptr;
}
auto renderable = getEntities()->renderableForEntityId(entityID);
if (renderable) {
return renderable->getTopMaterial();
}
return nullptr;
});
connect(this, &Application::aboutToQuit, [this]() {
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
});
@ -2624,7 +2651,7 @@ void Application::setCachebustRequire() {
return;
}
bool enable = menu->isOptionChecked(MenuOption::CachebustRequire);
Setting::Handle<bool>{ CACHEBUST_SCRIPT_REQUIRE_SETTING_NAME, false }.set(enable);
}
@ -3246,7 +3273,7 @@ void Application::initializeUi() {
safeURLS += settingsSafeURLS;
// END PULL SAFEURLS FROM INTERFACE.JSON Settings
if (AUTHORIZED_EXTERNAL_QML_SOURCE.isParentOf(url)) {
return true;
} else {
@ -4004,7 +4031,7 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
parser.parse(arguments());
if (parser.isSet(urlOption)) {
QUrl url = QUrl(parser.value(urlOption));
if (url.scheme() == URL_SCHEME_HIFIAPP) {
if (url.scheme() == URL_SCHEME_VIRCADIAAPP) {
Setting::Handle<QVariant>("startUpApp").set(url.path());
} else {
addressLookupString = url.toString();
@ -4022,7 +4049,7 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS);
Menu::getInstance()->triggerOption(MenuOption::HomeLocation);
}
if (!_overrideEntry) {
DependencyManager::get<AddressManager>()->goToEntry();
sentTo = SENT_TO_ENTRY;
@ -7198,7 +7225,7 @@ void Application::updateWindowTitle() const {
QString buildVersion = " - Vircadia - "
+ (BuildInfo::BUILD_TYPE == BuildInfo::BuildType::Stable ? QString("Version") : QString("Build"))
+ " " + applicationVersion();
if (BuildInfo::RELEASE_NAME != "") {
buildVersion += " - " + BuildInfo::RELEASE_NAME;
}
@ -7285,7 +7312,7 @@ void Application::clearDomainOctreeDetails(bool clearAll) {
void Application::domainURLChanged(QUrl domainURL) {
// disable physics until we have enough information about our new location to not cause craziness.
setIsServerlessMode(domainURL.scheme() != URL_SCHEME_HIFI);
setIsServerlessMode(domainURL.scheme() != URL_SCHEME_VIRCADIA);
if (isServerlessMode()) {
loadServerlessDomain(domainURL);
}
@ -7294,7 +7321,7 @@ void Application::domainURLChanged(QUrl domainURL) {
void Application::goToErrorDomainURL(QUrl errorDomainURL) {
// disable physics until we have enough information about our new location to not cause craziness.
setIsServerlessMode(errorDomainURL.scheme() != URL_SCHEME_HIFI);
setIsServerlessMode(errorDomainURL.scheme() != URL_SCHEME_VIRCADIA);
if (isServerlessMode()) {
loadErrorDomain(errorDomainURL);
}
@ -7658,7 +7685,7 @@ bool Application::canAcceptURL(const QString& urlString) const {
QUrl url(urlString);
if (url.query().contains(WEB_VIEW_TAG)) {
return false;
} else if (urlString.startsWith(URL_SCHEME_HIFI)) {
} else if (urlString.startsWith(URL_SCHEME_VIRCADIA)) {
return true;
}
QString lowerPath = url.path().toLower();
@ -7673,7 +7700,7 @@ bool Application::canAcceptURL(const QString& urlString) const {
bool Application::acceptURL(const QString& urlString, bool defaultUpload) {
QUrl url(urlString);
if (url.scheme() == URL_SCHEME_HIFI) {
if (url.scheme() == URL_SCHEME_VIRCADIA) {
// this is a hifi URL - have the AddressManager handle it
QMetaObject::invokeMethod(DependencyManager::get<AddressManager>().data(), "handleLookupString",
Qt::AutoConnection, Q_ARG(const QString&, urlString));
@ -7901,7 +7928,7 @@ bool Application::askToReplaceDomainContent(const QString& url) {
static const QString infoText = simpleWordWrap("Your domain's content will be replaced with a new content set. "
"If you want to save what you have now, create a backup before proceeding. For more information about backing up "
"and restoring content, visit the documentation page at: ", MAX_CHARACTERS_PER_LINE) +
"\nhttps://docs.vircadia.dev/host/maintain-domain/backup-domain.html";
"\nhttps://docs.vircadia.com/host/maintain-domain/backup-domain.html";
ModalDialogListener* dig = OffscreenUi::asyncQuestion("Are you sure you want to replace this domain's content set?",
infoText, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);

View file

@ -13,7 +13,10 @@
#define hifi_CrashHandler_h
#include <string>
class QCoreApplication;
#include <QCoreApplication>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(crash_handler)
bool startCrashHandler(std::string appPath);
void setCrashAnnotation(std::string name, std::string value);

View file

@ -13,6 +13,8 @@
#include "CrashHandler.h"
Q_LOGGING_CATEGORY(crash_handler, "vircadia.crash_handler")
#include <assert.h>
#include <vector>
@ -141,6 +143,10 @@ static const QString CRASHPAD_HANDLER_NAME{ "crashpad_handler.exe" };
static const QString CRASHPAD_HANDLER_NAME{ "crashpad_handler" };
#endif
#ifdef Q_OS_LINUX
#include <unistd.h>
#endif
#ifdef Q_OS_WIN
// ------------------------------------------------------------------------------------------------
// The area within this #ifdef is specific to the Microsoft C++ compiler
@ -311,8 +317,38 @@ void checkUnhandledExceptionHook() {
// ------------------------------------------------------------------------------------------------
#endif // Q_OS_WIN
// Locate the full path to the binary's directory
static QString findBinaryDir() {
// Normally we'd just use QCoreApplication::applicationDirPath(), but we can't.
// That function needs the QApplication to be created first, and Crashpad is initialized as early as possible,
// which is well before QApplication, so that function throws out a warning and returns ".".
//
// So we must do things the hard way here. In particular this is needed to correctly handle things in AppImage
// on Linux. On Windows and MacOS falling back to argv[0] should be fine.
#ifdef Q_OS_LINUX
// Find outselves by looking at /proc/<PID>/exe
pid_t ourPid = getpid();
QString exeLink = QString("/proc/%1/exe").arg(ourPid);
qCDebug(crash_handler) << "Looking at" << exeLink;
QFileInfo exeLinkInfo(exeLink);
if (exeLinkInfo.isSymLink()) {
QFileInfo exeInfo(exeLinkInfo.symLinkTarget());
qCDebug(crash_handler) << "exe symlink points at" << exeInfo;
return exeInfo.absoluteDir().absolutePath();
} else {
qCWarning(crash_handler) << exeLink << "isn't a symlink. /proc not mounted?";
}
#endif
return QString();
}
bool startCrashHandler(std::string appPath) {
if (BACKTRACE_URL.empty() || BACKTRACE_TOKEN.empty()) {
qCCritical(crash_handler) << "Backtrace URL or token not set, crash handler disabled.";
return false;
}
@ -338,11 +374,29 @@ bool startCrashHandler(std::string appPath) {
const auto crashpadDbPath = crashpadDbDir.toStdString() + "/" + crashpadDbName;
// Locate Crashpad handler
const QFileInfo interfaceBinary{ QString::fromStdString(appPath) };
const QDir interfaceDir = interfaceBinary.dir();
assert(interfaceDir.exists(CRASHPAD_HANDLER_NAME));
QString binaryDir = findBinaryDir();
QDir interfaceDir;
if (!binaryDir.isEmpty()) {
// Locating ourselves by argv[0] fails in the case of AppImage on Linux, as we get the AppImage
// itself in there. If we have a platform-specific method, and it succeeds, we use that instead
// of argv.
qCDebug(crash_handler) << "Locating own directory by platform-specific method";
interfaceDir.setPath(binaryDir);
} else {
qCDebug(crash_handler) << "Locating own directory by argv[0]";
interfaceDir.setPath(QString::fromStdString(appPath));
}
if (!interfaceDir.exists(CRASHPAD_HANDLER_NAME)) {
qCCritical(crash_handler) << "Failed to find" << CRASHPAD_HANDLER_NAME << "in" << interfaceDir << ", can't start crash handler";
return false;
}
const std::string CRASHPAD_HANDLER_PATH = interfaceDir.filePath(CRASHPAD_HANDLER_NAME).toStdString();
qCDebug(crash_handler) << "Crashpad handler found at" << QString::fromStdString(CRASHPAD_HANDLER_PATH);
// Setup different file paths
base::FilePath::StringType dbPath;
base::FilePath::StringType handlerPath;
@ -352,8 +406,10 @@ bool startCrashHandler(std::string appPath) {
base::FilePath db(dbPath);
base::FilePath handler(handlerPath);
qCDebug(crash_handler) << "Opening crashpad database" << QString::fromStdString(crashpadDbPath);
auto database = crashpad::CrashReportDatabase::Initialize(db);
if (database == nullptr || database->GetSettings() == nullptr) {
qCCritical(crash_handler) << "Failed to open crashpad database" << QString::fromStdString(crashpadDbPath);
return false;
}
@ -361,6 +417,7 @@ bool startCrashHandler(std::string appPath) {
database->GetSettings()->SetUploadsEnabled(true);
if (!client->StartHandler(handler, db, db, BACKTRACE_URL, annotations, arguments, true, true)) {
qCCritical(crash_handler) << "Failed to start crashpad handler";
return false;
}
@ -369,6 +426,7 @@ bool startCrashHandler(std::string appPath) {
gl_crashpadUnhandledExceptionFilter = SetUnhandledExceptionFilter(unhandledExceptionHandler);
#endif
qCInfo(crash_handler) << "Crashpad initialized";
return true;
}

View file

@ -17,8 +17,11 @@
#include <QDebug>
Q_LOGGING_CATEGORY(crash_handler, "vircadia.crash_handler")
bool startCrashHandler(std::string appPath) {
qDebug() << "No crash handler available.";
qCWarning(crash_handler) << "No crash handler available.";
return false;
}

View file

@ -1,9 +1,9 @@
//
// AvatarDoctor.cpp
//
//
// Created by Thijs Wenker on 2/12/2019.
// Copyright 2019 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -55,7 +55,7 @@ static QStringList HAND_MAPPING_SUFFIXES = {
"HandThumb1",
};
const QUrl PACKAGE_AVATAR_DOCS_BASE_URL = QUrl("https://docs.vircadia.dev/create/avatars/package-avatar.html");
const QUrl PACKAGE_AVATAR_DOCS_BASE_URL = QUrl("https://docs.vircadia.com/create/avatars/package-avatar.html");
AvatarDoctor::AvatarDoctor(const QUrl& avatarFSTFileUrl) :
_avatarFSTFileUrl(avatarFSTFileUrl) {
@ -71,7 +71,7 @@ void AvatarDoctor::startDiagnosing() {
return;
}
_isDiagnosing = true;
_errors.clear();
_externalTextureCount = 0;
@ -107,7 +107,7 @@ void AvatarDoctor::startDiagnosing() {
if (avatarModel.joints.length() > NETWORKED_JOINTS_LIMIT) {
addError(tr( "Avatar has over %n bones.", "", NETWORKED_JOINTS_LIMIT), "maximum-bone-limit");
}
// Avatar does not have Hips bone mapped
// Avatar does not have Hips bone mapped
if (!jointNames.contains("Hips")) {
addError("Hips are not mapped.", "hips-not-mapped");
}
@ -236,7 +236,7 @@ void AvatarDoctor::startDiagnosing() {
for (const auto& jointVariant: jointNameMappings.values()) {
jointValues << jointVariant.toString();
}
const auto& uniqueJointValues = jointValues.toSet();
for (const auto& jointName: uniqueJointValues) {
if (jointValues.count(jointName) > 1) {
@ -279,7 +279,7 @@ void AvatarDoctor::startDiagnosing() {
} else {
connect(materialMappingResource.data(), &NetworkTexture::finished, this,
[materialMappingHandled](bool success) mutable {
materialMappingHandled();
});
}
@ -302,7 +302,7 @@ void AvatarDoctor::startDiagnosing() {
} else {
addError("Model file cannot be opened", "missing-file");
emit complete(getErrors());
}
}
}
void AvatarDoctor::diagnoseTextures() {

File diff suppressed because it is too large Load diff

View file

@ -265,7 +265,7 @@ int main(int argc, const char* argv[]) {
if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {
if (parser.isSet(urlOption)) {
QUrl url = QUrl(parser.value(urlOption));
if (url.isValid() && (url.scheme() == URL_SCHEME_HIFI || url.scheme() == URL_SCHEME_HIFIAPP
if (url.isValid() && (url.scheme() == URL_SCHEME_VIRCADIA || url.scheme() == URL_SCHEME_VIRCADIAAPP
|| url.scheme() == HIFI_URL_SCHEME_HTTP || url.scheme() == HIFI_URL_SCHEME_HTTPS
|| url.scheme() == HIFI_URL_SCHEME_FILE)) {
qDebug() << "Writing URL to local socket";

View file

@ -139,9 +139,9 @@ void WindowScriptingInterface::disconnectedFromDomain() {
void WindowScriptingInterface::openUrl(const QUrl& url) {
if (!url.isEmpty()) {
auto scheme = url.scheme();
if (scheme == URL_SCHEME_HIFI) {
if (scheme == URL_SCHEME_VIRCADIA) {
DependencyManager::get<AddressManager>()->handleLookupString(url.toString());
} else if (scheme == URL_SCHEME_HIFIAPP) {
} else if (scheme == URL_SCHEME_VIRCADIAAPP) {
DependencyManager::get<QmlCommerce>()->openSystemApp(url.path());
} else {
#if defined(Q_OS_ANDROID)

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 1/22/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -33,7 +34,7 @@
#include <shared/WebRTC.h>
#include <DependencyManager.h>
#include <HifiSockAddr.h>
#include <SockAddr.h>
#include <NLPacket.h>
#include <MixedProcessedAudioStream.h>
#include <RingBufferHistory.h>

View file

@ -3,6 +3,7 @@
// interface/src/avatar
//
// Copyright 2012 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -207,7 +208,7 @@ public:
/*@jsdoc
* Gets the default rotation of a joint (in the current avatar) relative to its parent.
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* @function MyAvatar.getDefaultJointRotation
* @param {number} index - The joint index.
* @returns {Quat} The default rotation of the joint if the joint index is valid, otherwise {@link Quat(0)|Quat.IDENTITY}.
@ -218,10 +219,10 @@ public:
* Gets the default translation of a joint (in the current avatar) relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* @function MyAvatar.getDefaultJointTranslation
* @param {number} index - The joint index.
* @returns {Vec3} The default translation of the joint (in model coordinates) if the joint index is valid, otherwise
* @returns {Vec3} The default translation of the joint (in model coordinates) if the joint index is valid, otherwise
* {@link Vec3(0)|Vec3.ZERO}.
*/
Q_INVOKABLE virtual glm::vec3 getDefaultJointTranslation(int index) const;
@ -283,7 +284,7 @@ public:
// world-space to avatar-space rigconversion functions
/*@jsdoc
* Transforms a position in world coordinates to a position in a joint's coordinates, or avatar coordinates if no joint is
* Transforms a position in world coordinates to a position in a joint's coordinates, or avatar coordinates if no joint is
* specified.
* @function MyAvatar.worldToJointPoint
* @param {Vec3} position - The position in world coordinates.
@ -293,7 +294,7 @@ public:
Q_INVOKABLE glm::vec3 worldToJointPoint(const glm::vec3& position, const int jointIndex = -1) const;
/*@jsdoc
* Transforms a direction in world coordinates to a direction in a joint's coordinates, or avatar coordinates if no joint
* Transforms a direction in world coordinates to a direction in a joint's coordinates, or avatar coordinates if no joint
* is specified.
* @function MyAvatar.worldToJointDirection
* @param {Vec3} direction - The direction in world coordinates.
@ -303,7 +304,7 @@ public:
Q_INVOKABLE glm::vec3 worldToJointDirection(const glm::vec3& direction, const int jointIndex = -1) const;
/*@jsdoc
* Transforms a rotation in world coordinates to a rotation in a joint's coordinates, or avatar coordinates if no joint is
* Transforms a rotation in world coordinates to a rotation in a joint's coordinates, or avatar coordinates if no joint is
* specified.
* @function MyAvatar.worldToJointRotation
* @param {Quat} rotation - The rotation in world coordinates.
@ -313,7 +314,7 @@ public:
Q_INVOKABLE glm::quat worldToJointRotation(const glm::quat& rotation, const int jointIndex = -1) const;
/*@jsdoc
* Transforms a position in a joint's coordinates, or avatar coordinates if no joint is specified, to a position in world
* Transforms a position in a joint's coordinates, or avatar coordinates if no joint is specified, to a position in world
* coordinates.
* @function MyAvatar.jointToWorldPoint
* @param {Vec3} position - The position in joint coordinates, or avatar coordinates if no joint is specified.
@ -323,7 +324,7 @@ public:
Q_INVOKABLE glm::vec3 jointToWorldPoint(const glm::vec3& position, const int jointIndex = -1) const;
/*@jsdoc
* Transforms a direction in a joint's coordinates, or avatar coordinates if no joint is specified, to a direction in world
* Transforms a direction in a joint's coordinates, or avatar coordinates if no joint is specified, to a direction in world
* coordinates.
* @function MyAvatar.jointToWorldDirection
* @param {Vec3} direction - The direction in joint coordinates, or avatar coordinates if no joint is specified.
@ -333,7 +334,7 @@ public:
Q_INVOKABLE glm::vec3 jointToWorldDirection(const glm::vec3& direction, const int jointIndex = -1) const;
/*@jsdoc
* Transforms a rotation in a joint's coordinates, or avatar coordinates if no joint is specified, to a rotation in world
* Transforms a rotation in a joint's coordinates, or avatar coordinates if no joint is specified, to a rotation in world
* coordinates.
* @function MyAvatar.jointToWorldRotation
* @param {Quat} rotation - The rotation in joint coordinates, or avatar coordinates if no joint is specified.
@ -351,7 +352,7 @@ public:
virtual int parseDataFromBuffer(const QByteArray& buffer) override;
/*@jsdoc
* Sets the offset applied to the current avatar. The offset adjusts the position that the avatar is rendered. For example,
* Sets the offset applied to the current avatar. The offset adjusts the position that the avatar is rendered. For example,
* with an offset of <code>{ x: 0, y: 0.1, z: 0 }</code>, your avatar will appear to be raised off the ground slightly.
* @function MyAvatar.setSkeletonOffset
* @param {Vec3} offset - The skeleton offset to set.
@ -367,7 +368,7 @@ public:
Q_INVOKABLE void setSkeletonOffset(const glm::vec3& offset);
/*@jsdoc
* Gets the offset applied to the current avatar. The offset adjusts the position that the avatar is rendered. For example,
* Gets the offset applied to the current avatar. The offset adjusts the position that the avatar is rendered. For example,
* with an offset of <code>{ x: 0, y: 0.1, z: 0 }</code>, your avatar will appear to be raised off the ground slightly.
* @function MyAvatar.getSkeletonOffset
* @returns {Vec3} The current skeleton offset.
@ -452,7 +453,7 @@ public:
/*@jsdoc
* Sets the ID of the entity or avatar that the avatar is parented to.
* @function MyAvatar.setParentID
* @param {Uuid} parentID - The ID of the entity or avatar that the avatar should be parented to. Set to
* @param {Uuid} parentID - The ID of the entity or avatar that the avatar should be parented to. Set to
* {@link Uuid(0)|Uuid.NULL} to unparent.
*/
// This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript.
@ -461,17 +462,17 @@ public:
/*@jsdoc
* Gets the joint of the entity or avatar that the avatar is parented to.
* @function MyAvatar.getParentJointIndex
* @returns {number} The joint of the entity or avatar that the avatar is parented to. <code>65535</code> or
* @returns {number} The joint of the entity or avatar that the avatar is parented to. <code>65535</code> or
* <code>-1</code> if parented to the entity or avatar's position and orientation rather than a joint.
*/
// This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript.
Q_INVOKABLE virtual quint16 getParentJointIndex() const override { return SpatiallyNestable::getParentJointIndex(); }
/*@jsdoc
* Sets the joint of the entity or avatar that the avatar is parented to.
* Sets the joint of the entity or avatar that the avatar is parented to.
* @function MyAvatar.setParentJointIndex
* @param {number} parentJointIndex - The joint of the entity or avatar that the avatar should be parented to. Use
* <code>65535</code> or <code>-1</code> to parent to the entity or avatar's position and orientation rather than a
* <code>65535</code> or <code>-1</code> to parent to the entity or avatar's position and orientation rather than a
* joint.
*/
// This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript.
@ -557,7 +558,7 @@ public:
signals:
/*@jsdoc
* Triggered when the avatar's target scale is changed. The target scale is the desired scale of the avatar without any
* Triggered when the avatar's target scale is changed. The target scale is the desired scale of the avatar without any
* restrictions on permissible scale values imposed by the domain.
* @function MyAvatar.targetScaleChanged
* @param {number} targetScale - The avatar's target scale.
@ -758,7 +759,7 @@ protected:
static void metaBlendshapeOperator(render::ItemID renderItemID, int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets,
const QVector<int>& blendedMeshSizes, const render::ItemIDs& subItemIDs);
std::vector<MultiSphereShape> _multiSphereShapes;
AABox _fitBoundingBox;
void clearAvatarGrabData(const QUuid& grabID) override;

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 4/10/17.
// Copyright 2017 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -87,10 +88,10 @@ public slots:
/*@jsdoc
* Gets the default rotation of a joint in the avatar relative to its parent.
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* @function ScriptAvatar.getDefaultJointRotation
* @param {number} index - The joint index.
* @returns {Quat} The default rotation of the joint if avatar data are available and the joint index is valid, otherwise
* @returns {Quat} The default rotation of the joint if avatar data are available and the joint index is valid, otherwise
* {@link Quat(0)|Quat.IDENTITY}.
*/
glm::quat getDefaultJointRotation(int index) const;
@ -99,10 +100,10 @@ public slots:
* Gets the default translation of a joint in the avatar relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* @function ScriptAvatar.getDefaultJointTranslation
* @param {number} index - The joint index.
* @returns {Vec3} The default translation of the joint (in model coordinates) if avatar data are available and the joint
* @returns {Vec3} The default translation of the joint (in model coordinates) if avatar data are available and the joint
* index is valid, otherwise {@link Vec3(0)|Vec3.ZERO}.
*/
glm::vec3 getDefaultJointTranslation(int index) const;
@ -120,7 +121,7 @@ public slots:
* Gets the position of a joint in the avatar.
* @function ScriptAvatar.getJointPosition
* @param {number} index - The index of the joint.
* @returns {Vec3} The position of the joint in world coordinates, or {@link Vec3(0)|Vec3.ZERO} if avatar data aren't
* @returns {Vec3} The position of the joint in world coordinates, or {@link Vec3(0)|Vec3.ZERO} if avatar data aren't
* available.
*/
glm::vec3 getJointPosition(int index) const;
@ -154,7 +155,7 @@ public slots:
/*@jsdoc
* Gets the ID of the entity or avatar that the avatar is parented to.
* @function ScriptAvatar.getParentID
* @returns {Uuid} The ID of the entity or avatar that the avatar is parented to. {@link Uuid(0)|Uuid.NULL} if not parented
* @returns {Uuid} The ID of the entity or avatar that the avatar is parented to. {@link Uuid(0)|Uuid.NULL} if not parented
* or avatar data aren't available.
*/
QUuid getParentID() const;
@ -163,7 +164,7 @@ public slots:
* Gets the joint of the entity or avatar that the avatar is parented to.
* @function ScriptAvatar.getParentJointIndex
* @returns {number} The joint of the entity or avatar that the avatar is parented to. <code>65535</code> or
* <code>-1</code> if parented to the entity or avatar's position and orientation rather than a joint, or avatar data
* <code>-1</code> if parented to the entity or avatar's position and orientation rather than a joint, or avatar data
* aren't available.
*/
quint16 getParentJointIndex() const;
@ -189,7 +190,7 @@ public slots:
/*@jsdoc
* Gets the position of the left palm in world coordinates.
* @function ScriptAvatar.getLeftPalmPosition
* @returns {Vec3} The position of the left palm in world coordinates, or {@link Vec3(0)|Vec3.ZERO} if avatar data aren't
* @returns {Vec3} The position of the left palm in world coordinates, or {@link Vec3(0)|Vec3.ZERO} if avatar data aren't
* available.
*/
glm::vec3 getLeftPalmPosition() const;
@ -197,7 +198,7 @@ public slots:
/*@jsdoc
* Gets the rotation of the left palm in world coordinates.
* @function ScriptAvatar.getLeftPalmRotation
* @returns {Quat} The rotation of the left palm in world coordinates, or {@link Quat(0)|Quat.IDENTITY} if the avatar data
* @returns {Quat} The rotation of the left palm in world coordinates, or {@link Quat(0)|Quat.IDENTITY} if the avatar data
* aren't available.
*/
glm::quat getLeftPalmRotation() const;

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 4/9/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -530,23 +531,23 @@ class AvatarData : public QObject, public SpatiallyNestable {
* avatar. <em>Read-only.</em>
* @property {number} sensorToWorldScale - The scale that transforms dimensions in the user's real world to the avatar's
* size in the virtual world. <em>Read-only.</em>
* @property {boolean} hasPriority - <code>true</code> if the avatar is in a "hero" zone, <code>false</code> if it isn't.
* @property {boolean} hasPriority - <code>true</code> if the avatar is in a "hero" zone, <code>false</code> if it isn't.
* <em>Read-only.</em>
* @property {boolean} hasScriptedBlendshapes=false - <code>true</code> if blend shapes are controlled by scripted actions,
* otherwise <code>false</code>. Set this to <code>true</code> before using the {@link Avatar.setBlendshape} method,
* @property {boolean} hasScriptedBlendshapes=false - <code>true</code> if blend shapes are controlled by scripted actions,
* otherwise <code>false</code>. Set this to <code>true</code> before using the {@link Avatar.setBlendshape} method,
* and set back to <code>false</code> after you no longer want scripted control over the blend shapes.
* <p><strong>Note:</strong> This property will automatically be set to <code>true</code> if the controller system has
* <p><strong>Note:</strong> This property will automatically be set to <code>true</code> if the controller system has
* valid facial blend shape actions.</p>
* @property {boolean} hasProceduralBlinkFaceMovement=true - <code>true</code> if avatars blink automatically by animating
* facial blend shapes, <code>false</code> if automatic blinking is disabled. Set to <code>false</code> to fully control
* @property {boolean} hasProceduralBlinkFaceMovement=true - <code>true</code> if avatars blink automatically by animating
* facial blend shapes, <code>false</code> if automatic blinking is disabled. Set to <code>false</code> to fully control
* the blink facial blend shapes via the {@link Avatar.setBlendshape} method.
* @property {boolean} hasProceduralEyeFaceMovement=true - <code>true</code> if the facial blend shapes for an avatar's eyes
* adjust automatically as the eyes move, <code>false</code> if this automatic movement is disabled. Set this property
* @property {boolean} hasProceduralEyeFaceMovement=true - <code>true</code> if the facial blend shapes for an avatar's eyes
* adjust automatically as the eyes move, <code>false</code> if this automatic movement is disabled. Set this property
* to <code>true</code> to prevent the iris from being obscured by the upper or lower lids. Set to <code>false</code> to
* fully control the eye blend shapes via the {@link Avatar.setBlendshape} method.
* @property {boolean} hasAudioEnabledFaceMovement=true - <code>true</code> if the avatar's mouth blend shapes animate
* automatically based on detected microphone input, <code>false</code> if this automatic movement is disabled. Set
* this property to <code>false</code> to fully control the mouth facial blend shapes via the
* @property {boolean} hasAudioEnabledFaceMovement=true - <code>true</code> if the avatar's mouth blend shapes animate
* automatically based on detected microphone input, <code>false</code> if this automatic movement is disabled. Set
* this property to <code>false</code> to fully control the mouth facial blend shapes via the
* {@link Avatar.setBlendshape} method.
*/
Q_PROPERTY(glm::vec3 position READ getWorldPosition WRITE setPositionViaScript)
@ -758,7 +759,7 @@ public:
void setDomainMaximumHeight(float domainMaximumHeight);
/*@jsdoc
* Sets the pointing state of the hands to control where the laser emanates from. If the right index finger is pointing, the
* Sets the pointing state of the hands to control where the laser emanates from. If the right index finger is pointing, the
* laser emanates from the tip of that finger, otherwise it emanates from the palm.
* @function Avatar.setHandState
* @param {HandState} state - The pointing state of the hand.
@ -787,9 +788,9 @@ public:
* Sets a specific joint's rotation and position relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.</p>
* @function Avatar.setJointData
* @param {number} index - The index of the joint.
@ -816,10 +817,10 @@ public:
/*@jsdoc
* Sets a specific joint's rotation relative to its parent.
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.</p>
* @function Avatar.setJointRotation
* @param {number} index - The index of the joint.
@ -831,9 +832,9 @@ public:
* Sets a specific joint's translation relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.</p>
* @function Avatar.setJointTranslation
* @param {number} index - The index of the joint.
@ -842,7 +843,7 @@ public:
Q_INVOKABLE virtual void setJointTranslation(int index, const glm::vec3& translation);
/*@jsdoc
* Clears joint translations and rotations set by script for a specific joint. This restores all motion from the default
* Clears joint translations and rotations set by script for a specific joint. This restores all motion from the default
* animation system including inverse kinematics for that joint.
* <p>Note: This is slightly faster than the function variation that specifies the joint name.</p>
* @function Avatar.clearJointData
@ -859,8 +860,8 @@ public:
Q_INVOKABLE bool isJointDataValid(int index) const;
/*@jsdoc
* Gets the rotation of a joint relative to its parent. For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.
* Gets the rotation of a joint relative to its parent. For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.
* @function Avatar.getJointRotation
* @param {number} index - The index of the joint.
* @returns {Quat} The rotation of the joint relative to its parent.
@ -870,8 +871,8 @@ public:
/*@jsdoc
* Gets the translation of a joint relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* @function Avatar.getJointTranslation
* @param {number} index - The index of the joint.
* @returns {Vec3} The translation of the joint relative to its parent, in model coordinates.
@ -882,9 +883,9 @@ public:
* Sets a specific joint's rotation and position relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.</p>
* @function Avatar.setJointData
* @param {string} name - The name of the joint.
@ -895,10 +896,10 @@ public:
/*@jsdoc
* Sets a specific joint's rotation relative to its parent.
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.</p>
* @function Avatar.setJointRotation
* @param {string} name - The name of the joint.
@ -930,19 +931,19 @@ public:
* Sets a specific joint's translation relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
* the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.</p>
* @function Avatar.setJointTranslation
* @param {string} name - The name of the joint.
* @param {Vec3} translation - The translation of the joint relative to its parent, in model coordinates.
* @example <caption>Stretch your avatar's neck. Depending on the avatar you are using, you will either see a gap between
* @example <caption>Stretch your avatar's neck. Depending on the avatar you are using, you will either see a gap between
* the head and body or you will see the neck stretched.<br />
* <img alt="Avatar with neck stretched" src="https://apidocs.vircadia.dev/images/stretched-neck.png" /></caption>
* // Stretch your avatar's neck.
* MyAvatar.setJointTranslation("Neck", Vec3.multiply(2, MyAvatar.getJointTranslation("Neck")));
*
*
* // Restore your avatar's neck after 5s.
* Script.setTimeout(function () {
* MyAvatar.clearJointData("Neck");
@ -953,7 +954,7 @@ public:
Q_INVOKABLE virtual void setJointTranslation(const QString& name, const glm::vec3& translation);
/*@jsdoc
* Clears joint translations and rotations set by script for a specific joint. This restores all motion from the default
* Clears joint translations and rotations set by script for a specific joint. This restores all motion from the default
* animation system including inverse kinematics for that joint.
* <p>Note: This is slightly slower than the function variation that specifies the joint index.</p>
* @function Avatar.clearJointData
@ -980,8 +981,8 @@ public:
Q_INVOKABLE virtual bool isJointDataValid(const QString& name) const;
/*@jsdoc
* Gets the rotation of a joint relative to its parent. For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.
* Gets the rotation of a joint relative to its parent. For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.
* @function Avatar.getJointRotation
* @param {string} name - The name of the joint.
* @returns {Quat} The rotation of the joint relative to its parent.
@ -996,7 +997,7 @@ public:
* Gets the translation of a joint relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* @function Avatar.getJointTranslation
* @param {number} name - The name of the joint.
* @returns {Vec3} The translation of the joint relative to its parent, in model coordinates.
@ -1010,7 +1011,7 @@ public:
/*@jsdoc
* Gets the rotations of all joints in the current avatar. Each joint's rotation is relative to its parent joint.
* @function Avatar.getJointRotations
* @returns {Quat[]} The rotations of all joints relative to each's parent. The values are in the same order as the array
* @returns {Quat[]} The rotations of all joints relative to each's parent. The values are in the same order as the array
* returned by {@link MyAvatar.getJointNames}, or {@link Avatar.getJointNames} if using the <code>Avatar</code> API.
* @example <caption>Report the rotations of all your avatar's joints.</caption>
* print(JSON.stringify(MyAvatar.getJointRotations()));
@ -1024,8 +1025,8 @@ public:
* model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* @function Avatar.getJointTranslations
* @returns {Vec3[]} The translations of all joints relative to each's parent, in model coordinates. The values are in the
* same order as the array returned by {@link MyAvatar.getJointNames}, or {@link Avatar.getJointNames} if using the
* @returns {Vec3[]} The translations of all joints relative to each's parent, in model coordinates. The values are in the
* same order as the array returned by {@link MyAvatar.getJointNames}, or {@link Avatar.getJointNames} if using the
* <code>Avatar</code> API.
*/
Q_INVOKABLE virtual QVector<glm::vec3> getJointTranslations() const;
@ -1038,7 +1039,7 @@ public:
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.</p>
* @function Avatar.setJointRotations
* @param {Quat[]} jointRotations - The rotations for all joints in the avatar. The values are in the same order as the
* @param {Quat[]} jointRotations - The rotations for all joints in the avatar. The values are in the same order as the
* array returned by {@link MyAvatar.getJointNames}, or {@link Avatar.getJointNames} if using the <code>Avatar</code> API.
* @example <caption>Set your avatar to its default T-pose then rotate its right arm.<br />
* <img alt="Avatar in T-pose" src="https://apidocs.vircadia.dev/images/armpose.png" /></caption>
@ -1051,7 +1052,7 @@ public:
* }
*
* // Get all join rotations.
* var jointRotations = MyAvatar.getJointRotations();
* var jointRotations = MyAvatar.getJointRotations();
*
* // Update the rotation of the right arm in the array.
* jointRotations[MyAvatar.getJointIndex("RightArm")] = { x: 0.47, y: 0.22, z: -0.02, w: 0.87 };
@ -1067,9 +1068,9 @@ public:
* // Note: If using from the Avatar API, replace all occurrences of "MyAvatar" with "Avatar".
*/
Q_INVOKABLE virtual void setJointRotations(const QVector<glm::quat>& jointRotations);
/*@jsdoc
* Sets the translations of all joints in the current avatar. Each joint's translation is relative to its parent joint, in
* Sets the translations of all joints in the current avatar. Each joint's translation is relative to its parent joint, in
* model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>Setting joint data completely overrides/replaces all motion from the default animation system including inverse
@ -1078,14 +1079,14 @@ public:
* joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.</p>
* @function Avatar.setJointTranslations
* @param {Vec3[]} translations - The translations for all joints in the avatar, in model coordinates. The values are in
* the same order as the array returned by {@link MyAvatar.getJointNames}, or {@link Avatar.getJointNames} if using the
* @param {Vec3[]} translations - The translations for all joints in the avatar, in model coordinates. The values are in
* the same order as the array returned by {@link MyAvatar.getJointNames}, or {@link Avatar.getJointNames} if using the
* <code>Avatar</code> API.
*/
Q_INVOKABLE virtual void setJointTranslations(const QVector<glm::vec3>& jointTranslations);
/*@jsdoc
* Clears all joint translations and rotations that have been set by script. This restores all motion from the default
* Clears all joint translations and rotations that have been set by script. This restores all motion from the default
* animation system including inverse kinematics for all joints.
* @function Avatar.clearJointsData
* @example <caption>Set your avatar to it's default T-pose for a while.</caption>
@ -1107,7 +1108,7 @@ public:
Q_INVOKABLE virtual void clearJointsData();
/*@jsdoc
* Gets the joint index for a named joint. The joint index value is the position of the joint in the array returned by
* Gets the joint index for a named joint. The joint index value is the position of the joint in the array returned by
* {@link MyAvatar.getJointNames}, or {@link Avatar.getJointNames} if using the <code>Avatar</code> API.
* @function Avatar.getJointIndex
* @param {string} name - The name of the joint.
@ -1133,12 +1134,12 @@ public:
/*@jsdoc
* Sets the value of a blend shape to animate your avatar's face. In order for other users to see the resulting animations
* on your avatar's face, set <code>hasScriptedBlendshapes</code> to <code>true</code>. When you are done using this API,
* set <code>hasScriptedBlendshapes</code> back to <code>false</code> when the animation is complete.
* Sets the value of a blend shape to animate your avatar's face. In order for other users to see the resulting animations
* on your avatar's face, set <code>hasScriptedBlendshapes</code> to <code>true</code>. When you are done using this API,
* set <code>hasScriptedBlendshapes</code> back to <code>false</code> when the animation is complete.
* @function Avatar.setBlendshape
* @param {string} name - The name of the blendshape, per the
* {@link https://docs.vircadia.dev/create/avatars/avatar-standards.html#blendshapes Avatar Standards}.
* @param {string} name - The name of the blendshape, per the
* {@link https://docs.vircadia.com/create/avatars/avatar-standards.html#blendshapes Avatar Standards}.
* @param {number} value - A value between <code>0.0</code> and <code>1.0</code>.
* @example <caption>Open your avatar's mouth wide.</caption>
* MyAvatar.hasScriptedBlendshapes = true;
@ -1160,7 +1161,7 @@ public:
/*@jsdoc
* Sets all models currently attached to your avatar. For example, if you retrieve attachment data using
* {@link MyAvatar.getAttachmentsVariant} or {@link Avatar.getAttachmentsVariant}, make changes to it, and then want to
* {@link MyAvatar.getAttachmentsVariant} or {@link Avatar.getAttachmentsVariant}, make changes to it, and then want to
* update your avatar's attachments per the changed data.
* @function Avatar.setAttachmentsVariant
* @param {AttachmentData[]} variant - The attachment data defining the models to have attached to your avatar.
@ -1186,7 +1187,7 @@ public:
* @deprecated This function is deprecated and will be removed.
*/
Q_INVOKABLE virtual void clearAvatarEntity(const QUuid& entityID, bool requiresRemovalFromTree = true);
// FIXME: Rename to clearAvatarEntity() once the API call is removed.
virtual void clearAvatarEntityInternal(const QUuid& entityID);
@ -1195,12 +1196,12 @@ public:
QList<QUuid> getAvatarEntityIDs() const;
/*@jsdoc
* Enables blend shapes set using {@link Avatar.setBlendshape} or {@link MyAvatar.setBlendshape} to be transmitted to other
* Enables blend shapes set using {@link Avatar.setBlendshape} or {@link MyAvatar.setBlendshape} to be transmitted to other
* users so that they can see the animation of your avatar's face.
* <p class="important">Deprecated: This method is deprecated and will be removed. Use the
* <p class="important">Deprecated: This method is deprecated and will be removed. Use the
* <code>Avatar.hasScriptedBlendshapes</code> or <code>MyAvatar.hasScriptedBlendshapes</code> property instead.</p>
* @function Avatar.setForceFaceTrackerConnected
* @param {boolean} connected - <code>true</code> to enable blend shape changes to be transmitted to other users,
* @param {boolean} connected - <code>true</code> to enable blend shape changes to be transmitted to other users,
* <code>false</code> to disable.
*/
Q_INVOKABLE void setForceFaceTrackerConnected(bool connected) { setHasScriptedBlendshapes(connected); }
@ -1274,7 +1275,7 @@ public:
/*@jsdoc
* Sets all models currently attached to your avatar. For example, if you retrieve attachment data using
* {@link MyAvatar.getAttachmentData} or {@link Avatar.getAttachmentData}, make changes to it, and then want to update your avatar's attachments per the
* {@link MyAvatar.getAttachmentData} or {@link Avatar.getAttachmentData}, make changes to it, and then want to update your avatar's attachments per the
* changed data. You can also remove all attachments by using setting <code>attachmentData</code> to <code>null</code>.
* @function Avatar.setAttachmentData
* @param {AttachmentData[]} attachmentData - The attachment data defining the models to have attached to your avatar. Use
@ -1300,19 +1301,19 @@ public:
* Attaches a model to your avatar. For example, you can give your avatar a hat to wear, a guitar to hold, or a surfboard to
* stand on.
* @function Avatar.attach
* @param {string} modelURL - The URL of the glTF, FBX, or OBJ model to attach. glTF models may be in JSON or binary format
* @param {string} modelURL - The URL of the glTF, FBX, or OBJ model to attach. glTF models may be in JSON or binary format
* (".gltf" or ".glb" URLs respectively).
* @param {string} [jointName=""] - The name of the avatar joint (see {@link MyAvatar.getJointNames} or
* @param {string} [jointName=""] - The name of the avatar joint (see {@link MyAvatar.getJointNames} or
* {@link Avatar.getJointNames}) to attach the model to.
* @param {Vec3} [translation=Vec3.ZERO] - The offset to apply to the model relative to the joint position.
* @param {Quat} [rotation=Quat.IDENTITY] - The rotation to apply to the model relative to the joint orientation.
* @param {number} [scale=1.0] - The scale to apply to the model.
* @param {boolean} [isSoft=false] - If the model has a skeleton, set this to <code>true</code> so that the bones of the
* attached model's skeleton are rotated to fit the avatar's current pose. <code>isSoft</code> is used, for example,
* @param {boolean} [isSoft=false] - If the model has a skeleton, set this to <code>true</code> so that the bones of the
* attached model's skeleton are rotated to fit the avatar's current pose. <code>isSoft</code> is used, for example,
* to have clothing that moves with the avatar.
* <p>If <code>true</code>, the <code>translation</code>, <code>rotation</code>, and <code>scale</code> parameters are
* <p>If <code>true</code>, the <code>translation</code>, <code>rotation</code>, and <code>scale</code> parameters are
* ignored.</p>
* @param {boolean} [allowDuplicates=false] - If <code>true</code> then more than one copy of any particular model may be
* @param {boolean} [allowDuplicates=false] - If <code>true</code> then more than one copy of any particular model may be
* attached to the same joint; if <code>false</code> then the same model cannot be attached to the same joint.
* @param {boolean} [useSaved=true] - <em>Not used.</em>
* @deprecated This function is deprecated and will be removed. Use avatar entities instead.
@ -1344,7 +1345,7 @@ public:
* Detaches the most recently attached instance of a particular model from either a specific joint or any joint.
* @function Avatar.detachOne
* @param {string} modelURL - The URL of the model to detach.
* @param {string} [jointName=""] - The name of the joint to detach the model from. If <code>""</code>, then the most
* @param {string} [jointName=""] - The name of the joint to detach the model from. If <code>""</code>, then the most
* recently attached model is removed from which ever joint it was attached to.
* @deprecated This function is deprecated and will be removed. Use avatar entities instead.
*/
@ -1354,7 +1355,7 @@ public:
* Detaches all instances of a particular model from either a specific joint or all joints.
* @function Avatar.detachAll
* @param {string} modelURL - The URL of the model to detach.
* @param {string} [jointName=""] - The name of the joint to detach the model from. If <code>""</code>, then the model is
* @param {string} [jointName=""] - The name of the joint to detach the model from. If <code>""</code>, then the model is
* detached from all joints.
* @deprecated This function is deprecated and will be removed. Use avatar entities instead.
*/
@ -1414,7 +1415,7 @@ public:
/*@jsdoc
* Gets the transform from the user's real world to the avatar's size, orientation, and position in the virtual world.
* @function Avatar.getSensorToWorldMatrix
* @returns {Mat4} The scale, rotation, and translation transform from the user's real world to the avatar's size,
* @returns {Mat4} The scale, rotation, and translation transform from the user's real world to the avatar's size,
* orientation, and position in the virtual world.
* @example <caption>Report the sensor to world matrix.</caption>
* var sensorToWorldMatrix = MyAvatar.getSensorToWorldMatrix();
@ -1431,7 +1432,7 @@ public:
/*@jsdoc
* Gets the scale that transforms dimensions in the user's real world to the avatar's size in the virtual world.
* @function Avatar.getSensorToWorldScale
* @returns {number} The scale that transforms dimensions in the user's real world to the avatar's size in the virtual
* @returns {number} The scale that transforms dimensions in the user's real world to the avatar's size in the virtual
* world.
*/
// thread safe
@ -1661,7 +1662,7 @@ public slots:
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; }
/*@jsdoc
* Gets the target scale of the avatar without any restrictions on permissible values imposed by the domain. In contrast, the
* Gets the target scale of the avatar without any restrictions on permissible values imposed by the domain. In contrast, the
* <code>scale</code> property's value may be limited by the domain's settings.
* @function Avatar.getTargetScale
* @returns {number} The target scale of the avatar.
@ -1703,7 +1704,7 @@ protected:
void unpackSkeletonModelURL(const QByteArray& data);
void unpackSkeletonData(const QByteArray& data);
// isReplicated will be true on downstream Avatar Mixers and their clients, but false on the upstream "master"
// Audio Mixer that the replicated avatar is connected to.
bool _isReplicated{ false };

View file

@ -4,6 +4,7 @@
//
// Created by Zach Fox on 2017-04-10.
// Copyright 2017 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -117,10 +118,10 @@ public:
/*@jsdoc
* Gets the rotation of a joint relative to its parent. For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.
* @function ScriptAvatar.getJointRotation
* @param {number} index - The index of the joint.
* @returns {Quat} The rotation of the joint relative to its parent, or {@link Quat(0)|Quat.IDENTITY} if the avatar data
* @returns {Quat} The rotation of the joint relative to its parent, or {@link Quat(0)|Quat.IDENTITY} if the avatar data
* aren't available.
*/
Q_INVOKABLE glm::quat getJointRotation(int index) const;
@ -129,20 +130,20 @@ public:
* Gets the translation of a joint relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* @function ScriptAvatar.getJointTranslation
* @param {number} index - The index of the joint.
* @returns {Vec3} The translation of the joint relative to its parent, in model coordinates, or {@link Vec3(0)|Vec3.ZERO}
* @returns {Vec3} The translation of the joint relative to its parent, in model coordinates, or {@link Vec3(0)|Vec3.ZERO}
* if the avatar data aren't available.
*/
Q_INVOKABLE glm::vec3 getJointTranslation(int index) const;
/*@jsdoc
* Gets the rotation of a joint relative to its parent. For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.
* @function ScriptAvatar.getJointRotation
* @param {string} name - The name of the joint.
* @returns {Quat} The rotation of the joint relative to its parent, or {@link Quat(0)|Quat.IDENTITY} if the avatar data
* @returns {Quat} The rotation of the joint relative to its parent, or {@link Quat(0)|Quat.IDENTITY} if the avatar data
* aren't available.
*/
Q_INVOKABLE glm::quat getJointRotation(const QString& name) const;
@ -151,10 +152,10 @@ public:
* Gets the translation of a joint relative to its parent, in model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* <p>For information on the joint hierarchy used, see
* <a href="https://docs.vircadia.dev/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* <a href="https://docs.vircadia.com/create/avatars/avatar-standards.html">Avatar Standards</a>.</p>
* @function ScriptAvatar.getJointTranslation
* @param {number} name - The name of the joint.
* @returns {Vec3} The translation of the joint relative to its parent, in model coordinates, or {@link Vec3(0)|Vec3.ZERO}
* @returns {Vec3} The translation of the joint relative to its parent, in model coordinates, or {@link Vec3(0)|Vec3.ZERO}
* if the avatar data aren't available.
*/
Q_INVOKABLE glm::vec3 getJointTranslation(const QString& name) const;
@ -162,7 +163,7 @@ public:
/*@jsdoc
* Gets the rotations of all joints in the avatar. Each joint's rotation is relative to its parent joint.
* @function ScriptAvatar.getJointRotations
* @returns {Quat[]} The rotations of all joints relative to each's parent, or <code>[]</code> if the avatar data aren't
* @returns {Quat[]} The rotations of all joints relative to each's parent, or <code>[]</code> if the avatar data aren't
* available. The values are in the same order as the array returned by {@link ScriptAvatar.getJointNames}.
*/
Q_INVOKABLE QVector<glm::quat> getJointRotations() const;
@ -172,8 +173,8 @@ public:
* model coordinates.
* <p><strong>Warning:</strong> These coordinates are not necessarily in meters.</p>
* @function ScriptAvatar.getJointTranslations
* @returns {Vec3[]} The translations of all joints relative to each's parent, in model coordinates, or <code>[]</code> if
* the avatar data aren't available. The values are in the same order as the array returned by
* @returns {Vec3[]} The translations of all joints relative to each's parent, in model coordinates, or <code>[]</code> if
* the avatar data aren't available. The values are in the same order as the array returned by
* {@link ScriptAvatar.getJointNames}.
*/
Q_INVOKABLE QVector<glm::vec3> getJointTranslations() const;
@ -182,7 +183,7 @@ public:
* Checks that the data for a joint are valid.
* @function ScriptAvatar.isJointDataValid
* @param {number} index - The index of the joint.
* @returns {boolean} <code>true</code> if the joint data are valid, <code>false</code> if not or the avatar data aren't
* @returns {boolean} <code>true</code> if the joint data are valid, <code>false</code> if not or the avatar data aren't
* available.
*/
Q_INVOKABLE bool isJointDataValid(const QString& name) const;
@ -206,7 +207,7 @@ public:
/*@jsdoc
* Gets information about the models currently attached to the avatar.
* @function ScriptAvatar.getAttachmentData
* @returns {AttachmentData[]} Information about all models attached to the avatar, or <code>[]</code> if the avatar data
* @returns {AttachmentData[]} Information about all models attached to the avatar, or <code>[]</code> if the avatar data
* aren't available.
* @deprecated This function is deprecated and will be removed. Use avatar entities instead.
*/
@ -228,7 +229,7 @@ public:
glm::mat4 getSensorToWorldMatrix() const;
glm::mat4 getControllerLeftHandMatrix() const;
glm::mat4 getControllerRightHandMatrix() const;
bool getHasPriority() const;
signals:
@ -268,7 +269,7 @@ public slots:
* Gets the rotation of a joint relative to the avatar.
* @function ScriptAvatar.getAbsoluteJointRotationInObjectFrame
* @param {number} index - The index of the joint.
* @returns {Quat} The rotation of the joint relative to the avatar, or {@link Quat(0)|Quat.IDENTITY} if the avatar data
* @returns {Quat} The rotation of the joint relative to the avatar, or {@link Quat(0)|Quat.IDENTITY} if the avatar data
* aren't available.
*/
glm::quat getAbsoluteJointRotationInObjectFrame(int index) const;
@ -277,7 +278,7 @@ public slots:
* Gets the translation of a joint relative to the avatar.
* @function ScriptAvatar.getAbsoluteJointTranslationInObjectFrame
* @param {number} index - The index of the joint.
* @returns {Vec3} The translation of the joint relative to the avatar, or {@link Vec3(0)|Vec3.ZERO} if the avatar data
* @returns {Vec3} The translation of the joint relative to the avatar, or {@link Vec3(0)|Vec3.ZERO} if the avatar data
* aren't available.
*/
glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const;

View file

@ -738,7 +738,7 @@ Mapping::Pointer UserInputMapper::newMapping(const QString& mappingName) {
// if (request->getResult() == ResourceRequest::Success) {
// result = parseMapping(QString(request->getData()));
// } else {
// qCWarning(controllers) << "Failed to load mapping url <" << jsonUrl << ">" << endl;
// qCWarning(controllers) << "Failed to load mapping url <" << jsonUrl << ">" << Qt::endl;
// }
// request->deleteLater();
// }
@ -1177,13 +1177,13 @@ Mapping::Pointer UserInputMapper::parseMapping(const QString& json) {
if (doc.isNull()) {
qCDebug(controllers) << "Invalid JSON...\n";
qCDebug(controllers) << error.errorString();
qCDebug(controllers) << "JSON was:\n" << json << endl;
qCDebug(controllers) << "JSON was:\n" << json << Qt::endl;
return Mapping::Pointer();
}
if (!doc.isObject()) {
qWarning() << "Mapping json Document is not an object" << endl;
qCDebug(controllers) << "JSON was:\n" << json << endl;
qWarning() << "Mapping json Document is not an object" << Qt::endl;
qCDebug(controllers) << "JSON was:\n" << json << Qt::endl;
return Mapping::Pointer();
}
return parseMapping(doc.object());

View file

@ -495,6 +495,15 @@ void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const st
emit requestRenderUpdate();
}
graphics::MaterialPointer EntityRenderer::getTopMaterial() {
std::lock_guard<std::mutex> lock(_materialsLock);
auto materials = _materials.find("0");
if (materials != _materials.end()) {
return materials->second.top().material;
}
return nullptr;
}
EntityRenderer::Pipeline EntityRenderer::getPipelineType(const graphics::MultiMaterial& materials) {
if (materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) {
return Pipeline::PROCEDURAL;
@ -626,6 +635,7 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
{
std::lock_guard<std::mutex> lock(_materialsLock);
materials = _materials.find("0");
if (materials != _materials.end()) {
if (materials->second.shouldUpdate()) {
RenderPipelines::updateMultiMaterial(materials->second);
@ -653,7 +663,6 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
auto pipelineType = getPipelineType(materials->second);
if (pipelineType == Pipeline::MATERIAL) {
builder.withMaterial();
if (drawMaterialKey.isNormalMap()) {
builder.withTangents();
}

View file

@ -62,7 +62,9 @@ public:
};
virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName);
virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName);
virtual graphics::MaterialPointer getTopMaterial();
static Pipeline getPipelineType(const graphics::MultiMaterial& materials);
virtual gpu::TexturePointer getTexture() { return nullptr; }
virtual scriptable::ScriptableModelBase getScriptableModel() override { return scriptable::ScriptableModelBase(); }

View file

@ -198,10 +198,8 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
procedural->prepare(*batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created, ProceduralProgramKey(transparent));
} else if (pipelineType == Pipeline::SIMPLE) {
batch->setResourceTexture(0, _texture->getGPUTexture());
} else {
if (RenderPipelines::bindMaterials(materials, *batch, args->_renderMode, args->_enableTexturing)) {
args->_details._materialSwitches++;
}
} else if (RenderPipelines::bindMaterials(materials, *batch, args->_renderMode, args->_enableTexturing)) {
args->_details._materialSwitches++;
}
DependencyManager::get<GeometryCache>()->renderQuad(

View file

@ -24,6 +24,8 @@ public:
ImageEntityRenderer(const EntityItemPointer& entity);
~ImageEntityRenderer();
gpu::TexturePointer getTexture() override { return _texture ? _texture->getGPUTexture() : nullptr; }
protected:
Item::Bound getBound(RenderArgs* args) override;
ShapeKey getShapeKey() override;

View file

@ -79,26 +79,42 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
}
}
bool usingMaterialData = _materialURL.startsWith("materialData");
bool usingEntityID = _materialURL.startsWith("{");
bool materialDataChanged = false;
bool urlChanged = false;
std::string newCurrentMaterialName = _currentMaterialName;
QString targetEntityID = _materialURL;
{
QString materialURL = entity->getMaterialURL();
if (materialURL != _materialURL) {
_materialURL = materialURL;
usingMaterialData = _materialURL.startsWith("materialData");
usingEntityID = _materialURL.startsWith("{");
targetEntityID = _materialURL;
if (_materialURL.contains("#")) {
auto split = _materialURL.split("#");
newCurrentMaterialName = split.last().toStdString();
if (usingEntityID) {
targetEntityID = split.first();
}
} else if (_materialURL.contains("?")) {
qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL;
auto split = _materialURL.split("?");
newCurrentMaterialName = split.last().toStdString();
if (usingEntityID) {
targetEntityID = split.first();
}
}
if (usingMaterialData) {
materialDataChanged = true;
} else {
urlChanged = true;
}
urlChanged = true;
}
}
bool usingMaterialData = _materialURL.startsWith("materialData");
bool materialDataChanged = false;
QUuid oldParentID = _parentID;
QString oldParentMaterialName = _parentMaterialName;
{
@ -135,7 +151,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
}
}
if (urlChanged && !usingMaterialData) {
if (urlChanged && !usingMaterialData && !usingEntityID) {
_networkMaterial = DependencyManager::get<MaterialCache>()->getMaterial(_materialURL);
auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) {
deleteMaterial(oldParentID, oldParentMaterialName);
@ -159,6 +175,13 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
});
}
}
} else if (urlChanged && usingEntityID) {
deleteMaterial(oldParentID, oldParentMaterialName);
_texturesLoaded = true;
_parsedMaterials = NetworkMaterialResource::parseMaterialForUUID(QJsonValue(targetEntityID));
// Since our material changed, the current name might not be valid anymore, so we need to update
setCurrentMaterialName(newCurrentMaterialName);
applyMaterial(entity);
} else if (materialDataChanged && usingMaterialData) {
deleteMaterial(oldParentID, oldParentMaterialName);
_texturesLoaded = false;
@ -167,6 +190,10 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
setCurrentMaterialName(newCurrentMaterialName);
applyMaterial(entity);
} else {
if (newCurrentMaterialName != _currentMaterialName) {
setCurrentMaterialName(newCurrentMaterialName);
}
if (deleteNeeded) {
deleteMaterial(oldParentID, oldParentMaterialName);
}

View file

@ -26,6 +26,8 @@ public:
MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {}
~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); }
graphics::MaterialPointer getTopMaterial() override { return getMaterial(); }
private:
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;

View file

@ -274,6 +274,7 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
// Try to update the texture
OffscreenQmlSurface::TextureAndFence newTextureAndFence;
QSize windowSize;
bool newTextureAvailable = false;
if (!resultWithReadLock<bool>([&] {
if (!_webSurface) {
@ -281,6 +282,7 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
}
newTextureAvailable = _webSurface->fetchTexture(newTextureAndFence);
windowSize = _webSurface->size();
return true;
})) {
return;
@ -288,6 +290,8 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
if (newTextureAvailable) {
_texture->setExternalTexture(newTextureAndFence.first, newTextureAndFence.second);
_texture->setSize(windowSize.width(), windowSize.height());
_texture->setOriginalSize(windowSize.width(), windowSize.height());
}
static const glm::vec2 texMin(0.0f), texMax(1.0f), topLeft(-0.5f), bottomRight(0.5f);

View file

@ -55,6 +55,8 @@ public:
virtual void setProxyWindow(QWindow* proxyWindow) override;
virtual QObject* getEventHandler() override;
gpu::TexturePointer getTexture() override { return _texture; }
protected:
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;

View file

@ -951,10 +951,11 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
*
* @typedef {object} Entities.EntityProperties-Material
* @property {Vec3} dimensions=0.1,0.1,0.1 - Used when <code>materialMappingMode == "projected"</code>.
* @property {string} materialURL="" - URL to a {@link Entities.MaterialResource|MaterialResource}. If you append
* <code>"#name"</code> to the URL, the material with that name in the {@link Entities.MaterialResource|MaterialResource}
* will be applied to the entity. Alternatively, set the property value to <code>"materialData"</code> to use the
* <code>materialData</code> property for the {@link Entities.MaterialResource|MaterialResource} values.
* @property {string} materialURL="" - URL to a {@link Entities.MaterialResource|MaterialResource}. Alternatively, set the
* property value to <code>"materialData"</code> to use the <code>materialData</code> property for the
* {@link Entities.MaterialResource|MaterialResource} values. If you append <code>"#name"</code> to the URL, the material
* with that name will be applied to the entity. You can also use the ID of another Material entity as the URL, in which
* case this material will act as a copy of that material, with its own unique material transform, priority, etc.
* @property {string} materialData="" - Used to store {@link Entities.MaterialResource|MaterialResource} data as a JSON string.
* You can use <code>JSON.parse()</code> to parse the string into a JavaScript object which you can manipulate the
* properties of, and use <code>JSON.stringify()</code> to convert the object into a string to put in the property.
@ -1379,7 +1380,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
/*@jsdoc
* The <code>"Web"</code> {@link Entities.EntityType|EntityType} displays a browsable web page. Each user views their own copy
* of the web page: if one user navigates to another page on the entity, other users do not see the change; if a video is being
* played, users don't see it in sync. It has properties in addition to the common
* played, users don't see it in sync. Internally, a Web entity is rendered as a non-repeating, upside down texture, so additional
* transformations may be necessary if you reference a Web entity texture by UUID. It has properties in addition to the common
* {@link Entities.EntityProperties|EntityProperties}.
*
* @typedef {object} Entities.EntityProperties-Web

View file

@ -2751,6 +2751,47 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
return map.values().toVector();
}
QJsonValue replaceEntityIDsInJSONHelper(const QJsonValue& jsonValue, std::function<EntityItemID(EntityItemID)> getMapped) {
if (jsonValue.isString()) {
QString stringValue = jsonValue.toString();
QUuid oldID = stringValue;
if (!oldID.isNull()) {
return QJsonValue(getMapped(oldID).toString());
}
return stringValue;
} else if (jsonValue.isArray()) {
QJsonArray jsonArray = jsonValue.toArray();
for (int i = 0; i < jsonArray.count(); i++) {
jsonArray[i] = replaceEntityIDsInJSONHelper(jsonArray[i], getMapped);
}
return jsonArray;
} else if (jsonValue.isObject()) {
QJsonObject jsonObject = jsonValue.toObject();
auto keys = jsonObject.keys();
for (auto& key : keys) {
auto value = jsonObject.value(key);
jsonObject[key] = replaceEntityIDsInJSONHelper(value, getMapped);
}
return jsonObject;
} else {
return jsonValue;
}
}
QString replaceEntityIDsInJSON(const QString& json, std::function<EntityItemID(EntityItemID)> getMapped) {
QJsonDocument document = QJsonDocument::fromJson(json.toUtf8());
if (!document.isNull() && document.isObject()) {
QJsonObject jsonObject = document.object();
auto keys = jsonObject.keys();
for (auto& key : keys) {
auto value = jsonObject.value(key);
jsonObject[key] = replaceEntityIDsInJSONHelper(value, getMapped);
}
document = QJsonDocument(jsonObject);
}
return document.toJson();
}
bool EntityTree::sendEntitiesOperation(const OctreeElementPointer& element, void* extraData) {
SendEntitiesOperationArgs* args = static_cast<SendEntitiesOperationArgs*>(extraData);
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
@ -2819,6 +2860,61 @@ bool EntityTree::sendEntitiesOperation(const OctreeElementPointer& element, void
QByteArray actionData = properties.getActionData();
properties.setActionData(remapActionDataIDs(actionData, *args->map));
{
QString materialURL = properties.getMaterialURL();
QString uuidString = materialURL;
QString materialName = "";
if (materialURL.contains("?")) {
QStringList split = materialURL.split("?");
uuidString = split[0];
if (split.length() > 1) {
materialName = split[1];
}
} else if (materialURL.contains("#")) {
QStringList split = materialURL.split("#");
uuidString = split[0];
if (split.length() > 1) {
materialName = split[1];
}
}
QUuid oldID = uuidString;
if (!oldID.isNull()) {
uuidString = getMapped(oldID).toString();
}
QUuid oldMaterialName = materialName;
if (!oldMaterialName.isNull()) {
materialName = getMapped(oldMaterialName).toString();
}
if (!materialName.isEmpty()) {
properties.setMaterialURL(uuidString + "?" + materialName);
} else {
properties.setMaterialURL(uuidString);
}
}
QString imageURL = properties.getImageURL();
if (imageURL.startsWith("{")) {
QUuid oldID = imageURL;
if (!oldID.isNull()) {
properties.setImageURL(getMapped(oldID).toString());
}
}
QString materialData = properties.getMaterialData();
if (!materialData.isEmpty()) {
materialData = replaceEntityIDsInJSON(materialData, getMapped);
properties.setMaterialData(materialData);
}
QString userData = properties.getUserData();
if (!userData.isEmpty()) {
userData = replaceEntityIDsInJSON(userData, getMapped);
properties.setUserData(userData);
}
// set creation time to "now" for imported entities
properties.setCreated(usecTimestampNow());

View file

@ -322,6 +322,16 @@ bool Texture::isDepthStencilRenderTarget() const {
return (_texelFormat.getSemantic() == gpu::DEPTH) || (_texelFormat.getSemantic() == gpu::DEPTH_STENCIL);
}
void Texture::setSize(int width, int height) {
_width = width;
_height = height;
}
void Texture::setOriginalSize(int width, int height) {
_originalWidth = width;
_originalHeight = height;
}
uint16 Texture::evalDimMaxNumMips(uint16 size) {
double largerDim = size;
double val = log(largerDim)/log(2.0);
@ -887,16 +897,34 @@ void SphericalHarmonics::evalFromTexture(const Texture& texture, gpu::BackendTar
// TextureSource
void TextureSource::resetTexture(gpu::TexturePointer texture) {
const gpu::TexturePointer TextureSource::getGPUTexture() const {
if (_gpuTextureOperator && !_locked) {
_locked = true;
auto gpuTexture = _gpuTextureOperator();
_locked = false;
return gpuTexture;
}
return _gpuTexture;
}
void TextureSource::resetTexture(const gpu::TexturePointer& texture) {
_gpuTexture = texture;
_gpuTextureOperator = nullptr;
}
void TextureSource::resetTextureOperator(const std::function<gpu::TexturePointer()>& textureOperator) {
_gpuTexture = nullptr;
_gpuTextureOperator = textureOperator;
}
bool TextureSource::isDefined() const {
if (_gpuTexture) {
return _gpuTexture->isDefined();
} else {
return false;
if (_gpuTextureOperator && !_locked) {
_locked = true;
auto gpuTexture = _gpuTextureOperator();
_locked = false;
return gpuTexture && gpuTexture->isDefined();
}
return _gpuTexture && _gpuTexture->isDefined();
}
bool Texture::setMinMip(uint16 newMinMip) {
@ -930,6 +958,7 @@ void Texture::setExternalTexture(uint32 externalId, void* externalFence) {
Lock lock(_externalMutex);
assert(_externalRecycler);
_externalUpdates.push_back({ externalId, externalFence });
_defined = true;
}
Texture::ExternalUpdates Texture::getUpdates() const {

View file

@ -417,11 +417,16 @@ public:
Element getTexelFormat() const { return _texelFormat; }
void setSize(int width, int height);
Vec3u getDimensions() const { return Vec3u(_width, _height, _depth); }
uint16 getWidth() const { return _width; }
uint16 getHeight() const { return _height; }
uint16 getDepth() const { return _depth; }
void setOriginalSize(int width, int height);
int getOriginalWidth() const { return _originalWidth; }
int getOriginalHeight() const { return _originalHeight; }
// The number of faces is mostly used for cube map, and maybe for stereo ? otherwise it's 1
// For cube maps, this means the pixels of the different faces are supposed to be packed back to back in a mip
// as if the height was NUM_FACES time bigger.
@ -615,6 +620,8 @@ protected:
uint16 _width { 1 };
uint16 _height { 1 };
uint16 _depth { 1 };
int _originalWidth { 0 };
int _originalHeight { 0 };
uint16 _numSamples { 1 };
@ -676,9 +683,10 @@ public:
_element(element)
{};
TextureView(const TexturePointer& texture, uint16 subresource) :
TextureView(const TexturePointer& texture, uint16 subresource, std::function<gpu::TexturePointer()> textureOperator = nullptr) :
_texture(texture),
_subresource(subresource)
_subresource(subresource),
_textureOperator(textureOperator)
{};
~TextureView() {}
@ -689,6 +697,12 @@ public:
bool operator !() const { return (!_texture); }
bool isValid() const { return bool(_texture); }
bool isReference() const { return (bool)_textureOperator; }
std::function<gpu::TexturePointer()> getTextureOperator() const { return _textureOperator; }
private:
std::function<gpu::TexturePointer()> _textureOperator { nullptr };
};
typedef std::vector<TextureView> TextureViews;
@ -700,16 +714,20 @@ public:
void setUrl(const QUrl& url) { _imageUrl = url; }
const QUrl& getUrl() const { return _imageUrl; }
const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; }
const gpu::TexturePointer getGPUTexture() const;
void setType(int type) { _type = type; }
int getType() const { return _type; }
void resetTexture(gpu::TexturePointer texture);
void resetTexture(const gpu::TexturePointer& texture);
void resetTextureOperator(const std::function<gpu::TexturePointer()>& textureOperator);
bool isDefined() const;
std::function<gpu::TexturePointer()> getTextureOperator() const { return _gpuTextureOperator; }
protected:
gpu::TexturePointer _gpuTexture;
std::function<gpu::TexturePointer()> _gpuTextureOperator { nullptr };
mutable bool _locked { false };
QUrl _imageUrl;
int _type { 0 };
};

View file

@ -281,4 +281,33 @@ void MultiMaterial::calculateMaterialInfo() const {
}
_hasCalculatedTextureInfo = allTextures;
}
}
}
void MultiMaterial::resetReferenceTexturesAndMaterials() {
_referenceTextures.clear();
_referenceMaterials.clear();
}
void MultiMaterial::addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator) {
_referenceTextures.emplace_back(textureOperator, textureOperator());
}
void MultiMaterial::addReferenceMaterial(const std::function<graphics::MaterialPointer()>& materialOperator) {
_referenceMaterials.emplace_back(materialOperator, materialOperator());
}
bool MultiMaterial::anyReferenceMaterialsOrTexturesChanged() const {
for (auto textureOperatorPair : _referenceTextures) {
if (textureOperatorPair.first() != textureOperatorPair.second) {
return true;
}
}
for (auto materialOperatorPair : _referenceMaterials) {
if (materialOperatorPair.first() != materialOperatorPair.second) {
return true;
}
}
return false;
}

View file

@ -341,57 +341,57 @@ public:
virtual ~Material() = default;
Material& operator= (const Material& material);
const MaterialKey& getKey() const { return _key; }
virtual MaterialKey getKey() const { return _key; }
static const float DEFAULT_EMISSIVE;
void setEmissive(const glm::vec3& emissive, bool isSRGB = true);
glm::vec3 getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_emissive) : _emissive); }
virtual glm::vec3 getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_emissive) : _emissive); }
static const float DEFAULT_OPACITY;
void setOpacity(float opacity);
float getOpacity() const { return _opacity; }
virtual float getOpacity() const { return _opacity; }
static const MaterialKey::OpacityMapMode DEFAULT_OPACITY_MAP_MODE;
void setOpacityMapMode(MaterialKey::OpacityMapMode opacityMapMode);
MaterialKey::OpacityMapMode getOpacityMapMode() const;
virtual MaterialKey::OpacityMapMode getOpacityMapMode() const;
static const float DEFAULT_OPACITY_CUTOFF;
void setOpacityCutoff(float opacityCutoff);
float getOpacityCutoff() const { return _opacityCutoff; }
virtual float getOpacityCutoff() const { return _opacityCutoff; }
static const MaterialKey::CullFaceMode DEFAULT_CULL_FACE_MODE;
void setCullFaceMode(MaterialKey::CullFaceMode cullFaceMode) { _cullFaceMode = cullFaceMode; }
MaterialKey::CullFaceMode getCullFaceMode() const { return _cullFaceMode; }
virtual MaterialKey::CullFaceMode getCullFaceMode() const { return _cullFaceMode; }
void setUnlit(bool value);
bool isUnlit() const { return _key.isUnlit(); }
virtual bool isUnlit() const { return _key.isUnlit(); }
static const float DEFAULT_ALBEDO;
void setAlbedo(const glm::vec3& albedo, bool isSRGB = true);
glm::vec3 getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_albedo) : _albedo); }
virtual glm::vec3 getAlbedo(bool SRGB = true) const { return (SRGB ? ColorUtils::tosRGBVec3(_albedo) : _albedo); }
static const float DEFAULT_METALLIC;
void setMetallic(float metallic);
float getMetallic() const { return _metallic; }
virtual float getMetallic() const { return _metallic; }
static const float DEFAULT_ROUGHNESS;
void setRoughness(float roughness);
float getRoughness() const { return _roughness; }
virtual float getRoughness() const { return _roughness; }
static const float DEFAULT_SCATTERING;
void setScattering(float scattering);
float getScattering() const { return _scattering; }
virtual float getScattering() const { return _scattering; }
// The texture map to channel association
static const int NUM_TEXCOORD_TRANSFORMS { 2 };
void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap);
const TextureMaps& getTextureMaps() const { return _textureMaps; } // FIXME - not thread safe...
virtual TextureMaps getTextureMaps() const { return _textureMaps; } // FIXME - not thread safe...
const TextureMapPointer getTextureMap(MapChannel channel) const;
// Albedo maps cannot have opacity detected until they are loaded
// This method allows const changing of the key/schemaBuffer without touching the map
// return true if the opacity changed, flase otherwise
bool resetOpacityMap() const;
virtual bool resetOpacityMap() const;
// conversion from legacy material properties to PBR equivalent
static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; }
@ -404,12 +404,12 @@ public:
const std::string& getModel() const { return _model; }
void setModel(const std::string& model) { _model = model; }
glm::mat4 getTexCoordTransform(uint i) const { return _texcoordTransforms[i]; }
virtual glm::mat4 getTexCoordTransform(uint i) const { return _texcoordTransforms[i]; }
void setTexCoordTransform(uint i, const glm::mat4& mat4) { _texcoordTransforms[i] = mat4; }
glm::vec2 getLightmapParams() const { return _lightmapParams; }
glm::vec2 getMaterialParams() const { return _materialParams; }
virtual glm::vec2 getLightmapParams() const { return _lightmapParams; }
virtual glm::vec2 getMaterialParams() const { return _materialParams; }
bool getDefaultFallthrough() const { return _defaultFallthrough; }
virtual bool getDefaultFallthrough() const { return _defaultFallthrough; }
void setDefaultFallthrough(bool defaultFallthrough) { _defaultFallthrough = defaultFallthrough; }
enum ExtraFlagBit {
@ -430,6 +430,8 @@ public:
virtual bool isReady() const { return true; }
virtual QString getProceduralString() const { return QString(); }
virtual bool isReference() const { return false; }
static const std::string HIFI_PBR;
static const std::string HIFI_SHADER_SIMPLE;
@ -547,12 +549,16 @@ public:
void setTexturesLoading(bool value) { _texturesLoading = value; }
void setInitialized() { _initialized = true; }
bool shouldUpdate() const { return !_initialized || _needsUpdate || _texturesLoading; }
bool shouldUpdate() const { return !_initialized || _needsUpdate || _texturesLoading || anyReferenceMaterialsOrTexturesChanged(); }
int getTextureCount() const { calculateMaterialInfo(); return _textureCount; }
size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; }
bool hasTextureInfo() const { return _hasCalculatedTextureInfo; }
void resetReferenceTexturesAndMaterials();
void addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator);
void addReferenceMaterial(const std::function<graphics::MaterialPointer()>& materialOperator);
private:
gpu::BufferView _schemaBuffer;
graphics::MaterialKey::CullFaceMode _cullFaceMode { graphics::Material::DEFAULT_CULL_FACE_MODE };
@ -565,6 +571,11 @@ private:
mutable int _textureCount { 0 };
mutable bool _hasCalculatedTextureInfo { false };
void calculateMaterialInfo() const;
bool anyReferenceMaterialsOrTexturesChanged() const;
std::vector<std::pair<std::function<gpu::TexturePointer()>, gpu::TexturePointer>> _referenceTextures;
std::vector<std::pair<std::function<graphics::MaterialPointer()>, graphics::MaterialPointer>> _referenceMaterials;
};
};

View file

@ -18,16 +18,12 @@ void TextureMap::setTextureSource(TextureSourcePointer& textureSource) {
}
bool TextureMap::isDefined() const {
if (_textureSource) {
return _textureSource->isDefined();
} else {
return false;
}
return _textureSource && _textureSource->isDefined();
}
gpu::TextureView TextureMap::getTextureView() const {
if (_textureSource) {
return gpu::TextureView(_textureSource->getGPUTexture(), 0);
return gpu::TextureView(_textureSource->getGPUTexture(), 0, _textureSource->getTextureOperator());
} else {
return gpu::TextureView();
}

View file

@ -4,6 +4,7 @@
//
// Created by Clement Brisset on 4/5/2017.
// Copyright 2017 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -23,7 +24,7 @@ namespace image {
std::function<gpu::uint32(const glm::vec3&)> getHDRPackingFunction();
std::function<glm::vec3(gpu::uint32)> getHDRUnpackingFunction();
void convertToFloatFromPacked(const unsigned char* source, int width, int height, size_t srcLineByteStride, gpu::Element sourceFormat,
void convertToFloatFromPacked(const unsigned char* source, int width, int height, size_t srcLineByteStride, gpu::Element sourceFormat,
glm::vec4* output, size_t outputLinePixelStride);
void convertToPackedFromFloat(unsigned char* output, int width, int height, size_t outputLineByteStride, gpu::Element outputFormat,
const glm::vec4* source, size_t srcLinePixelStride);
@ -32,8 +33,8 @@ namespace TextureUsage {
/*@jsdoc
* <p>Describes the type of texture.</p>
* <p>See also: {@link Material} and
* {@link https://docs.vircadia.dev/create/3d-models/pbr-materials-guide.html|PBR Materials Guide}.</p>
* <p>See also: {@link Material} and
* {@link https://docs.vircadia.com/create/3d-models/pbr-materials-guide.html|PBR Materials Guide}.</p>
* <table>
* <thead>
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
@ -102,7 +103,7 @@ gpu::TexturePointer createCubeTextureFromImage(Image&& image, const std::string&
gpu::TexturePointer createAmbientCubeTextureAndIrradianceFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createLightmapTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer process2DTextureColorFromImage(Image&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool isStrict, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer process2DTextureNormalMapFromImage(Image&& srcImage, const std::string& srcImageName, bool compress,

View file

@ -98,6 +98,8 @@ static const QUrl HMD_PREVIEW_FRAME_URL("resource://hmdPreviewFrame");
static const float SKYBOX_LOAD_PRIORITY { 10.0f }; // Make sure skybox loads first
static const float HIGH_MIPS_LOAD_PRIORITY { 9.0f }; // Make sure high mips loads after skybox but before models
std::function<gpu::TexturePointer(const QUuid&)> Texture::_unboundTextureForUUIDOperator { nullptr };
TextureCache::TextureCache() {
_ktxCache->initialize();
#if defined(DISABLE_KTX_CACHE)
@ -252,6 +254,10 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, image::TextureUs
if (url.scheme() == RESOURCE_SCHEME) {
return getResourceTexture(url);
}
QString decodedURL = QUrl::fromPercentEncoding(url.toEncoded());
if (decodedURL.startsWith("{")) {
return getTextureByUUID(decodedURL);
}
auto modifiedUrl = url;
if (type == image::TextureUsage::SKY_TEXTURE) {
QUrlQuery query { url.query() };
@ -385,8 +391,6 @@ NetworkTexture::NetworkTexture(const NetworkTexture& other) :
_type(other._type),
_sourceChannel(other._sourceChannel),
_currentlyLoadingResourceType(other._currentlyLoadingResourceType),
_originalWidth(other._originalWidth),
_originalHeight(other._originalHeight),
_width(other._width),
_height(other._height),
_maxNumPixels(other._maxNumPixels),
@ -462,13 +466,12 @@ void NetworkTexture::setExtra(void* extra) {
void NetworkTexture::setImage(gpu::TexturePointer texture, int originalWidth,
int originalHeight) {
_originalWidth = originalWidth;
_originalHeight = originalHeight;
// Passing ownership
_textureSource->resetTexture(texture);
if (texture) {
texture->setOriginalSize(originalWidth, originalHeight);
_width = texture->getWidth();
_height = texture->getHeight();
setSize(texture->getStoredSize());
@ -481,6 +484,12 @@ void NetworkTexture::setImage(gpu::TexturePointer texture, int originalWidth,
emit networkTextureCreated(qWeakPointerCast<NetworkTexture, Resource> (_self));
}
void NetworkTexture::setImageOperator(std::function<gpu::TexturePointer()> textureOperator) {
_textureSource->resetTextureOperator(textureOperator);
finishedLoading((bool)textureOperator);
emit networkTextureCreated(qWeakPointerCast<NetworkTexture, Resource> (_self));
}
gpu::TexturePointer NetworkTexture::getFallbackTexture() const {
return getFallbackTextureForType(_type);
}
@ -1312,7 +1321,6 @@ void ImageReader::read() {
}
NetworkTexturePointer TextureCache::getResourceTexture(const QUrl& resourceTextureUrl) {
gpu::TexturePointer texture;
if (resourceTextureUrl == SPECTATOR_CAMERA_FRAME_URL) {
if (!_spectatorCameraNetworkTexture) {
_spectatorCameraNetworkTexture.reset(new NetworkTexture(resourceTextureUrl, true));
@ -1329,6 +1337,7 @@ NetworkTexturePointer TextureCache::getResourceTexture(const QUrl& resourceTextu
_hmdPreviewNetworkTexture.reset(new NetworkTexture(resourceTextureUrl, true));
}
if (_hmdPreviewFramebuffer) {
gpu::TexturePointer texture;
texture = _hmdPreviewFramebuffer->getRenderBuffer(0);
if (texture) {
texture->setSource(HMD_PREVIEW_FRAME_URL.toString().toStdString());
@ -1375,3 +1384,27 @@ void TextureCache::updateSpectatorCameraNetworkTexture() {
}
}
}
NetworkTexturePointer TextureCache::getTextureByUUID(const QString& uuid) {
QUuid quuid = QUuid(uuid);
if (!quuid.isNull()) {
// We mark this as a resource texture because it's just a reference to another texture. The source
// texture will be marked properly
NetworkTexturePointer toReturn = NetworkTexturePointer(new NetworkTexture(uuid, true));
toReturn->setImageOperator(Texture::getTextureForUUIDOperator(uuid));
return toReturn;
}
return NetworkTexturePointer();
}
std::function<gpu::TexturePointer()> Texture::getTextureForUUIDOperator(const QUuid& uuid) {
if (_unboundTextureForUUIDOperator) {
return std::bind(_unboundTextureForUUIDOperator, uuid);
}
return nullptr;
}
void Texture::setUnboundTextureForUUIDOperator(std::function<gpu::TexturePointer(const QUuid&)> textureForUUIDOperator) {
_unboundTextureForUUIDOperator = textureForUUIDOperator;
}

View file

@ -39,6 +39,12 @@ class Texture {
public:
gpu::TexturePointer getGPUTexture() const { return _textureSource->getGPUTexture(); }
gpu::TextureSourcePointer _textureSource;
static std::function<gpu::TexturePointer()> getTextureForUUIDOperator(const QUuid& uuid);
static void setUnboundTextureForUUIDOperator(std::function<gpu::TexturePointer(const QUuid&)> textureForUUIDOperator);
private:
static std::function<gpu::TexturePointer(const QUuid&)> _unboundTextureForUUIDOperator;
};
/// A texture loaded from the network.
@ -52,10 +58,10 @@ public:
QString getType() const override { return "NetworkTexture"; }
int getOriginalWidth() const { return _originalWidth; }
int getOriginalHeight() const { return _originalHeight; }
int getWidth() const { return _width; }
int getHeight() const { return _height; }
int getOriginalWidth() const { return _textureSource->getGPUTexture() ? _textureSource->getGPUTexture()->getOriginalWidth() : 0; }
int getOriginalHeight() const { return _textureSource->getGPUTexture() ? _textureSource->getGPUTexture()->getOriginalHeight() : 0; }
int getWidth() const { return _textureSource->getGPUTexture() ? _textureSource->getGPUTexture()->getWidth() : 0; }
int getHeight() const { return _textureSource->getGPUTexture() ? _textureSource->getGPUTexture()->getHeight() : 0; }
image::TextureUsage::Type getTextureType() const { return _type; }
gpu::TexturePointer getFallbackTexture() const;
@ -86,6 +92,7 @@ protected:
Q_INVOKABLE void loadTextureContent(const QByteArray& content);
Q_INVOKABLE void setImage(gpu::TexturePointer texture, int originalWidth, int originalHeight);
void setImageOperator(std::function<gpu::TexturePointer()> textureOperator);
Q_INVOKABLE void startRequestForNextMipLevel();
@ -136,8 +143,6 @@ private:
// mip offsets to change.
ktx::KTXDescriptorPointer _originalKtxDescriptor;
int _originalWidth { 0 };
int _originalHeight { 0 };
int _width { 0 };
int _height { 0 };
int _maxNumPixels { ABSOLUTE_MAX_TEXTURE_NUM_PIXELS };
@ -192,6 +197,8 @@ public:
const gpu::FramebufferPointer& getSpectatorCameraFramebuffer(int width, int height);
void updateSpectatorCameraNetworkTexture();
NetworkTexturePointer getTextureByUUID(const QString& uuid);
static const int DEFAULT_SPECTATOR_CAM_WIDTH { 2048 };
static const int DEFAULT_SPECTATOR_CAM_HEIGHT { 1024 };

View file

@ -5,6 +5,7 @@
// Created by Burt Sloane
// Modified by Bruce Brown
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -21,9 +22,9 @@
#include <string>
/*@jsdoc
* The <code>Midi</code> API provides the ability to connect Interface with musical instruments and other external or virtual
* devices via the MIDI protocol. For further information and examples, see the tutorial:
* <a href="https://docs.vircadia.dev/script/midi-tutorial.html">Use MIDI to Control Your Environment</a>.
* The <code>Midi</code> API provides the ability to connect Interface with musical instruments and other external or virtual
* devices via the MIDI protocol. For further information and examples, see the tutorial:
* <a href="https://docs.vircadia.com/script/midi-tutorial.html">Use MIDI to Control Your Environment</a>.
*
* <p><strong>Note:</strong> Only works on Windows.</p>
*
@ -43,7 +44,7 @@ public:
void midiHardwareChange(); // relay hardware change to Javascript
void sendRawMessage(int device, int raw); // relay midi message to MIDI outputs
void sendNote(int status, int note, int velocity); // relay a note to MIDI outputs
void sendMessage(int device, int channel, int type, int note, int velocity); // relay a message to MIDI outputs
void sendMessage(int device, int channel, int type, int note, int velocity); // relay a message to MIDI outputs
static void USBchanged();
private:
@ -150,7 +151,7 @@ public slots:
/*@jsdoc
* Enables or disables repeating all incoming notes to all outputs. (Default is disabled.)
* @function Midi.thruModeEnable
* @param {boolean} enable - <code>true</code> to enable repeating all incoming notes to all output, <code>false</code> to
* @param {boolean} enable - <code>true</code> to enable repeating all incoming notes to all output, <code>false</code> to
* disable.
*/
Q_INVOKABLE void thruModeEnable(bool enable);
@ -159,11 +160,11 @@ public slots:
/*@jsdoc
* Enables or disables broadcasts to all unblocked devices.
* @function Midi.broadcastEnable
* @param {boolean} enable - <code>true</code> to have "send" functions broadcast to all devices, <code>false</code> to
* @param {boolean} enable - <code>true</code> to have "send" functions broadcast to all devices, <code>false</code> to
* have them send to specific output devices.
*/
Q_INVOKABLE void broadcastEnable(bool enable);
/// filter by event types

View file

@ -39,7 +39,7 @@ const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
const QString DEFAULT_VIRCADIA_ADDRESS = (!BuildInfo::PRELOADED_STARTUP_LOCATION.isEmpty())
? BuildInfo::PRELOADED_STARTUP_LOCATION
: NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS;
const QString DEFAULT_HOME_ADDRESS = (!BuildInfo::PRELOADED_STARTUP_LOCATION.isEmpty())
const QString DEFAULT_HOME_ADDRESS = (!BuildInfo::PRELOADED_STARTUP_LOCATION.isEmpty())
? BuildInfo::PRELOADED_STARTUP_LOCATION
: NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS;
@ -56,7 +56,7 @@ QString AddressManager::getProtocol() const {
QUrl AddressManager::currentAddress(bool domainOnly) const {
QUrl hifiURL = _domainURL;
if (!domainOnly && hifiURL.scheme() == URL_SCHEME_HIFI) {
if (!domainOnly && hifiURL.scheme() == URL_SCHEME_VIRCADIA) {
hifiURL.setPath(currentPath());
}
@ -65,7 +65,7 @@ QUrl AddressManager::currentAddress(bool domainOnly) const {
QUrl AddressManager::currentFacingAddress() const {
auto hifiURL = currentAddress();
if (hifiURL.scheme() == URL_SCHEME_HIFI) {
if (hifiURL.scheme() == URL_SCHEME_VIRCADIA) {
hifiURL.setPath(currentFacingPath());
}
@ -77,7 +77,7 @@ QUrl AddressManager::currentShareableAddress(bool domainOnly) const {
// if we have a shareable place name use that instead of whatever the current host is
QUrl hifiURL;
hifiURL.setScheme(URL_SCHEME_HIFI);
hifiURL.setScheme(URL_SCHEME_VIRCADIA);
hifiURL.setHost(_shareablePlaceName);
if (!domainOnly) {
@ -94,7 +94,7 @@ QUrl AddressManager::currentPublicAddress(bool domainOnly) const {
// return an address that can be used by others to visit this client's current location. If
// in a serverless domain (which can't be visited) return an empty URL.
QUrl shareableAddress = currentShareableAddress(domainOnly);
if (shareableAddress.scheme() != URL_SCHEME_HIFI) {
if (shareableAddress.scheme() != URL_SCHEME_VIRCADIA) {
return QUrl(); // file: urls aren't public
}
return shareableAddress;
@ -103,7 +103,7 @@ QUrl AddressManager::currentPublicAddress(bool domainOnly) const {
QUrl AddressManager::currentFacingShareableAddress() const {
auto hifiURL = currentShareableAddress();
if (hifiURL.scheme() == URL_SCHEME_HIFI) {
if (hifiURL.scheme() == URL_SCHEME_VIRCADIA) {
hifiURL.setPath(currentFacingPath());
}
@ -114,7 +114,7 @@ QUrl AddressManager::currentFacingPublicAddress() const {
// return an address that can be used by others to visit this client's current location. If
// in a serverless domain (which can't be visited) return an empty URL.
QUrl shareableAddress = currentFacingShareableAddress();
if (shareableAddress.scheme() != URL_SCHEME_HIFI) {
if (shareableAddress.scheme() != URL_SCHEME_VIRCADIA) {
return QUrl(); // file: urls aren't public
}
return shareableAddress;
@ -165,7 +165,7 @@ void AddressManager::storeCurrentAddress() {
if (url.scheme() == HIFI_URL_SCHEME_FILE ||
url.scheme() == HIFI_URL_SCHEME_HTTP || url.scheme() == HIFI_URL_SCHEME_HTTPS ||
(url.scheme() == URL_SCHEME_HIFI && !url.host().isEmpty())) {
(url.scheme() == URL_SCHEME_VIRCADIA && !url.host().isEmpty())) {
// TODO -- once Octree::readFromURL no-longer takes over the main event-loop, serverless-domain urls can
// be loaded over http(s)
// url.scheme() == HIFI_URL_SCHEME_HTTP ||
@ -242,7 +242,7 @@ const JSONCallbackParameters& AddressManager::apiCallbackParameters() {
return callbackParams;
}
bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger) {
bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger, const QString& lookupUrlInString) {
static QString URL_TYPE_USER = "user";
static QString URL_TYPE_DOMAIN_ID = "domain_id";
static QString URL_TYPE_PLACE = "place";
@ -258,24 +258,32 @@ bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger) {
if (lookupUrl.scheme().isEmpty() && !lookupUrl.path().startsWith("/")) {
// 'urls' without schemes are taken as domain names, as opposed to
// simply a path portion of a url, so we need to set the scheme
lookupUrl.setScheme(URL_SCHEME_HIFI);
lookupUrl.setScheme(URL_SCHEME_VIRCADIA);
}
static const QRegExp PORT_REGEX = QRegExp("\\d{1,5}(\\/.*)?");
if(!lookupUrl.scheme().isEmpty() && lookupUrl.host().isEmpty() && PORT_REGEX.exactMatch(lookupUrl.path())) {
// this is in the form somewhere:<port>, convert it to hifi://somewhere:<port>
lookupUrl = QUrl(URL_SCHEME_HIFI + "://" + lookupUrl.toString());
lookupUrl = QUrl(URL_SCHEME_VIRCADIA + "://" + lookupUrl.toString());
}
// it should be noted that url's in the form
// somewhere:<port> are not valid, as that
// would indicate that the scheme is 'somewhere'
// use hifi://somewhere:<port> instead
if (lookupUrl.scheme() == URL_SCHEME_HIFI) {
if (lookupUrl.scheme() == URL_SCHEME_VIRCADIA || lookupUrlInString.startsWith(URL_SCHEME_VIRCADIA + "://")) {
QString lookupUrlString;
if (lookupUrlInString.startsWith(URL_SCHEME_VIRCADIA + "://")) {
lookupUrlString = lookupUrlInString;
} else {
lookupUrlString = lookupUrl.toString(QUrl::FullyEncoded);
}
if (lookupUrl.host().isEmpty()) {
// this was in the form hifi:/somewhere or hifi:somewhere. Fix it by making it hifi://somewhere
static const QRegExp HIFI_SCHEME_REGEX = QRegExp(URL_SCHEME_HIFI + ":\\/{0,2}", Qt::CaseInsensitive);
lookupUrl = QUrl(lookupUrl.toString().replace(HIFI_SCHEME_REGEX, URL_SCHEME_HIFI + "://"));
static const QRegExp HIFI_SCHEME_REGEX = QRegExp(URL_SCHEME_VIRCADIA + ":\\/{0,2}", Qt::CaseInsensitive);
lookupUrl = QUrl(lookupUrl.toString().replace(HIFI_SCHEME_REGEX, URL_SCHEME_VIRCADIA + "://"));
}
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::LookupAddress);
@ -340,6 +348,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger) {
// try to look up the domain ID on the metaverse API
attemptDomainIDLookup(lookupUrl.host(), lookupUrl.path(), trigger);
} else {
// wasn't an address - lookup the place name
// we may have a path that defines a relative viewpoint - pass that through the lookup so we can go to it after
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_PLACE, lookupUrl.toString());
// save the last visited domain URL.
@ -348,10 +358,26 @@ bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger) {
// store this place name as the previous lookup in case we fail to connect and want to refresh API info
_previousAPILookup = lookupUrl;
// wasn't an address - lookup the place name
// we may have a path that defines a relative viewpoint - pass that through the lookup so we can go to it after
if (!lookupUrl.host().isNull() && !lookupUrl.host().isEmpty()) {
attemptPlaceNameLookup(lookupUrl.host(), lookupUrl.path(), trigger);
// Let's convert this to a QString for processing in case there are spaces in it.
if (lookupUrlString.contains(URL_SCHEME_VIRCADIA + "://", Qt::CaseInsensitive)) {
lookupUrlString = lookupUrlString.replace((URL_SCHEME_VIRCADIA + "://"), "");
} else if (lookupUrlString.contains(URL_SCHEME_VIRCADIA + ":/", Qt::CaseInsensitive)) {
lookupUrlString = lookupUrlString.replace((URL_SCHEME_VIRCADIA + ":/"), "");
} else if (lookupUrlString.contains(URL_SCHEME_VIRCADIA + ":", Qt::CaseInsensitive)) {
lookupUrlString = lookupUrlString.replace((URL_SCHEME_VIRCADIA + ":"), "");
}
// Get the path and then strip it out.
QString lookupUrlStringPath;
int index = lookupUrlString.indexOf('/');
if (index != -1) {
lookupUrlStringPath = lookupUrlString.mid(index);
lookupUrlString.replace(lookupUrlStringPath, "");
}
if (!lookupUrlString.isEmpty()) {
attemptPlaceNameLookup(lookupUrlString, lookupUrlStringPath, trigger);
}
}
}
@ -371,7 +397,7 @@ bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger) {
return true;
} else if (lookupUrl.scheme() == HIFI_URL_SCHEME_FILE || lookupUrl.scheme() == HIFI_URL_SCHEME_HTTPS
|| lookupUrl.scheme() == HIFI_URL_SCHEME_HTTP) {
// Save the last visited domain URL.
_lastVisitedURL = lookupUrl;
@ -412,13 +438,13 @@ bool isPossiblePlaceName(QString possiblePlaceName) {
}
void AddressManager::handleLookupString(const QString& lookupString, bool fromSuggestions) {
QString trimmedString = lookupString.trimmed();
QString sanitizedString = lookupString.trimmed();
if (!sanitizedString.isEmpty()) {
if (!trimmedString.isEmpty()) {
resetConfirmConnectWithoutAvatarEntities();
// make this a valid hifi URL and handle it off to handleUrl
handleUrl(sanitizedString, fromSuggestions ? Suggestions : UserInput);
handleUrl(trimmedString, fromSuggestions ? Suggestions : UserInput, trimmedString);
}
}
@ -494,7 +520,7 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
qCDebug(networking) << "Possible domain change required to connect to" << domainHostname
<< "on" << domainPort;
QUrl domainURL;
domainURL.setScheme(URL_SCHEME_HIFI);
domainURL.setScheme(URL_SCHEME_VIRCADIA);
domainURL.setHost(domainHostname);
if (domainPort > 0) {
domainURL.setPort(domainPort);
@ -606,8 +632,6 @@ void AddressManager::handleAPIError(QNetworkReply* errorReply) {
void AddressManager::attemptPlaceNameLookup(const QString& lookupString, const QString& overridePath, LookupTrigger trigger) {
// assume this is a place name and see if we can get any info on it
QString placeName = QUrl::toPercentEncoding(lookupString);
QVariantMap requestParams;
// if the user asked for a specific path with this lookup then keep it with the request so we can use it later
@ -618,7 +642,7 @@ void AddressManager::attemptPlaceNameLookup(const QString& lookupString, const Q
// remember how this lookup was triggered for history storage handling later
requestParams.insert(LOOKUP_TRIGGER_KEY, static_cast<int>(trigger));
DependencyManager::get<AccountManager>()->sendRequest(GET_PLACE.arg(placeName),
DependencyManager::get<AccountManager>()->sendRequest(GET_PLACE.arg(lookupString),
AccountManagerAuth::None,
QNetworkAccessManager::GetOperation,
apiCallbackParameters(),
@ -667,7 +691,7 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri
emit lookupResultsFinished();
QUrl domainURL;
domainURL.setScheme(URL_SCHEME_HIFI);
domainURL.setScheme(URL_SCHEME_VIRCADIA);
domainURL.setHost(domainIPString);
if (domainPort > 0) {
domainURL.setPort(domainPort);
@ -690,7 +714,7 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri
emit lookupResultsFinished();
QUrl domainURL;
domainURL.setScheme(URL_SCHEME_HIFI);
domainURL.setScheme(URL_SCHEME_VIRCADIA);
domainURL.setHost(domainHostname);
if (domainPort > 0) {
domainURL.setPort(domainPort);
@ -823,7 +847,7 @@ bool AddressManager::setHost(const QString& host, LookupTrigger trigger, quint16
addCurrentAddressToHistory(trigger);
_domainURL = QUrl();
_domainURL.setScheme(URL_SCHEME_HIFI);
_domainURL.setScheme(URL_SCHEME_VIRCADIA);
_domainURL.setHost(host);
if (port > 0) {
_domainURL.setPort(port);
@ -860,7 +884,7 @@ bool AddressManager::setDomainInfo(const QUrl& domainURL, LookupTrigger trigger)
// clear any current place information
_rootPlaceID = QUuid();
if (_domainURL.scheme() == URL_SCHEME_HIFI) {
if (_domainURL.scheme() == URL_SCHEME_VIRCADIA) {
qCDebug(networking) << "Possible domain change required to connect to domain at" << hostname << "on" << port;
} else {
qCDebug(networking) << "Possible domain change required to serverless domain: " << domainURL.toString();

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2014-09-10.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -35,7 +36,7 @@ const QString GET_PLACE = "/api/v1/places/%1";
* The <code>location</code> API provides facilities related to your current location in the metaverse.
*
* <h3>Getter/Setter</h3>
* <p>You can get and set your current metaverse address by directly reading a string value from and writing a string value to
* <p>You can get and set your current metaverse address by directly reading a string value from and writing a string value to
* the <code>location</code> object. This is an alternative to using the <code>location.href</code> property or other object
* functions.</p>
*
@ -53,12 +54,12 @@ const QString GET_PLACE = "/api/v1/places/%1";
* <code>localhost</code>, or an IP address). Is blank if you're in a serverless domain.
* <em>Read-only.</em>
* @property {string} href - Your current metaverse address (e.g., <code>"hifi://domainname/15,-10,26/0,0,0,1"</code>)
* regardless of whether or not you're connected to the domain. Starts with <code>"file:///"</code> if you're in a
* regardless of whether or not you're connected to the domain. Starts with <code>"file:///"</code> if you're in a
* serverless domain.
* <em>Read-only.</em>
* @property {boolean} isConnected - <code>true</code> if you're connected to the domain in your current <code>href</code>
* metaverse address, otherwise <code>false</code>.
* @property {string} pathname - The location and orientation in your current <code>href</code> metaverse address
* @property {string} pathname - The location and orientation in your current <code>href</code> metaverse address
* (e.g., <code>"/15,-10,26/0,0,0,1"</code>).
* <em>Read-only.</em>
* @property {string} placename - The place name in your current <code>href</code> metaverse address
@ -77,7 +78,7 @@ const QString GET_PLACE = "/api/v1/places/%1";
* @hifi-client-entity
* @hifi-avatar
*
* @deprecated This API is deprecated and will be removed. Use the {@link location} or {@link Window|Window.location} APIs
* @deprecated This API is deprecated and will be removed. Use the {@link location} or {@link Window|Window.location} APIs
* instead.
*
* @property {Uuid} domainID - A UUID uniquely identifying the domain you're visiting. Is {@link Uuid(0)|Uuid.NULL} if you're not
@ -248,17 +249,17 @@ public slots:
/*@jsdoc
* Takes you to a specified metaverse address.
* @function location.handleLookupString
* @param {string} address - The address to go to: a <code>"hifi://"</code> address, an IP address (e.g.,
* <code>"127.0.0.1"</code> or <code>"localhost"</code>), a <code>file:///</code> address, a domain name, a named path
* on a domain (starts with <code>"/"</code>), a position or position and orientation, or a user (starts with
* @param {string} address - The address to go to: a <code>"hifi://"</code> address, an IP address (e.g.,
* <code>"127.0.0.1"</code> or <code>"localhost"</code>), a <code>file:///</code> address, a domain name, a named path
* on a domain (starts with <code>"/"</code>), a position or position and orientation, or a user (starts with
* <code>"@"</code>).
* @param {boolean} [fromSuggestions=false] - Set to <code>true</code> if the address is obtained from the "Goto" dialog.
* Helps ensure that user's location history is correctly maintained.
* @param {boolean} [fromSuggestions=false] - Set to <code>true</code> if the address is obtained from the "Explore" app.
* Helps ensure that the user's location history is correctly maintained.
*/
void handleLookupString(const QString& lookupString, bool fromSuggestions = false);
/*@jsdoc
* Takes you to a position and orientation resulting from a lookup for a named path in the domain (set in the domain
* Takes you to a position and orientation resulting from a lookup for a named path in the domain (set in the domain
* server's settings).
* @function location.goToViewpointForPath
* @param {string} path - The position and orientation corresponding to the named path.
@ -292,7 +293,7 @@ public slots:
* location history is correctly maintained.
*/
void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) {
handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger);
handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger);
}
/*@jsdoc
@ -307,7 +308,7 @@ public slots:
* Takes you to the specified user's location.
* @function location.goToUser
* @param {string} username - The user's username.
* @param {boolean} [matchOrientation=true] - If <code>true</code> then go to a location just in front of the user and turn
* @param {boolean} [matchOrientation=true] - If <code>true</code> then go to a location just in front of the user and turn
* to face them, otherwise go to the user's exact location and orientation.
*/
void goToUser(const QString& username, bool shouldMatchOrientation = true);
@ -348,7 +349,7 @@ public slots:
void copyAddress();
/*@jsdoc
* Copies your current metaverse location and orientation (i.e., <code>location.pathname</code> property value) to the OS
* Copies your current metaverse location and orientation (i.e., <code>location.pathname</code> property value) to the OS
* clipboard.
* @function location.copyPath
*/
@ -374,7 +375,7 @@ signals:
void lookupResultsFinished();
/*@jsdoc
* Triggered when looking up the details of a metaverse user or location to go to has completed and the domain or user is
* Triggered when looking up the details of a metaverse user or location to go to has completed and the domain or user is
* offline.
* @function location.lookupResultIsOffline
* @returns {Signal}
@ -390,10 +391,10 @@ signals:
void lookupResultIsNotFound();
/*@jsdoc
* Triggered when a request is made to go to an IP address.
* Triggered when a request is made to go to a URL or IP address.
* @function location.possibleDomainChangeRequired
* @param {Url} domainURL - URL for domain
* @param {Uuid} domainID - The UUID of the domain to go to.
* @param {string} domainURL - The URL of the domain.
* @param {Uuid} domainID - The UUID of the domain to go to. May be {@link Uuid|Uuid.NULL} if not yet known.
* @returns {Signal}
*/
// No example because this function isn't typically used in scripts.
@ -415,9 +416,9 @@ signals:
* @function location.locationChangeRequired
* @param {Vec3} position - The position to go to.
* @param {boolean} hasOrientationChange - If <code>true</code> then a new <code>orientation</code> has been requested.
* @param {Quat} orientation - The orientation to change to. Is {@link Quat(0)|Quat.IDENTITY} if
* @param {Quat} orientation - The orientation to change to. Is {@link Quat(0)|Quat.IDENTITY} if
* <code>hasOrientationChange</code> is <code>false</code>.
* @param {boolean} shouldFaceLocation - If <code>true</code> then the request is to go to a position near that specified
* @param {boolean} shouldFaceLocation - If <code>true</code> then the request is to go to a position near that specified
* and orient your avatar to face it. For example when you visit someone from the "People" dialog.
* @returns {Signal}
* @example <caption>Report location change requests.</caption>
@ -468,7 +469,7 @@ signals:
* Triggered when there's a change in whether or not there's a previous location that can be navigated to using
* {@link location.goBack|goBack}. (Reflects changes in the state of the "Goto" dialog's back arrow.)
* @function location.goBackPossible
* @param {boolean} isPossible - <code>true</code> if there's a previous location to navigate to, otherwise
* @param {boolean} isPossible - <code>true</code> if there's a previous location to navigate to, otherwise
* <code>false</code>.
* @returns {Signal}
* @example <caption>Report when ability to navigate back changes.</caption>
@ -511,7 +512,7 @@ private:
const JSONCallbackParameters& apiCallbackParameters();
bool handleUrl(const QUrl& lookupUrl, LookupTrigger trigger = UserInput);
bool handleUrl(const QUrl& lookupUrl, LookupTrigger trigger = UserInput, const QString& lookupUrlInString = "");
bool handleNetworkAddress(const QString& lookupString, LookupTrigger trigger, bool& hostChanged);
void handlePath(const QString& path, LookupTrigger trigger, bool wasPathOnly = false);

View file

@ -26,7 +26,7 @@
#include "AddressManager.h"
#include "Assignment.h"
#include "DomainAccountManager.h"
#include "HifiSockAddr.h"
#include "SockAddr.h"
#include "NodeList.h"
#include "udt/Packet.h"
#include "udt/PacketHeaders.h"
@ -37,7 +37,7 @@
DomainHandler::DomainHandler(QObject* parent) :
QObject(parent),
_sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
_sockAddr(SockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
_icePeer(this),
_settingsTimer(this),
_apiRefreshTimer(this)
@ -133,7 +133,7 @@ void DomainHandler::hardReset(QString reason) {
qCDebug(networking) << "Hard reset in NodeList DomainHandler.";
_pendingDomainID = QUuid();
_iceServerSockAddr = HifiSockAddr();
_iceServerSockAddr = SockAddr();
_sockAddr.clear();
_domainURL = QUrl();
@ -170,7 +170,7 @@ void DomainHandler::setErrorDomainURL(const QUrl& url) {
return;
}
void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname) {
void DomainHandler::setSockAddr(const SockAddr& sockAddr, const QString& hostname) {
if (_sockAddr != sockAddr) {
// we should reset on a sockAddr change
hardReset("Changing domain sockAddr");
@ -184,7 +184,7 @@ void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hos
// some callers may pass a hostname, this is not to be used for lookup but for DTLS certificate verification
_domainURL = QUrl();
_domainURL.setScheme(URL_SCHEME_HIFI);
_domainURL.setScheme(URL_SCHEME_VIRCADIA);
_domainURL.setHost(hostname);
_domainURL.setPort(_sockAddr.getPort());
}
@ -199,7 +199,7 @@ void DomainHandler::setUUID(const QUuid& uuid) {
void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
_pendingDomainID = domainID;
if (domainURL.scheme() != URL_SCHEME_HIFI) {
if (domainURL.scheme() != URL_SCHEME_VIRCADIA) {
_sockAddr.clear();
// if this is a file URL we need to see if it has a ~ for us to expand
@ -215,7 +215,7 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
// if it's in the error state, reset and try again.
if (_domainURL != domainURL
|| (_sockAddr.getPort() != domainPort && domainURL.scheme() == URL_SCHEME_HIFI)
|| (_sockAddr.getPort() != domainPort && domainURL.scheme() == URL_SCHEME_VIRCADIA)
|| isServerless() // For reloading content in serverless domain.
|| _isInErrorState) {
// re-set the domain info so that auth information is reloaded
@ -230,7 +230,7 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
qCDebug(networking) << "Updated domain hostname to" << domainURL.host();
if (!domainURL.host().isEmpty()) {
if (domainURL.scheme() == URL_SCHEME_HIFI) {
if (domainURL.scheme() == URL_SCHEME_VIRCADIA) {
// re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname
qCDebug(networking, "Looking up DS hostname %s.", domainURL.host().toLocal8Bit().constData());
QHostInfo::lookupHost(domainURL.host(), this, SLOT(completedHostnameLookup(const QHostInfo&)));
@ -280,9 +280,9 @@ void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname,
_pendingDomainID = id;
HifiSockAddr* replaceableSockAddr = &_iceServerSockAddr;
replaceableSockAddr->~HifiSockAddr();
replaceableSockAddr = new (replaceableSockAddr) HifiSockAddr(iceServerHostname, ICE_SERVER_DEFAULT_PORT);
SockAddr* replaceableSockAddr = &_iceServerSockAddr;
replaceableSockAddr->~SockAddr();
replaceableSockAddr = new (replaceableSockAddr) SockAddr(iceServerHostname, ICE_SERVER_DEFAULT_PORT);
_iceServerSockAddr.setObjectName("IceServer");
auto nodeList = DependencyManager::get<NodeList>();
@ -291,7 +291,7 @@ void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname,
if (_iceServerSockAddr.getAddress().isNull()) {
// connect to lookup completed for ice-server socket so we can request a heartbeat once hostname is looked up
connect(&_iceServerSockAddr, &HifiSockAddr::lookupCompleted, this, &DomainHandler::completedIceServerHostnameLookup);
connect(&_iceServerSockAddr, &SockAddr::lookupCompleted, this, &DomainHandler::completedIceServerHostnameLookup);
} else {
completedIceServerHostnameLookup();
}
@ -303,7 +303,7 @@ void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname,
void DomainHandler::activateICELocalSocket() {
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::SetDomainSocket);
_sockAddr = _icePeer.getLocalSocket();
_domainURL.setScheme(URL_SCHEME_HIFI);
_domainURL.setScheme(URL_SCHEME_VIRCADIA);
_domainURL.setHost(_sockAddr.getAddress().toString());
emit domainURLChanged(_domainURL);
emit completedSocketDiscovery();
@ -312,7 +312,7 @@ void DomainHandler::activateICELocalSocket() {
void DomainHandler::activateICEPublicSocket() {
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::SetDomainSocket);
_sockAddr = _icePeer.getPublicSocket();
_domainURL.setScheme(URL_SCHEME_HIFI);
_domainURL.setScheme(URL_SCHEME_VIRCADIA);
_domainURL.setHost(_sockAddr.getAddress().toString());
emit domainURLChanged(_domainURL);
emit completedSocketDiscovery();
@ -369,7 +369,7 @@ void DomainHandler::setIsConnected(bool isConnected) {
// FIXME: Reinstate the requestDomainSettings() call here in version 2021.2.0 instead of having it in
// NodeList::processDomainServerList().
/*
if (_domainURL.scheme() == URL_SCHEME_HIFI && !_domainURL.host().isEmpty()) {
if (_domainURL.scheme() == URL_SCHEME_VIRCADIA && !_domainURL.host().isEmpty()) {
// we've connected to new domain - time to ask it for global settings
requestDomainSettings();
}
@ -458,7 +458,7 @@ void DomainHandler::processSettingsPacketList(QSharedPointer<ReceivedMessage> pa
}
void DomainHandler::processICEPingReplyPacket(QSharedPointer<ReceivedMessage> message) {
const HifiSockAddr& senderSockAddr = message->getSenderSockAddr();
const SockAddr& senderSockAddr = message->getSenderSockAddr();
qCDebug(networking_ice) << "Received reply from domain-server on" << senderSockAddr;
if (getIP().isNull()) {

View file

@ -25,7 +25,7 @@
#include <shared/ReadWriteLockable.h>
#include <SettingHandle.h>
#include "HifiSockAddr.h"
#include "SockAddr.h"
#include "NetworkPeer.h"
#include "NLPacket.h"
#include "NLPacketList.h"
@ -109,8 +109,8 @@ public:
const QHostAddress& getIP() const { return _sockAddr.getAddress(); }
void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); }
const HifiSockAddr& getSockAddr() const { return _sockAddr; }
void setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname);
const SockAddr& getSockAddr() const { return _sockAddr; }
void setSockAddr(const SockAddr& sockAddr, const QString& hostname);
unsigned short getPort() const { return _sockAddr.getPort(); }
void setPort(quint16 port) { _sockAddr.setPort(port); }
@ -126,7 +126,7 @@ public:
const QUuid& getICEClientID() const { return _iceClientID; }
bool requiresICE() const { return !_iceServerSockAddr.isNull(); }
const HifiSockAddr& getICEServerSockAddr() const { return _iceServerSockAddr; }
const SockAddr& getICEServerSockAddr() const { return _iceServerSockAddr; }
NetworkPeer& getICEPeer() { return _icePeer; }
void activateICELocalSocket();
void activateICEPublicSocket();
@ -137,7 +137,7 @@ public:
void setCanConnectWithoutAvatarEntities(bool canConnect);
bool canConnectWithoutAvatarEntities();
bool isServerless() const { return _domainURL.scheme() != URL_SCHEME_HIFI; }
bool isServerless() const { return _domainURL.scheme() != URL_SCHEME_VIRCADIA; }
bool getInterstitialModeEnabled() const;
void setInterstitialModeEnabled(bool enableInterstitialMode);
@ -288,12 +288,12 @@ private:
Node::LocalID _localID;
QUrl _domainURL;
QUrl _errorDomainURL;
HifiSockAddr _sockAddr;
SockAddr _sockAddr;
QUuid _assignmentUUID;
QUuid _connectionToken;
QUuid _pendingDomainID; // ID of domain being connected to, via ICE or direct connection
QUuid _iceClientID;
HifiSockAddr _iceServerSockAddr;
SockAddr _iceServerSockAddr;
NetworkPeer _icePeer;
bool _isConnected { false };
bool _haveAskedConnectWithoutAvatarEntities { false };

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2/15/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -33,7 +34,7 @@
#include "AccountManager.h"
#include "AssetClient.h"
#include "Assignment.h"
#include "HifiSockAddr.h"
#include "SockAddr.h"
#include "NetworkLogging.h"
#include "udt/Packet.h"
#include "HMACAuth.h"
@ -103,7 +104,7 @@ LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) :
_nodeSocket.setMessageHandler([this](std::unique_ptr<udt::Packet> packet) {
_packetReceiver->handleVerifiedMessagePacket(std::move(packet));
});
_nodeSocket.setMessageFailureHandler([this](HifiSockAddr from,
_nodeSocket.setMessageFailureHandler([this](SockAddr from,
udt::Packet::MessageNumber messageNumber) {
_packetReceiver->handleMessageFailure(from, messageNumber);
});
@ -120,7 +121,7 @@ LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) :
if (_stunSockAddr.getAddress().isNull()) {
// we don't know the stun server socket yet, add it to unfiltered once known
connect(&_stunSockAddr, &HifiSockAddr::lookupCompleted, this, &LimitedNodeList::addSTUNHandlerToUnfiltered);
connect(&_stunSockAddr, &SockAddr::lookupCompleted, this, &LimitedNodeList::addSTUNHandlerToUnfiltered);
} else {
// we know the stun server socket, add it to unfiltered now
addSTUNHandlerToUnfiltered();
@ -248,11 +249,11 @@ bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) {
if (headerVersion != versionForPacketType(headerType)) {
static QMultiHash<QUuid, PacketType> sourcedVersionDebugSuppressMap;
static QMultiHash<HifiSockAddr, PacketType> versionDebugSuppressMap;
static QMultiHash<SockAddr, PacketType> versionDebugSuppressMap;
bool hasBeenOutput = false;
QString senderString;
const HifiSockAddr& senderSockAddr = packet.getSenderSockAddr();
const SockAddr& senderSockAddr = packet.getSenderSockAddr();
QUuid sourceID;
if (PacketTypeEnum::getNonSourcedPackets().contains(headerType)) {
@ -413,7 +414,7 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node&
return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getAuthenticateHash());
}
qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr,
qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const SockAddr& sockAddr,
HMACAuth* hmacAuth) {
Q_ASSERT(!packet.isPartOfMessage());
Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket",
@ -446,7 +447,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const Node&
}
}
qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const HifiSockAddr& sockAddr,
qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const SockAddr& sockAddr,
HMACAuth* hmacAuth) {
Q_ASSERT(!packet->isPartOfMessage());
if (packet->isReliable()) {
@ -497,7 +498,7 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi
}
}
qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr,
qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetList, const SockAddr& sockAddr,
HMACAuth* hmacAuth) {
qint64 bytesSent = 0;
@ -511,7 +512,7 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi
return bytesSent;
}
qint64 LimitedNodeList::sendPacketList(std::unique_ptr<NLPacketList> packetList, const HifiSockAddr& sockAddr) {
qint64 LimitedNodeList::sendPacketList(std::unique_ptr<NLPacketList> packetList, const SockAddr& sockAddr) {
// close the last packet in the list
packetList->closeCurrentPacket();
@ -543,7 +544,7 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr<NLPacketList> packetList,
}
qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode,
const HifiSockAddr& overridenSockAddr) {
const SockAddr& overridenSockAddr) {
if (overridenSockAddr.isNull() && !destinationNode.getActiveSocket()) {
qCDebug(networking) << "LimitedNodeList::sendPacket called without active socket for node"
<< destinationNode.getUUID() << ". Not sending.";
@ -675,7 +676,7 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node, ConnectionID
}
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
const SockAddr& publicSocket, const SockAddr& localSocket,
Node::LocalID localID, bool isReplicated, bool isUpstream,
const QUuid& connectionSecret, const NodePermissions& permissions) {
auto matchingNode = nodeWithUUID(uuid);
@ -1105,7 +1106,7 @@ void LimitedNodeList::processSTUNResponse(std::unique_ptr<udt::BasePacket> packe
_publicSockAddr.getAddress().toString().toLocal8Bit().constData(),
_publicSockAddr.getPort());
_publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort);
_publicSockAddr = SockAddr(newPublicAddress, newPublicPort);
if (!_hasCompletedInitialSTUN) {
// if we're here we have definitely completed our initial STUN sequence
@ -1133,10 +1134,10 @@ void LimitedNodeList::startSTUNPublicSocketUpdate() {
if (_stunSockAddr.getAddress().isNull()) {
// if we fail to lookup the socket then timeout the STUN address lookup
connect(&_stunSockAddr, &HifiSockAddr::lookupFailed, this, &LimitedNodeList::possiblyTimeoutSTUNAddressLookup);
connect(&_stunSockAddr, &SockAddr::lookupFailed, this, &LimitedNodeList::possiblyTimeoutSTUNAddressLookup);
// immediately send a STUN request once we know the socket
connect(&_stunSockAddr, &HifiSockAddr::lookupCompleted, this, &LimitedNodeList::sendSTUNRequest);
connect(&_stunSockAddr, &SockAddr::lookupCompleted, this, &LimitedNodeList::sendSTUNRequest);
// start the initial STUN timer once we know the socket
connect(&_stunSockAddr, SIGNAL(lookupCompleted()), _initialSTUNTimer, SLOT(start()));
@ -1186,7 +1187,7 @@ void LimitedNodeList::stopInitialSTUNUpdate(bool success) {
qCDebug(networking) << "LimitedNodeList public socket will be set with local port and null QHostAddress.";
// reset the public address and port to a null address
_publicSockAddr = HifiSockAddr(QHostAddress(), _nodeSocket.localPort());
_publicSockAddr = SockAddr(QHostAddress(), _nodeSocket.localPort());
// we have changed the publicSockAddr, so emit our signal
emit publicSockAddrChanged(_publicSockAddr);
@ -1213,7 +1214,7 @@ void LimitedNodeList::stopInitialSTUNUpdate(bool success) {
void LimitedNodeList::updateLocalSocket() {
// when update is called, if the local socket is empty then start with the guessed local socket
if (_localSockAddr.isNull()) {
setLocalSocket(HifiSockAddr { getGuessedLocalAddress(), _nodeSocket.localPort() });
setLocalSocket(SockAddr { getGuessedLocalAddress(), _nodeSocket.localPort() });
}
// attempt to use Google's DNS to confirm that local IP
@ -1237,7 +1238,7 @@ void LimitedNodeList::connectedForLocalSocketTest() {
auto localHostAddress = localIPTestSocket->localAddress();
if (localHostAddress.protocol() == QAbstractSocket::IPv4Protocol) {
setLocalSocket(HifiSockAddr { localHostAddress, _nodeSocket.localPort() });
setLocalSocket(SockAddr { localHostAddress, _nodeSocket.localPort() });
_hasTCPCheckedLocalSocket = true;
}
@ -1253,7 +1254,7 @@ void LimitedNodeList::errorTestingLocalSocket() {
// error connecting to the test socket - if we've never set our local socket using this test socket
// then use our possibly updated guessed local address as fallback
if (!_hasTCPCheckedLocalSocket) {
setLocalSocket(HifiSockAddr { getGuessedLocalAddress(), _nodeSocket.localPort() });
setLocalSocket(SockAddr { getGuessedLocalAddress(), _nodeSocket.localPort() });
qCCritical(networking) << "PAGE: Can't connect to Google DNS service via TCP, falling back to guessed local address"
<< getLocalSockAddr();
}
@ -1262,7 +1263,7 @@ void LimitedNodeList::errorTestingLocalSocket() {
}
}
void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) {
void LimitedNodeList::setLocalSocket(const SockAddr& sockAddr) {
if (sockAddr.getAddress() != _localSockAddr.getAddress()) {
if (_localSockAddr.isNull()) {
@ -1283,12 +1284,12 @@ void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) {
}
}
void LimitedNodeList::sendPeerQueryToIceServer(const HifiSockAddr& iceServerSockAddr, const QUuid& clientID,
void LimitedNodeList::sendPeerQueryToIceServer(const SockAddr& iceServerSockAddr, const QUuid& clientID,
const QUuid& peerID) {
sendPacketToIceServer(PacketType::ICEServerQuery, iceServerSockAddr, clientID, peerID);
}
SharedNodePointer LimitedNodeList::findNodeWithAddr(const HifiSockAddr& addr) {
SharedNodePointer LimitedNodeList::findNodeWithAddr(const SockAddr& addr) {
QReadLocker locker(&_nodeMutex);
auto it = std::find_if(std::begin(_nodeHash), std::end(_nodeHash), [&addr](const UUIDNodePair& pair) {
return pair.second->getPublicSocket() == addr
@ -1298,7 +1299,7 @@ SharedNodePointer LimitedNodeList::findNodeWithAddr(const HifiSockAddr& addr) {
return (it != std::end(_nodeHash)) ? it->second : SharedNodePointer();
}
bool LimitedNodeList::sockAddrBelongsToNode(const HifiSockAddr& sockAddr) {
bool LimitedNodeList::sockAddrBelongsToNode(const SockAddr& sockAddr) {
QReadLocker locker(&_nodeMutex);
auto it = std::find_if(std::begin(_nodeHash), std::end(_nodeHash), [&sockAddr](const UUIDNodePair& pair) {
return pair.second->getPublicSocket() == sockAddr
@ -1308,7 +1309,7 @@ bool LimitedNodeList::sockAddrBelongsToNode(const HifiSockAddr& sockAddr) {
return it != std::end(_nodeHash);
}
void LimitedNodeList::sendPacketToIceServer(PacketType packetType, const HifiSockAddr& iceServerSockAddr,
void LimitedNodeList::sendPacketToIceServer(PacketType packetType, const SockAddr& iceServerSockAddr,
const QUuid& clientID, const QUuid& peerID) {
auto icePacket = NLPacket::create(packetType);
@ -1400,7 +1401,7 @@ void LimitedNodeList::flagTimeForConnectionStep(ConnectionStep connectionStep, q
}
}
void LimitedNodeList::clientConnectionToSockAddrReset(const HifiSockAddr& sockAddr) {
void LimitedNodeList::clientConnectionToSockAddrReset(const SockAddr& sockAddr) {
// for certain reliable channels higher level classes may need to know if the udt::Connection has been reset
auto matchingNode = findNodeWithAddr(sockAddr);

View file

@ -145,26 +145,26 @@ public:
virtual bool isDomainServer() const { return true; }
virtual QUuid getDomainUUID() const { assert(false); return QUuid(); }
virtual Node::LocalID getDomainLocalID() const { assert(false); return Node::NULL_LOCAL_ID; }
virtual HifiSockAddr getDomainSockAddr() const { assert(false); return HifiSockAddr(); }
virtual SockAddr getDomainSockAddr() const { assert(false); return SockAddr(); }
// use sendUnreliablePacket to send an unreliable packet (that you do not need to move)
// either to a node (via its active socket) or to a manual sockaddr
qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode);
qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, HMACAuth* hmacAuth = nullptr);
qint64 sendUnreliablePacket(const NLPacket& packet, const SockAddr& sockAddr, HMACAuth* hmacAuth = nullptr);
// use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode);
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const HifiSockAddr& sockAddr, HMACAuth* hmacAuth = nullptr);
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const SockAddr& sockAddr, HMACAuth* hmacAuth = nullptr);
// use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list
// either to a node's active socket or to a manual sockaddr
qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode);
qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr,
qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const SockAddr& sockAddr,
HMACAuth* hmacAuth = nullptr);
// use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket
// or to a manual sock addr
qint64 sendPacketList(std::unique_ptr<NLPacketList> packetList, const HifiSockAddr& sockAddr);
qint64 sendPacketList(std::unique_ptr<NLPacketList> packetList, const SockAddr& sockAddr);
qint64 sendPacketList(std::unique_ptr<NLPacketList> packetList, const Node& destinationNode);
std::function<void(Node*)> linkedDataCreateCallback;
@ -175,7 +175,7 @@ public:
SharedNodePointer nodeWithLocalID(Node::LocalID localID) const;
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
const SockAddr& publicSocket, const SockAddr& localSocket,
Node::LocalID localID = Node::NULL_LOCAL_ID, bool isReplicated = false,
bool isUpstream = false, const QUuid& connectionSecret = QUuid(),
const NodePermissions& permissions = DEFAULT_AGENT_PERMISSIONS);
@ -183,9 +183,9 @@ public:
static bool parseSTUNResponse(udt::BasePacket* packet, QHostAddress& newPublicAddress, uint16_t& newPublicPort);
bool hasCompletedInitialSTUN() const { return _hasCompletedInitialSTUN; }
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
const HifiSockAddr& getPublicSockAddr() const { return _publicSockAddr; }
const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; }
const SockAddr& getLocalSockAddr() const { return _localSockAddr; }
const SockAddr& getPublicSockAddr() const { return _publicSockAddr; }
const SockAddr& getSTUNSockAddr() const { return _stunSockAddr; }
void processKillNode(ReceivedMessage& message);
@ -201,9 +201,9 @@ public:
static std::unique_ptr<NLPacket> constructICEPingPacket(PingType_t pingType, const QUuid& iceID);
static std::unique_ptr<NLPacket> constructICEPingReplyPacket(ReceivedMessage& message, const QUuid& iceID);
void sendPeerQueryToIceServer(const HifiSockAddr& iceServerSockAddr, const QUuid& clientID, const QUuid& peerID);
void sendPeerQueryToIceServer(const SockAddr& iceServerSockAddr, const QUuid& clientID, const QUuid& peerID);
SharedNodePointer findNodeWithAddr(const HifiSockAddr& addr);
SharedNodePointer findNodeWithAddr(const SockAddr& addr);
using value_type = SharedNodePointer;
using const_iterator = std::vector<value_type>::const_iterator;
@ -369,7 +369,7 @@ private slots:
signals:
// QUuid might be zero for non-sourced packet types.
void packetVersionMismatch(PacketType type, const HifiSockAddr& senderSockAddr, const QUuid& senderUUID);
void packetVersionMismatch(PacketType type, const SockAddr& senderSockAddr, const QUuid& senderUUID);
void uuidChanged(const QUuid& ownerUUID, const QUuid& oldUUID);
void nodeAdded(SharedNodePointer);
@ -379,8 +379,8 @@ signals:
void clientConnectionToNodeReset(SharedNodePointer);
void localSockAddrChanged(const HifiSockAddr& localSockAddr);
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
void localSockAddrChanged(const SockAddr& localSockAddr);
void publicSockAddrChanged(const SockAddr& publicSockAddr);
void isAllowedEditorChanged(bool isAllowedEditor);
void canRezChanged(bool canRez);
@ -397,7 +397,7 @@ protected slots:
void connectedForLocalSocketTest();
void errorTestingLocalSocket();
void clientConnectionToSockAddrReset(const HifiSockAddr& sockAddr);
void clientConnectionToSockAddrReset(const SockAddr& sockAddr);
void processDelayedAdds();
@ -405,8 +405,8 @@ protected:
struct NewNodeInfo {
qint8 type;
QUuid uuid;
HifiSockAddr publicSocket;
HifiSockAddr localSocket;
SockAddr publicSocket;
SockAddr localSocket;
NodePermissions permissions;
bool isReplicated;
Node::LocalID sessionLocalID;
@ -418,10 +418,10 @@ protected:
void operator=(LimitedNodeList const&) = delete; // Don't implement, needed to avoid copies of singleton
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode,
const HifiSockAddr& overridenSockAddr);
const SockAddr& overridenSockAddr);
void fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth = nullptr);
void setLocalSocket(const HifiSockAddr& sockAddr);
void setLocalSocket(const SockAddr& sockAddr);
bool packetSourceAndHashMatchAndTrackBandwidth(const udt::Packet& packet, Node* sourceNode = nullptr);
void processSTUNResponse(std::unique_ptr<udt::BasePacket> packet);
@ -430,10 +430,10 @@ protected:
void stopInitialSTUNUpdate(bool success);
void sendPacketToIceServer(PacketType packetType, const HifiSockAddr& iceServerSockAddr, const QUuid& clientID,
void sendPacketToIceServer(PacketType packetType, const SockAddr& iceServerSockAddr, const QUuid& clientID,
const QUuid& peerRequestID = QUuid());
bool sockAddrBelongsToNode(const HifiSockAddr& sockAddr);
bool sockAddrBelongsToNode(const SockAddr& sockAddr);
void addNewNode(NewNodeInfo info);
void delayNodeAdd(NewNodeInfo info);
@ -444,9 +444,9 @@ protected:
mutable QReadWriteLock _nodeMutex { QReadWriteLock::Recursive };
udt::Socket _nodeSocket;
QUdpSocket* _dtlsSocket { nullptr };
HifiSockAddr _localSockAddr;
HifiSockAddr _publicSockAddr;
HifiSockAddr _stunSockAddr { STUN_SERVER_HOSTNAME, STUN_SERVER_PORT };
SockAddr _localSockAddr;
SockAddr _publicSockAddr;
SockAddr _stunSockAddr { STUN_SERVER_HOSTNAME, STUN_SERVER_PORT };
bool _hasTCPCheckedLocalSocket { false };
bool _useAuthentication { true };

View file

@ -4,6 +4,7 @@
//
// Created by Clement on 7/6/15.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -35,7 +36,7 @@ std::unique_ptr<NLPacket> NLPacket::create(PacketType type, qint64 size, bool is
}
std::unique_ptr<NLPacket> NLPacket::fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
const HifiSockAddr& senderSockAddr) {
const SockAddr& senderSockAddr) {
// Fail with null data
Q_ASSERT(data);
@ -89,7 +90,7 @@ NLPacket::NLPacket(const NLPacket& other) : Packet(other) {
_sourceID = other._sourceID;
}
NLPacket::NLPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr) :
NLPacket::NLPacket(std::unique_ptr<char[]> data, qint64 size, const SockAddr& senderSockAddr) :
Packet(std::move(data), size, senderSockAddr)
{
// sanity check before we decrease the payloadSize with the payloadCapacity

View file

@ -4,6 +4,7 @@
//
// Created by Clement on 7/6/15.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -52,7 +53,7 @@ public:
bool isReliable = false, bool isPartOfMessage = false, PacketVersion version = 0);
static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
const HifiSockAddr& senderSockAddr);
const SockAddr& senderSockAddr);
static std::unique_ptr<NLPacket> fromBase(std::unique_ptr<Packet> packet);
@ -87,7 +88,7 @@ public:
protected:
NLPacket(PacketType type, qint64 size = -1, bool forceReliable = false, bool isPartOfMessage = false, PacketVersion version = 0);
NLPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
NLPacket(std::unique_ptr<char[]> data, qint64 size, const SockAddr& senderSockAddr);
NLPacket(const NLPacket& other);
NLPacket(NLPacket&& other);

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2014-10-02.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -37,7 +38,7 @@ NetworkPeer::NetworkPeer(QObject* parent) :
_lastHeardMicrostamp = usecTimestampNow();
}
NetworkPeer::NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, QObject* parent) :
NetworkPeer::NetworkPeer(const QUuid& uuid, const SockAddr& publicSocket, const SockAddr& localSocket, QObject* parent) :
QObject(parent),
_uuid(uuid),
_publicSocket(publicSocket),
@ -50,7 +51,7 @@ NetworkPeer::NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, co
_lastHeardMicrostamp = usecTimestampNow();
}
void NetworkPeer::setPublicSocket(const HifiSockAddr& publicSocket) {
void NetworkPeer::setPublicSocket(const SockAddr& publicSocket) {
if (publicSocket != _publicSocket) {
if (_activeSocket == &_publicSocket) {
// if the active socket was the public socket then reset it to NULL
@ -70,7 +71,7 @@ void NetworkPeer::setPublicSocket(const HifiSockAddr& publicSocket) {
}
}
void NetworkPeer::setLocalSocket(const HifiSockAddr& localSocket) {
void NetworkPeer::setLocalSocket(const SockAddr& localSocket) {
if (localSocket != _localSocket) {
if (_activeSocket == &_localSocket) {
// if the active socket was the local socket then reset it to NULL
@ -90,7 +91,7 @@ void NetworkPeer::setLocalSocket(const HifiSockAddr& localSocket) {
}
}
void NetworkPeer::setSymmetricSocket(const HifiSockAddr& symmetricSocket) {
void NetworkPeer::setSymmetricSocket(const SockAddr& symmetricSocket) {
if (symmetricSocket != _symmetricSocket) {
if (_activeSocket == &_symmetricSocket) {
// if the active socket was the symmetric socket then reset it to NULL
@ -110,7 +111,7 @@ void NetworkPeer::setSymmetricSocket(const HifiSockAddr& symmetricSocket) {
}
}
void NetworkPeer::setActiveSocket(HifiSockAddr* discoveredSocket) {
void NetworkPeer::setActiveSocket(SockAddr* discoveredSocket) {
_activeSocket = discoveredSocket;
// we have an active socket, stop our ping timer
@ -145,7 +146,7 @@ void NetworkPeer::activateSymmetricSocket() {
}
}
void NetworkPeer::activateMatchingOrNewSymmetricSocket(const HifiSockAddr& matchableSockAddr) {
void NetworkPeer::activateMatchingOrNewSymmetricSocket(const SockAddr& matchableSockAddr) {
if (matchableSockAddr == _publicSocket) {
activatePublicSocket();
} else if (matchableSockAddr == _localSocket) {

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2014-10-02.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -18,7 +19,7 @@
#include <QtCore/QTimer>
#include <QtCore/QUuid>
#include "HifiSockAddr.h"
#include "SockAddr.h"
#include "UUID.h"
const QString ICE_SERVER_HOSTNAME = "localhost";
@ -32,7 +33,7 @@ class NetworkPeer : public QObject {
Q_OBJECT
public:
NetworkPeer(QObject* parent = 0);
NetworkPeer(const QUuid& uuid, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, QObject* parent = 0);
NetworkPeer(const QUuid& uuid, const SockAddr& publicSocket, const SockAddr& localSocket, QObject* parent = 0);
bool isNull() const { return _uuid.isNull(); }
bool hasSockets() const { return !_localSocket.isNull() && !_publicSocket.isNull(); }
@ -49,21 +50,21 @@ public:
void softReset();
void reset();
const HifiSockAddr& getPublicSocket() const { return _publicSocket; }
const HifiSockAddr& getLocalSocket() const { return _localSocket; }
const HifiSockAddr& getSymmetricSocket() const { return _symmetricSocket; }
const SockAddr& getPublicSocket() const { return _publicSocket; }
const SockAddr& getLocalSocket() const { return _localSocket; }
const SockAddr& getSymmetricSocket() const { return _symmetricSocket; }
void setPublicSocket(const HifiSockAddr& publicSocket);
void setLocalSocket(const HifiSockAddr& localSocket);
void setSymmetricSocket(const HifiSockAddr& symmetricSocket);
void setPublicSocket(const SockAddr& publicSocket);
void setLocalSocket(const SockAddr& localSocket);
void setSymmetricSocket(const SockAddr& symmetricSocket);
const HifiSockAddr* getActiveSocket() const { return _activeSocket; }
const SockAddr* getActiveSocket() const { return _activeSocket; }
void activatePublicSocket();
void activateLocalSocket();
void activateSymmetricSocket();
void activateMatchingOrNewSymmetricSocket(const HifiSockAddr& matchableSockAddr);
void activateMatchingOrNewSymmetricSocket(const SockAddr& matchableSockAddr);
quint64 getWakeTimestamp() const { return _wakeTimestamp; }
void setWakeTimestamp(quint64 wakeTimestamp) { _wakeTimestamp = wakeTimestamp; }
@ -93,19 +94,19 @@ public slots:
signals:
void pingTimerTimeout();
void socketActivated(const HifiSockAddr& sockAddr);
void socketUpdated(HifiSockAddr previousAddress, HifiSockAddr currentAddress);
void socketActivated(const SockAddr& sockAddr);
void socketUpdated(SockAddr previousAddress, SockAddr currentAddress);
protected:
void setActiveSocket(HifiSockAddr* discoveredSocket);
void setActiveSocket(SockAddr* discoveredSocket);
QUuid _uuid;
LocalID _localID { 0 };
HifiSockAddr _publicSocket;
HifiSockAddr _localSocket;
HifiSockAddr _symmetricSocket;
HifiSockAddr* _activeSocket;
SockAddr _publicSocket;
SockAddr _localSocket;
SockAddr _symmetricSocket;
SockAddr* _activeSocket;
quint64 _wakeTimestamp;
std::atomic_ullong _lastHeardMicrostamp;

View file

@ -25,7 +25,7 @@ namespace NetworkingConstants {
// You can avoid changing that and still effectively use a connected domain on staging
// if you manually generate a personal access token for the domains scope
// at https://staging.highfidelity.com/user/tokens/new?for_domain_server=true
const QString WEB_ENGINE_VERSION = "Chrome/83.0.4103.122";
// For now we only have one Metaverse server.
@ -35,21 +35,21 @@ namespace NetworkingConstants {
// Web Engine requests to this parent domain have an account authorization header added
const QString AUTH_HOSTNAME_BASE = "vircadia.com";
const QStringList IS_AUTHABLE_HOSTNAME = { "vircadia.com", "vircadia.io" };
// Use a custom User-Agent to avoid ModSecurity filtering, e.g. by hosting providers.
const QByteArray VIRCADIA_USER_AGENT = "Mozilla/5.0 (VircadiaInterface)";
const QString WEB_ENGINE_USER_AGENT = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) " + WEB_ENGINE_VERSION + " Mobile Safari/537.36";
const QString MOBILE_USER_AGENT = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) " + WEB_ENGINE_VERSION + " Mobile Safari/537.36";
// WebEntity Defaults
const QString WEB_ENTITY_DEFAULT_SOURCE_URL = "https://vircadia.com/";
const QString WEB_ENTITY_DEFAULT_USER_AGENT = WEB_ENGINE_USER_AGENT;
// Builds URLs
const QUrl BUILDS_XML_URL("https://highfidelity.com/builds.xml");
const QUrl MASTER_BUILDS_XML_URL("https://highfidelity.com/dev-builds.xml");
const QString DEFAULT_AVATAR_COLLISION_SOUND_URL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/Body_Hits_Impact.wav";
// CDN URLs
@ -71,20 +71,20 @@ namespace NetworkingConstants {
const unsigned short STUN_SERVER_DEFAULT_PORT = 19302;
#endif
const QUrl HELP_DOCS_URL { "https://docs.vircadia.dev" };
const QUrl HELP_FORUM_URL { "https://forums.vircadia.dev" };
const QUrl HELP_DOCS_URL { "https://docs.vircadia.com" };
const QUrl HELP_FORUM_URL { "https://forum.vircadia.com" };
const QUrl HELP_SCRIPTING_REFERENCE_URL{ "https://apidocs.vircadia.dev/" };
const QUrl HELP_RELEASE_NOTES_URL{ "https://docs.vircadia.dev/release-notes.html" };
const QUrl HELP_RELEASE_NOTES_URL{ "https://docs.vircadia.com/release-notes.html" };
const QUrl HELP_BUG_REPORT_URL{ "https://github.com/vircadia/vircadia/issues" };
const QString DEFAULT_VIRCADIA_ADDRESS = "file:///~/serverless/tutorial.json";
const QString DEFAULT_HOME_ADDRESS = "file:///~/serverless/tutorial.json";
const QString REDIRECT_HIFI_ADDRESS = "file:///~/serverless/redirect.json";
}
const QString HIFI_URL_SCHEME_ABOUT = "about";
const QString URL_SCHEME_HIFI = "hifi";
const QString URL_SCHEME_HIFIAPP = "hifiapp";
const QString URL_SCHEME_VIRCADIA = "hifi";
const QString URL_SCHEME_VIRCADIAAPP = "hifiapp";
const QString URL_SCHEME_DATA = "data";
const QString URL_SCHEME_QRC = "qrc";
const QString HIFI_URL_SCHEME_FILE = "file";

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2/15/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -85,8 +86,8 @@ NodeType_t NodeType::fromString(QString type) {
}
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
const HifiSockAddr& localSocket, QObject* parent) :
Node::Node(const QUuid& uuid, NodeType_t type, const SockAddr& publicSocket,
const SockAddr& localSocket, QObject* parent) :
NetworkPeer(uuid, publicSocket, localSocket, parent),
_type(type),
_pingMs(-1), // "Uninitialized"

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2/15/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -27,7 +28,7 @@
#include <TBBHelpers.h>
#include "HifiSockAddr.h"
#include "SockAddr.h"
#include "NetworkPeer.h"
#include "NodeData.h"
#include "NodeType.h"
@ -44,7 +45,7 @@ public:
using Stats = udt::ConnectionStats::Stats;
Node(const QUuid& uuid, NodeType_t type,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
const SockAddr& publicSocket, const SockAddr& localSocket,
QObject* parent = nullptr);
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }

View file

@ -35,7 +35,7 @@
#include "Assignment.h"
#include "AudioHelpers.h"
#include "DomainAccountManager.h"
#include "HifiSockAddr.h"
#include "SockAddr.h"
#include "FingerprintUtils.h"
#include "NetworkLogging.h"
@ -176,11 +176,11 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort)
PacketReceiver::makeUnsourcedListenerReference<NodeList>(this, &NodeList::processUsernameFromIDReply));
}
qint64 NodeList::sendStats(QJsonObject statsObject, HifiSockAddr destination) {
qint64 NodeList::sendStats(QJsonObject statsObject, SockAddr destination) {
if (thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "sendStats", Qt::QueuedConnection,
Q_ARG(QJsonObject, statsObject),
Q_ARG(HifiSockAddr, destination));
Q_ARG(SockAddr, destination));
return 0;
}
@ -245,7 +245,7 @@ void NodeList::timePingReply(ReceivedMessage& message, const SharedNodePointer&
void NodeList::processPingPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
// send back a reply
auto replyPacket = constructPingReplyPacket(*message);
const HifiSockAddr& senderSockAddr = message->getSenderSockAddr();
const SockAddr& senderSockAddr = message->getSenderSockAddr();
sendPacket(std::move(replyPacket), *sendingNode, senderSockAddr);
// If we don't have a symmetric socket for this node and this socket doesn't match
@ -364,7 +364,7 @@ void NodeList::sendDomainServerCheckIn() {
// let the domain handler know we are due to send a checkin packet
} else if (!domainHandlerIp.isNull() && !_domainHandler.checkInPacketTimeout()) {
bool domainIsConnected = _domainHandler.isConnected();
HifiSockAddr domainSockAddr = _domainHandler.getSockAddr();
SockAddr domainSockAddr = _domainHandler.getSockAddr();
PacketType domainPacketType = !domainIsConnected
? PacketType::DomainConnectRequest : PacketType::DomainListRequest;
@ -405,7 +405,7 @@ void NodeList::sendDomainServerCheckIn() {
QDataStream packetStream(domainPacket.get());
HifiSockAddr localSockAddr = _localSockAddr;
SockAddr localSockAddr = _localSockAddr;
if (domainPacketType == PacketType::DomainConnectRequest) {
#if (PR_BUILD || DEV_BUILD)
@ -823,8 +823,8 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
// FIXME: Remove this call to requestDomainSettings() and reinstate the one in DomainHandler::setIsConnected(), in version
// 2021.2.0. (New protocol version implies a domain server upgrade.)
if (!_domainHandler.isConnected()
&& _domainHandler.getScheme() == URL_SCHEME_HIFI && !_domainHandler.getHostname().isEmpty()) {
if (!_domainHandler.isConnected()
&& _domainHandler.getScheme() == URL_SCHEME_VIRCADIA && !_domainHandler.getHostname().isEmpty()) {
// We're about to connect but we need the domain settings (in particular, the node permissions) in order to adjust the
// canRezAvatarEntities permission above before using the permissions in determining whether or not to connect without
// avatar entities rezzing below.
@ -1012,7 +1012,7 @@ void NodeList::sendKeepAlivePings() {
});
}
bool NodeList::sockAddrBelongsToDomainOrNode(const HifiSockAddr& sockAddr) {
bool NodeList::sockAddrBelongsToDomainOrNode(const SockAddr& sockAddr) {
return _domainHandler.getSockAddr() == sockAddr || LimitedNodeList::sockAddrBelongsToNode(sockAddr);
}

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2/15/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -57,7 +58,7 @@ public:
NodeType_t getOwnerType() const { return _ownerType.load(); }
void setOwnerType(NodeType_t ownerType) { _ownerType.store(ownerType); }
Q_INVOKABLE qint64 sendStats(QJsonObject statsObject, HifiSockAddr destination);
Q_INVOKABLE qint64 sendStats(QJsonObject statsObject, SockAddr destination);
Q_INVOKABLE qint64 sendStatsToDomainServer(QJsonObject statsObject);
DomainHandler& getDomainHandler() { return _domainHandler; }
@ -67,7 +68,7 @@ public:
void addSetOfNodeTypesToNodeInterestSet(const NodeSet& setOfNodeTypes);
void resetNodeInterestSet() { _nodeTypesOfInterest.clear(); }
void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; }
void setAssignmentServerSocket(const SockAddr& serverSocket) { _assignmentServerSocket = serverSocket; }
void sendAssignment(Assignment& assignment);
void disableDomainPortAutoDiscovery(bool disabled = false) { _domainPortAutoDiscovery = disabled; };
@ -102,7 +103,7 @@ public:
virtual bool isDomainServer() const override { return false; }
virtual QUuid getDomainUUID() const override { return _domainHandler.getUUID(); }
virtual Node::LocalID getDomainLocalID() const override { return _domainHandler.getLocalID(); }
virtual HifiSockAddr getDomainSockAddr() const override { return _domainHandler.getSockAddr(); }
virtual SockAddr getDomainSockAddr() const override { return _domainHandler.getSockAddr(); }
public slots:
void reset(QString reason, bool skipDomainHandlerReset = false);
@ -171,12 +172,12 @@ private:
void pingPunchForInactiveNode(const SharedNodePointer& node);
bool sockAddrBelongsToDomainOrNode(const HifiSockAddr& sockAddr);
bool sockAddrBelongsToDomainOrNode(const SockAddr& sockAddr);
std::atomic<NodeType_t> _ownerType;
NodeSet _nodeTypesOfInterest;
DomainHandler _domainHandler;
HifiSockAddr _assignmentServerSocket;
SockAddr _assignmentServerSocket;
bool _isShuttingDown { false };
QTimer _keepAlivePingTimer;
bool _requestsDomainListData { false };

View file

@ -5,6 +5,7 @@
// Created by Stephen Birarda on 1/23/2014.
// Update by Ryan Huffman on 7/8/2015.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -152,7 +153,7 @@ void PacketReceiver::handleVerifiedPacket(std::unique_ptr<udt::Packet> packet) {
void PacketReceiver::handleVerifiedMessagePacket(std::unique_ptr<udt::Packet> packet) {
auto nlPacket = NLPacket::fromBase(std::move(packet));
auto key = std::pair<HifiSockAddr, udt::Packet::MessageNumber>(nlPacket->getSenderSockAddr(), nlPacket->getMessageNumber());
auto key = std::pair<SockAddr, udt::Packet::MessageNumber>(nlPacket->getSenderSockAddr(), nlPacket->getMessageNumber());
auto it = _pendingMessages.find(key);
QSharedPointer<ReceivedMessage> message;
@ -174,8 +175,8 @@ void PacketReceiver::handleVerifiedMessagePacket(std::unique_ptr<udt::Packet> pa
}
}
void PacketReceiver::handleMessageFailure(HifiSockAddr from, udt::Packet::MessageNumber messageNumber) {
auto key = std::pair<HifiSockAddr, udt::Packet::MessageNumber>(from, messageNumber);
void PacketReceiver::handleMessageFailure(SockAddr from, udt::Packet::MessageNumber messageNumber) {
auto key = std::pair<SockAddr, udt::Packet::MessageNumber>(from, messageNumber);
auto it = _pendingMessages.find(key);
if (it != _pendingMessages.end()) {
auto message = it->second;

View file

@ -5,6 +5,7 @@
// Created by Stephen Birarda on 1/23/2014.
// Update by Ryan Huffman on 7/8/2015.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -34,9 +35,9 @@ class OctreePacketProcessor;
namespace std {
template <>
struct hash<std::pair<HifiSockAddr, udt::Packet::MessageNumber>> {
size_t operator()(const std::pair<HifiSockAddr, udt::Packet::MessageNumber>& pair) const {
return hash<HifiSockAddr>()(pair.first) ^ hash<udt::Packet::MessageNumber>()(pair.second);
struct hash<std::pair<SockAddr, udt::Packet::MessageNumber>> {
size_t operator()(const std::pair<SockAddr, udt::Packet::MessageNumber>& pair) const {
return hash<SockAddr>()(pair.first) ^ hash<udt::Packet::MessageNumber>()(pair.second);
}
};
}
@ -78,7 +79,7 @@ public:
void handleVerifiedPacket(std::unique_ptr<udt::Packet> packet);
void handleVerifiedMessagePacket(std::unique_ptr<udt::Packet> message);
void handleMessageFailure(HifiSockAddr from, udt::Packet::MessageNumber messageNumber);
void handleMessageFailure(SockAddr from, udt::Packet::MessageNumber messageNumber);
private:
template <class T>
@ -129,7 +130,7 @@ private:
QMutex _directConnectSetMutex;
QSet<QObject*> _directlyConnectedObjects;
std::unordered_map<std::pair<HifiSockAddr, udt::Packet::MessageNumber>, QSharedPointer<ReceivedMessage>> _pendingMessages;
std::unordered_map<std::pair<SockAddr, udt::Packet::MessageNumber>, QSharedPointer<ReceivedMessage>> _pendingMessages;
friend class EntityEditPacketSender;
friend class OctreePacketProcessor;

View file

@ -4,6 +4,7 @@
//
// Created by Ryan Huffman on 2015/09/17
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -49,7 +50,7 @@ ReceivedMessage::ReceivedMessage(NLPacket& packet)
}
ReceivedMessage::ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion,
const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID) :
const SockAddr& senderSockAddr, NLPacket::LocalID sourceID) :
_data(byteArray),
_headData(_data.mid(0, HEAD_DATA_SIZE)),
_numPackets(1),

View file

@ -4,6 +4,7 @@
//
// Created by Ryan Huffman on 2015/09/15
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -25,7 +26,7 @@ public:
ReceivedMessage(const NLPacketList& packetList);
ReceivedMessage(NLPacket& packet);
ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion,
const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID = NLPacket::NULL_LOCAL_ID);
const SockAddr& senderSockAddr, NLPacket::LocalID sourceID = NLPacket::NULL_LOCAL_ID);
QByteArray getMessage() const { return _data; }
const char* getRawMessage() const { return _data.constData(); }
@ -41,7 +42,7 @@ public:
bool isComplete() const { return _isComplete; }
NLPacket::LocalID getSourceID() const { return _sourceID; }
const HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; }
const SockAddr& getSenderSockAddr() { return _senderSockAddr; }
qint64 getPosition() const { return _position; }
@ -99,7 +100,7 @@ private:
NLPacket::LocalID _sourceID { NLPacket::NULL_LOCAL_ID };
PacketType _packetType;
PacketVersion _packetVersion;
HifiSockAddr _senderSockAddr;
SockAddr _senderSockAddr;
std::atomic<bool> _isComplete { true };
std::atomic<bool> _failed { false };

View file

@ -1,15 +1,16 @@
//
// HifiSockAddr.cpp
// SockAddr.cpp
// libraries/networking/src
//
// Created by Stephen Birarda on 11/26/2013.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "HifiSockAddr.h"
#include "SockAddr.h"
#include <qdatastream.h>
#include <qhostinfo.h>
@ -24,23 +25,23 @@
#include <netinet/in.h>
#endif
int hifiSockAddrMetaTypeId = qRegisterMetaType<HifiSockAddr>();
int sockAddrMetaTypeId = qRegisterMetaType<SockAddr>();
HifiSockAddr::HifiSockAddr() :
SockAddr::SockAddr() :
_address(),
_port(0)
{
}
HifiSockAddr::HifiSockAddr(const QHostAddress& address, quint16 port) :
SockAddr::SockAddr(const QHostAddress& address, quint16 port) :
_address(address),
_port(port)
{
}
HifiSockAddr::HifiSockAddr(const HifiSockAddr& otherSockAddr) :
SockAddr::SockAddr(const SockAddr& otherSockAddr) :
QObject(),
_address(otherSockAddr._address),
_port(otherSockAddr._port)
@ -48,14 +49,14 @@ HifiSockAddr::HifiSockAddr(const HifiSockAddr& otherSockAddr) :
setObjectName(otherSockAddr.objectName());
}
HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) {
SockAddr& SockAddr::operator=(const SockAddr& rhsSockAddr) {
setObjectName(rhsSockAddr.objectName());
_address = rhsSockAddr._address;
_port = rhsSockAddr._port;
return *this;
}
HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort, bool shouldBlockForLookup) :
SockAddr::SockAddr(const QString& hostname, quint16 hostOrderPort, bool shouldBlockForLookup) :
_address(hostname),
_port(hostOrderPort)
{
@ -73,7 +74,7 @@ HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort, bool
}
}
HifiSockAddr::HifiSockAddr(const sockaddr* sockaddr) {
SockAddr::SockAddr(const sockaddr* sockaddr) {
_address = QHostAddress(sockaddr);
if (sockaddr->sa_family == AF_INET) {
@ -83,7 +84,7 @@ HifiSockAddr::HifiSockAddr(const sockaddr* sockaddr) {
}
}
void HifiSockAddr::swap(HifiSockAddr& otherSockAddr) {
void SockAddr::swap(SockAddr& otherSockAddr) {
using std::swap;
swap(_address, otherSockAddr._address);
@ -95,11 +96,11 @@ void HifiSockAddr::swap(HifiSockAddr& otherSockAddr) {
setObjectName(temp);
}
bool HifiSockAddr::operator==(const HifiSockAddr& rhsSockAddr) const {
bool SockAddr::operator==(const SockAddr& rhsSockAddr) const {
return _address == rhsSockAddr._address && _port == rhsSockAddr._port;
}
void HifiSockAddr::handleLookupResult(const QHostInfo& hostInfo) {
void SockAddr::handleLookupResult(const QHostInfo& hostInfo) {
if (hostInfo.error() != QHostInfo::NoError) {
qCDebug(networking) << "Lookup failed for" << hostInfo.lookupId() << ":" << hostInfo.errorString();
emit lookupFailed();
@ -117,11 +118,11 @@ void HifiSockAddr::handleLookupResult(const QHostInfo& hostInfo) {
}
}
QString HifiSockAddr::toString() const {
QString SockAddr::toString() const {
return _address.toString() + ":" + QString::number(_port);
}
bool HifiSockAddr::hasPrivateAddress() const {
bool SockAddr::hasPrivateAddress() const {
// an address is private if it is loopback or falls in any of the RFC1918 address spaces
const QPair<QHostAddress, int> TWENTY_FOUR_BIT_BLOCK = { QHostAddress("10.0.0.0"), 8 };
const QPair<QHostAddress, int> TWENTY_BIT_BLOCK = { QHostAddress("172.16.0.0") , 12 };
@ -133,22 +134,22 @@ bool HifiSockAddr::hasPrivateAddress() const {
|| _address.isInSubnet(SIXTEEN_BIT_BLOCK);
}
QDebug operator<<(QDebug debug, const HifiSockAddr& sockAddr) {
QDebug operator<<(QDebug debug, const SockAddr& sockAddr) {
debug.nospace() << sockAddr._address.toString().toLocal8Bit().constData() << ":" << sockAddr._port;
return debug.space();
}
QDataStream& operator<<(QDataStream& dataStream, const HifiSockAddr& sockAddr) {
QDataStream& operator<<(QDataStream& dataStream, const SockAddr& sockAddr) {
dataStream << sockAddr._address << sockAddr._port;
return dataStream;
}
QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr) {
QDataStream& operator>>(QDataStream& dataStream, SockAddr& sockAddr) {
dataStream >> sockAddr._address >> sockAddr._port;
return dataStream;
}
uint qHash(const HifiSockAddr& key, uint seed) {
uint qHash(const SockAddr& key, uint seed) {
// use the existing QHostAddress and quint16 hash functions to get our hash
return qHash(key.getAddress(), seed) ^ qHash(key.getPort(), seed);
}

View file

@ -1,16 +1,17 @@
//
// HifiSockAddr.h
// SockAddr.h
// libraries/networking/src
//
// Created by Stephen Birarda on 11/26/2013.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_HifiSockAddr_h
#define hifi_HifiSockAddr_h
#ifndef hifi_SockAddr_h
#define hifi_SockAddr_h
#include <cstdint>
#include <string>
@ -19,23 +20,23 @@ struct sockaddr;
#include <QtNetwork/QHostInfo>
class HifiSockAddr : public QObject {
class SockAddr : public QObject {
Q_OBJECT
public:
HifiSockAddr();
HifiSockAddr(const QHostAddress& address, quint16 port);
HifiSockAddr(const HifiSockAddr& otherSockAddr);
HifiSockAddr(const QString& hostname, quint16 hostOrderPort, bool shouldBlockForLookup = false);
HifiSockAddr(const sockaddr* sockaddr);
SockAddr();
SockAddr(const QHostAddress& address, quint16 port);
SockAddr(const SockAddr& otherSockAddr);
SockAddr(const QString& hostname, quint16 hostOrderPort, bool shouldBlockForLookup = false);
SockAddr(const sockaddr* sockaddr);
bool isNull() const { return _address.isNull() && _port == 0; }
void clear() { _address.clear(); _port = 0;}
HifiSockAddr& operator=(const HifiSockAddr& rhsSockAddr);
void swap(HifiSockAddr& otherSockAddr);
SockAddr& operator=(const SockAddr& rhsSockAddr);
void swap(SockAddr& otherSockAddr);
bool operator==(const HifiSockAddr& rhsSockAddr) const;
bool operator!=(const HifiSockAddr& rhsSockAddr) const { return !(*this == rhsSockAddr); }
bool operator==(const SockAddr& rhsSockAddr) const;
bool operator!=(const SockAddr& rhsSockAddr) const { return !(*this == rhsSockAddr); }
const QHostAddress& getAddress() const { return _address; }
QHostAddress* getAddressPointer() { return &_address; }
@ -45,16 +46,16 @@ public:
quint16* getPortPointer() { return &_port; }
void setPort(quint16 port) { _port = port; }
static int packSockAddr(unsigned char* packetData, const HifiSockAddr& packSockAddr);
static int unpackSockAddr(const unsigned char* packetData, HifiSockAddr& unpackDestSockAddr);
static int packSockAddr(unsigned char* packetData, const SockAddr& packSockAddr);
static int unpackSockAddr(const unsigned char* packetData, SockAddr& unpackDestSockAddr);
QString toString() const;
bool hasPrivateAddress() const; // checks if the address behind this sock addr is private per RFC 1918
friend QDebug operator<<(QDebug debug, const HifiSockAddr& sockAddr);
friend QDataStream& operator<<(QDataStream& dataStream, const HifiSockAddr& sockAddr);
friend QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr);
friend QDebug operator<<(QDebug debug, const SockAddr& sockAddr);
friend QDataStream& operator<<(QDataStream& dataStream, const SockAddr& sockAddr);
friend QDataStream& operator>>(QDataStream& dataStream, SockAddr& sockAddr);
private slots:
void handleLookupResult(const QHostInfo& hostInfo);
@ -66,14 +67,14 @@ private:
quint16 _port;
};
uint qHash(const HifiSockAddr& key, uint seed);
uint qHash(const SockAddr& key, uint seed);
namespace std {
template <>
struct hash<HifiSockAddr> {
struct hash<SockAddr> {
// NOTE: this hashing specifically ignores IPv6 addresses - if we begin to support those we will need
// to conditionally hash the bytes that represent an IPv6 address
size_t operator()(const HifiSockAddr& sockAddr) const {
size_t operator()(const SockAddr& sockAddr) const {
// use XOR of implemented std::hash templates for new hash
// depending on the type of address we're looking at
@ -90,6 +91,6 @@ namespace std {
};
}
Q_DECLARE_METATYPE(HifiSockAddr);
Q_DECLARE_METATYPE(SockAddr);
#endif // hifi_HifiSockAddr_h
#endif // hifi_SockAddr_h

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2015-07-23.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -36,7 +37,7 @@ std::unique_ptr<BasePacket> BasePacket::create(qint64 size) {
}
std::unique_ptr<BasePacket> BasePacket::fromReceivedPacket(std::unique_ptr<char[]> data,
qint64 size, const HifiSockAddr& senderSockAddr) {
qint64 size, const SockAddr& senderSockAddr) {
// Fail with invalid size
Q_ASSERT(size >= 0);
@ -66,7 +67,7 @@ BasePacket::BasePacket(qint64 size) {
_payloadStart = _packet.get();
}
BasePacket::BasePacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr) :
BasePacket::BasePacket(std::unique_ptr<char[]> data, qint64 size, const SockAddr& senderSockAddr) :
_packetSize(size),
_packet(std::move(data)),
_payloadStart(_packet.get()),

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 2015-07-23.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -18,7 +19,7 @@
#include <PortableHighResolutionClock.h>
#include "../HifiSockAddr.h"
#include "../SockAddr.h"
#include "Constants.h"
#include "../ExtendedIODevice.h"
@ -31,7 +32,7 @@ public:
static std::unique_ptr<BasePacket> create(qint64 size = -1);
static std::unique_ptr<BasePacket> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
const HifiSockAddr& senderSockAddr);
const SockAddr& senderSockAddr);
// Current level's header size
static int localHeaderSize();
@ -66,8 +67,8 @@ public:
qint64 bytesLeftToRead() const { return _payloadSize - pos(); }
qint64 bytesAvailableForWrite() const { return _payloadCapacity - pos(); }
HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; }
const HifiSockAddr& getSenderSockAddr() const { return _senderSockAddr; }
SockAddr& getSenderSockAddr() { return _senderSockAddr; }
const SockAddr& getSenderSockAddr() const { return _senderSockAddr; }
// QIODevice virtual functions
// WARNING: Those methods all refer to the payload ONLY and NOT the entire packet
@ -87,7 +88,7 @@ public:
protected:
BasePacket(qint64 size);
BasePacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
BasePacket(std::unique_ptr<char[]> data, qint64 size, const SockAddr& senderSockAddr);
BasePacket(const BasePacket& other) : ExtendedIODevice() { *this = other; }
BasePacket& operator=(const BasePacket& other);
BasePacket(BasePacket&& other);
@ -107,7 +108,7 @@ protected:
qint64 _payloadSize = 0; // How much of the payload is actually used
HifiSockAddr _senderSockAddr; // sender address for packet (only used on receiving end)
SockAddr _senderSockAddr; // sender address for packet (only used on receiving end)
p_high_resolution_clock::time_point _receiveTime; // captures the time the packet received (only used on receiving end)
};

View file

@ -4,6 +4,7 @@
//
// Created by Clement on 7/27/15.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -17,7 +18,7 @@
#include <NumericalConstants.h>
#include "../HifiSockAddr.h"
#include "../SockAddr.h"
#include "../NetworkLogging.h"
#include "CongestionControl.h"
@ -30,7 +31,7 @@
using namespace udt;
using namespace std::chrono;
Connection::Connection(Socket* parentSocket, HifiSockAddr destination, std::unique_ptr<CongestionControl> congestionControl) :
Connection::Connection(Socket* parentSocket, SockAddr destination, std::unique_ptr<CongestionControl> congestionControl) :
_parentSocket(parentSocket),
_destination(destination),
_congestionControl(move(congestionControl))
@ -485,7 +486,7 @@ std::unique_ptr<Packet> PendingReceivedMessage::removeNextPacket() {
return std::unique_ptr<Packet>();
}
void Connection::setDestinationAddress(const HifiSockAddr& destination) {
void Connection::setDestinationAddress(const SockAddr& destination) {
if (_destination != destination) {
_destination = destination;
emit destinationAddressChange(destination);

View file

@ -4,6 +4,7 @@
//
// Created by Clement on 7/27/15.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -23,7 +24,7 @@
#include "Constants.h"
#include "LossList.h"
#include "SendQueue.h"
#include "../HifiSockAddr.h"
#include "../SockAddr.h"
namespace udt {
@ -52,7 +53,7 @@ class Connection : public QObject {
public:
using ControlPacketPointer = std::unique_ptr<ControlPacket>;
Connection(Socket* parentSocket, HifiSockAddr destination, std::unique_ptr<CongestionControl> congestionControl);
Connection(Socket* parentSocket, SockAddr destination, std::unique_ptr<CongestionControl> congestionControl);
virtual ~Connection();
void sendReliablePacket(std::unique_ptr<Packet> packet);
@ -68,7 +69,7 @@ public:
ConnectionStats::Stats sampleStats() { return _stats.sample(); }
HifiSockAddr getDestination() const { return _destination; }
SockAddr getDestination() const { return _destination; }
void setMaxBandwidth(int maxBandwidth);
@ -77,12 +78,12 @@ public:
void recordSentUnreliablePackets(int wireSize, int payloadSize);
void recordReceivedUnreliablePackets(int wireSize, int payloadSize);
void setDestinationAddress(const HifiSockAddr& destination);
void setDestinationAddress(const SockAddr& destination);
signals:
void packetSent();
void receiverHandshakeRequestComplete(const HifiSockAddr& sockAddr);
void destinationAddressChange(HifiSockAddr currentAddress);
void receiverHandshakeRequestComplete(const SockAddr& sockAddr);
void destinationAddressChange(SockAddr currentAddress);
private slots:
void recordSentPackets(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint);
@ -124,7 +125,7 @@ private:
SequenceNumber _lastReceivedACK; // The last ACK received
Socket* _parentSocket { nullptr };
HifiSockAddr _destination;
SockAddr _destination;
std::unique_ptr<CongestionControl> _congestionControl;

Some files were not shown because too many files have changed in this diff Show more