mirror of
https://github.com/lubosz/overte.git
synced 2025-04-07 16:42:08 +02:00
merge with master
This commit is contained in:
commit
7f99ddca2e
501 changed files with 14909 additions and 6475 deletions
17
.github/stale.yml
vendored
Normal file
17
.github/stale.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 120
|
||||
# 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
|
||||
# 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.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
6
.github/workflows/master_build.yml
vendored
6
.github/workflows/master_build.yml
vendored
|
@ -35,7 +35,7 @@ jobs:
|
|||
include:
|
||||
- os: ubuntu-18.04
|
||||
build_type: full
|
||||
apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0
|
||||
apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0 libsnappy1v5 libwebpdemux2 libwebpmux3
|
||||
fail-fast: false
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
|
@ -50,6 +50,7 @@ jobs:
|
|||
echo "UPLOAD_PREFIX=master" >> $GITHUB_ENV
|
||||
echo ::set-output name=github_sha_short::`echo $GIT_COMMIT | cut -c1-7`
|
||||
echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV
|
||||
echo "APP_TARGET_NAME=$APP_NAME" >> $GITHUB_ENV
|
||||
# Linux build variables
|
||||
if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then
|
||||
echo "PYTHON_EXEC=python3" >> $GITHUB_ENV
|
||||
|
@ -65,6 +66,7 @@ jobs:
|
|||
echo "INSTALLER_EXT=dmg" >> $GITHUB_ENV
|
||||
echo "CMAKE_EXTRA=-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" >> $GITHUB_ENV
|
||||
echo "::set-output name=symbols_archive::${BUILD_NUMBER}-${{ matrix.build_type }}-mac-symbols.zip"
|
||||
echo "APP_TARGET_NAME=Vircadia" >> $GITHUB_ENV
|
||||
fi
|
||||
# Windows build variables
|
||||
if [ "${{ matrix.os }}" = "windows-latest" ]; then
|
||||
|
@ -126,7 +128,7 @@ jobs:
|
|||
- name: Build application
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target $APP_NAME $CMAKE_BUILD_EXTRA
|
||||
run: cmake --build . --config $BUILD_TYPE --target $APP_TARGET_NAME $CMAKE_BUILD_EXTRA
|
||||
- name: Build domain server
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
|
|
48
.github/workflows/pr_build.yml
vendored
48
.github/workflows/pr_build.yml
vendored
|
@ -36,9 +36,11 @@ jobs:
|
|||
build_type: full
|
||||
- os: macOS-latest
|
||||
build_type: full
|
||||
- os: macOS-latest
|
||||
build_type: client
|
||||
- os: ubuntu-18.04
|
||||
build_type: full
|
||||
apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0
|
||||
apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0 libsnappy1v5 libwebpdemux2 libwebpmux3
|
||||
- os: ubuntu-18.04
|
||||
build_type: android
|
||||
apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0
|
||||
|
@ -52,25 +54,39 @@ jobs:
|
|||
run: |
|
||||
echo ::set-output name=github_sha_short::`echo $GIT_COMMIT | cut -c1-7`
|
||||
echo "JOB_NAME=build (${{matrix.os}}, ${{matrix.build_type}})" >> $GITHUB_ENV
|
||||
echo "APP_TARGET_NAME=$APP_NAME" >> $GITHUB_ENV
|
||||
|
||||
# Linux build variables
|
||||
if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then
|
||||
echo "PYTHON_EXEC=python3" >> $GITHUB_ENV
|
||||
echo "INSTALLER_EXT=*" >> $GITHUB_ENV
|
||||
echo "CMAKE_BUILD_EXTRA=-- -j3" >> $GITHUB_ENV
|
||||
echo "CMAKE_EXTRA=-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" >> $GITHUB_ENV
|
||||
if [ "${{ matrix.build_type }}" = "full" ]; then
|
||||
echo "CMAKE_EXTRA=-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CMAKE_EXTRA=-DCLIENT_ONLY=1 -DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
# Mac build variables
|
||||
if [ "${{ matrix.os }}" = "macOS-latest" ]; then
|
||||
echo "PYTHON_EXEC=python3" >> $GITHUB_ENV
|
||||
echo "INSTALLER_EXT=dmg" >> $GITHUB_ENV
|
||||
echo "CMAKE_EXTRA=-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" >> $GITHUB_ENV
|
||||
if [ "${{ matrix.build_type }}" = "full" ]; then
|
||||
echo "CMAKE_EXTRA=-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CMAKE_EXTRA=-DCLIENT_ONLY=1 -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "APP_TARGET_NAME=Vircadia" >> $GITHUB_ENV
|
||||
fi
|
||||
# Windows build variables
|
||||
if [ "${{ matrix.os }}" = "windows-latest" ]; then
|
||||
echo "PYTHON_EXEC=python" >> $GITHUB_ENV
|
||||
echo "INSTALLER_EXT=exe" >> $GITHUB_ENV
|
||||
echo "CMAKE_EXTRA=-A x64" >> $GITHUB_ENV
|
||||
if [ "${{ matrix.build_type }}" = "full" ]; then
|
||||
echo "CMAKE_EXTRA=-A x64" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CMAKE_EXTRA=-A x64 -DCLIENT_ONLY=1" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
# Android + Quest build variables
|
||||
if [[ "${{ matrix.build_type }}" == "android" ]]; then
|
||||
|
@ -86,9 +102,13 @@ jobs:
|
|||
echo "${{ steps.buildenv1.outputs.symbols_archive }}"
|
||||
echo "GIT_COMMIT_SHORT=${{ steps.buildenv1.outputs.github_sha_short }}" >> $GITHUB_ENV
|
||||
if [[ "${{ matrix.build_type }}" != "android" ]]; then
|
||||
echo "ARTIFACT_PATTERN=Vircadia-PR${{ github.event.number }}-*.$INSTALLER_EXT" >> $GITHUB_ENV
|
||||
# Build type variables
|
||||
echo "INSTALLER=Vircadia-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV
|
||||
if [ "${{ matrix.build_type }}" = "full" ]; then
|
||||
echo "ARTIFACT_PATTERN=Vircadia-PR${{ github.event.number }}-*.$INSTALLER_EXT" >> $GITHUB_ENV
|
||||
echo "INSTALLER=Vircadia-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV
|
||||
else
|
||||
echo "ARTIFACT_PATTERN=Vircadia-Interface-PR${{ github.event.number }}-*.$INSTALLER_EXT" >> $GITHUB_ENV
|
||||
echo "INSTALLER=Vircadia-Interface-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV
|
||||
fi
|
||||
else
|
||||
echo "ARTIFACT_PATTERN=*.$INSTALLER_EXT" >> $GITHUB_ENV
|
||||
fi
|
||||
|
@ -124,7 +144,7 @@ jobs:
|
|||
if: matrix.build_type == 'full' || matrix.build_type == 'client'
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target $APP_NAME $CMAKE_BUILD_EXTRA
|
||||
run: cmake --build . --config $BUILD_TYPE --target $APP_TARGET_NAME $CMAKE_BUILD_EXTRA
|
||||
- name: Build Domain Server
|
||||
if: matrix.build_type == 'full'
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
|
@ -136,7 +156,7 @@ jobs:
|
|||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target assignment-client $CMAKE_BUILD_EXTRA
|
||||
- name: Build Console
|
||||
if: matrix.build_type == 'full'
|
||||
if: matrix.build_type == 'full' || matrix.os == 'windows-latest'
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: cmake --build . --config $BUILD_TYPE --target packaged-server-console $CMAKE_BUILD_EXTRA
|
||||
|
@ -168,6 +188,16 @@ jobs:
|
|||
done
|
||||
}
|
||||
retry cmake --build . --config $BUILD_TYPE --target package $CMAKE_BUILD_EXTRA
|
||||
# As of 05/17/21 GitHub Virtual Environments changed their "Ubuntu 18.04.5 LTS" image to include two versions of CMake for Android
|
||||
# https://github.com/actions/virtual-environments/blob/ubuntu18/20210517.1/images/linux/Ubuntu1804-README.md
|
||||
# Removing 3.18.1 version of CMake as its not compatible with our Android build.
|
||||
# It will fall back to 3.10.2 which is already installed
|
||||
- name: Nuke CMake 3.18.1-g262b901
|
||||
if: matrix.build_type == 'android'
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/vircadia
|
||||
run: |
|
||||
/usr/local/lib/android/sdk/tools/bin/sdkmanager --uninstall 'cmake;3.18.1'
|
||||
- name: Build for Android + Quest
|
||||
if: matrix.build_type == 'android'
|
||||
shell: bash
|
||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "vircadia-web"]
|
||||
path = vircadia-web
|
||||
url = ../vircadia-web.git
|
43
.grenrc.js
Normal file
43
.grenrc.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// .grenrc.js
|
||||
//
|
||||
// Created by Kalila L. on May 25, 2021
|
||||
// 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
|
||||
//
|
||||
// This configuration is for generating a changelog with gren for a GitHub repository.
|
||||
// https://github.com/github-tools/github-release-notes
|
||||
//
|
||||
// gren changelog -G
|
||||
//
|
||||
|
||||
module.exports = {
|
||||
"dataSource": "prs",
|
||||
"prefix": "",
|
||||
"ignoreLabels": [
|
||||
"enhancement",
|
||||
"bugfix",
|
||||
"CR Approved",
|
||||
"QA Approved",
|
||||
"allow-build-upload",
|
||||
"bug",
|
||||
"confirmed",
|
||||
"do not merge",
|
||||
"duplicate",
|
||||
"good first issue",
|
||||
"help wanted",
|
||||
"hifi migration",
|
||||
"high risk",
|
||||
"rebuild",
|
||||
"merge right before snip"
|
||||
],
|
||||
"onlyMilestones": true,
|
||||
"groupBy": {
|
||||
"Enhancements": ["enhancement"],
|
||||
"Bug Fixes": ["bugfix"],
|
||||
"Docs": ["docs"]
|
||||
},
|
||||
"changelogFilename": "CHANGELOG.md"
|
||||
}
|
191
BUILD.md
191
BUILD.md
|
@ -1,116 +1,153 @@
|
|||
# General Build Information
|
||||
|
||||
*Last Updated on August 26, 2020*
|
||||
*Last Updated on March 8, 2021*
|
||||
|
||||
### OS Specific Build Guides
|
||||
## OS Specific Build Guides
|
||||
|
||||
* [Build Windows](BUILD_WIN.md) - complete instructions for Windows.
|
||||
* [Build Linux](BUILD_LINUX.md) - additional instructions for Linux.
|
||||
* [Build OSX](BUILD_OSX.md) - additional instructions for OS X.
|
||||
* [Build Android](BUILD_ANDROID.md) - additional instructions for Android.
|
||||
|
||||
### Dependencies
|
||||
- [git](https://git-scm.com/downloads): >= 1.6
|
||||
- [cmake](https://cmake.org/download/): 3.9
|
||||
## Dependencies
|
||||
- [git](https://git-scm.com/downloads): >= 1.6
|
||||
- [CMake](https://cmake.org/download/): 3.9 (or greater up to 3.18.x)
|
||||
- [Python](https://www.python.org/downloads/): 3.6 or higher
|
||||
- [Node.JS](https://nodejs.org/en/): >= 12.13.1 LTS
|
||||
- Used to build the Screen Sharing executable.
|
||||
|
||||
### CMake External Project Dependencies
|
||||
## CMake External Project Dependencies
|
||||
|
||||
These dependencies need not be installed manually. They are automatically downloaded on the platforms where they are required.
|
||||
- [Bullet Physics Engine](https://github.com/bulletphysics/bullet3/releases): 2.83
|
||||
- [glm](https://glm.g-truc.net/0.9.8/index.html): 0.9.8
|
||||
- [Oculus SDK](https://developer.oculus.com/downloads/): 1.11 (Windows) / 0.5 (Mac)
|
||||
- [OpenVR](https://github.com/ValveSoftware/openvr): 1.11.11 (Windows, Linux)
|
||||
- [Polyvox](http://www.volumesoffun.com/): 0.2.1
|
||||
- [QuaZip](https://sourceforge.net/projects/quazip/files/quazip/): 0.7.3
|
||||
- [SDL2](https://www.libsdl.org/download-2.0.php): 2.0.3
|
||||
- [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/): 4.3
|
||||
- [vcpkg](https://github.com/hifi-archive/vcpkg):
|
||||
- [VHACD](https://github.com/virneo/v-hacd)
|
||||
- [zlib](http://www.zlib.net/): 1.28 (Win32 only)
|
||||
- [nvtt](https://github.com/hifi-archive/nvidia-texture-tools): 2.1.1 (customized)
|
||||
- [Bullet Physics Engine](https://github.com/bulletphysics/bullet3/releases): 2.83
|
||||
- [glm](https://glm.g-truc.net/0.9.8/index.html): 0.9.8
|
||||
- [Oculus SDK](https://developer.oculus.com/downloads/): 1.11 (Windows) / 0.5 (Mac)
|
||||
- [OpenVR](https://github.com/ValveSoftware/openvr): 1.11.11 (Windows, Linux)
|
||||
- [Polyvox](http://www.volumesoffun.com/): 0.2.1
|
||||
- [QuaZip](https://sourceforge.net/projects/quazip/files/quazip/): 0.7.3
|
||||
- [SDL2](https://www.libsdl.org/download-2.0.php): 2.0.3
|
||||
- [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/): 4.3
|
||||
- [vcpkg](https://github.com/hifi-archive/vcpkg):
|
||||
- [VHACD](https://github.com/virneo/v-hacd)
|
||||
- [zlib](http://www.zlib.net/): 1.28 (Win32 only)
|
||||
- [nvtt](https://github.com/hifi-archive/nvidia-texture-tools): 2.1.1 (customized)
|
||||
|
||||
The above dependencies will be downloaded, built, linked and included automatically by CMake where we require them. The CMakeLists files that handle grabbing each of the following external dependencies can be found in the [cmake/externals folder](cmake/externals). The resulting downloads, source files and binaries will be placed in the `build/ext` folder in each of the subfolders for each external project.
|
||||
|
||||
These are not placed in your normal build tree when doing an out of source build so that they do not need to be re-downloaded and re-compiled every time the CMake build folder is cleared. Should you want to force a re-download and re-compile of a specific external, you can simply remove that directory from the appropriate subfolder in `build/ext`. Should you want to force a re-download and re-compile of all externals, just remove the `build/ext` folder.
|
||||
|
||||
#### CMake
|
||||
### CMake
|
||||
|
||||
Vircadia uses CMake to generate build files and project files for your platform.
|
||||
|
||||
#### Qt
|
||||
CMake will download Qt 5.12.3 using vcpkg.
|
||||
### Qt
|
||||
|
||||
To override this (i.e. use an installed Qt configuration - you will need to set a QT_CMAKE_PREFIX_PATH environment variable pointing to your Qt **lib/cmake** folder.
|
||||
This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). The path it needs to be set to will depend on where and how Qt5 was installed. e.g.
|
||||
CMake will download Qt 5.15.2 using vcpkg.
|
||||
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/Qt5.12.3/gcc_64/lib/cmake
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.12.3/clang_64/lib/cmake/
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.12.3/lib/cmake
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake
|
||||
To override this - i.e., use an installed Qt configuration - you need to set a QT_CMAKE_PREFIX_PATH environment variable pointing to your Qt **lib/cmake** folder.
|
||||
This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). The path it needs to be set to will depend on where and how Qt5 was installed.
|
||||
|
||||
#### VCPKG
|
||||
For example, under Linux:
|
||||
```bash
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/Qt5.15.2/gcc_64/lib/cmake
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.15.2/clang_64/lib/cmake/
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.15.2/lib/cmake
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake
|
||||
```
|
||||
|
||||
For example, under Windows:
|
||||
|
||||
set QT_CMAKE_PREFIX_PATH=C:\Qt\5.15.2\msvc2019_64\lib\cmake
|
||||
|
||||
For example, under OSX:
|
||||
|
||||
export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.15.2/lib/cmake
|
||||
|
||||
Note: You only need the following components checked under Qt 5.15.2 (select the "Custom Installation" option):
|
||||
"MSVC 2019 64-bit", "Qt WebEngine", and "Qt Script (Deprecated)".
|
||||
|
||||
Note: Installing the sources is optional but recommended if you have room for them (~3GB). You may also want the Qt debug
|
||||
information files (~7GB).
|
||||
|
||||
Note: Installing Qt Creator is optional but recommended if you will be editing QML files.
|
||||
|
||||
### VCPKG
|
||||
|
||||
Vircadia uses vcpkg to download and build dependencies.
|
||||
You do not need to install vcpkg.
|
||||
|
||||
Building the dependencies can be lengthy and the resulting files will be stored in your OS temp directory.
|
||||
However, those files can potentially get cleaned up by the OS, so in order to avoid this and having to redo the lengthy build step, you can set the following environment variable:
|
||||
However, those files can potentially get cleaned up by the OS, so in order to avoid this and having to redo the lengthy build step, you can set an environment variable.
|
||||
|
||||
export HIFI_VCPKG_BASE=/path/to/directory
|
||||
Linux:
|
||||
|
||||
```bash
|
||||
export HIFI_VCPKG_BASE=/path/to/directory
|
||||
```
|
||||
|
||||
Windows:
|
||||
```bash
|
||||
set HIFI_VCPKG_BASE=/path/to/directory
|
||||
```
|
||||
|
||||
Where `/path/to/directory` is the path to a directory where you wish the build files to get stored.
|
||||
|
||||
#### Generating Build Files
|
||||
### Generating Build Files
|
||||
|
||||
##### Possible Environment Variables
|
||||
#### Possible Environment Variables
|
||||
|
||||
// The URL to post the dump to.
|
||||
CMAKE_BACKTRACE_URL
|
||||
// The identifying tag of the release.
|
||||
CMAKE_BACKTRACE_TOKEN
|
||||
|
||||
// The release version, e.g., 2021.3.2.
|
||||
RELEASE_NUMBER
|
||||
// The release name, e.g., Eos.
|
||||
RELEASE_NAME
|
||||
// The build commit, e.g., use a Git hash for the most recent commit in the branch - fd6973b.
|
||||
BUILD_NUMBER
|
||||
```text
|
||||
// The URL to post the dump to.
|
||||
CMAKE_BACKTRACE_URL
|
||||
// The identifying tag of the release.
|
||||
CMAKE_BACKTRACE_TOKEN
|
||||
|
||||
// The type of release.
|
||||
RELEASE_TYPE=PRODUCTION|PR|DEV
|
||||
|
||||
// The Interface will have a custom default home and startup location.
|
||||
INITIAL_STARTUP_LOCATION=Location/IP/URL
|
||||
|
||||
// Code-signing environment variables must be set during runtime of CMake AND globally when the signing takes place.
|
||||
HF_PFX_FILE=Path to certificate
|
||||
HF_PFX_PASSPHRASE=Passphrase for certificate
|
||||
|
||||
// Determine the build type
|
||||
PRODUCTION_BUILD=0|1
|
||||
PR_BUILD=0|1
|
||||
STABLE_BUILD=0|1
|
||||
|
||||
// Determine if to utilize testing or stable Metaverse URLs
|
||||
USE_STABLE_GLOBAL_SERVICES=1
|
||||
BUILD_GLOBAL_SERVICES=STABLE
|
||||
|
||||
##### Generate Files
|
||||
// The release version, e.g., 2021.3.2.
|
||||
RELEASE_NUMBER
|
||||
// The release name, e.g., Eos.
|
||||
RELEASE_NAME
|
||||
// The build commit, e.g., use a Git hash for the most recent commit in the branch - fd6973b.
|
||||
|
||||
BUILD_NUMBER
|
||||
|
||||
// The type of release.
|
||||
RELEASE_TYPE=PRODUCTION|PR|DEV
|
||||
|
||||
// The Interface will have a custom default home and startup location.
|
||||
PRELOADED_STARTUP_LOCATION=Location/IP/URL
|
||||
// The Interface will have a custom default script whitelist, comma separated, no spaces.
|
||||
// This will also activate the whitelist on Interface's first run.
|
||||
PRELOADED_SCRIPT_WHITELIST=ListOfEntries
|
||||
|
||||
// Code-signing environment variables must be set during runtime of CMake AND globally when the signing takes place.
|
||||
HF_PFX_FILE=Path to certificate
|
||||
HF_PFX_PASSPHRASE=Passphrase for certificate
|
||||
|
||||
// Determine the build type
|
||||
PRODUCTION_BUILD=0|1
|
||||
PR_BUILD=0|1
|
||||
STABLE_BUILD=0|1
|
||||
|
||||
// Determine if to utilize testing or stable Metaverse URLs
|
||||
USE_STABLE_GLOBAL_SERVICES=1
|
||||
BUILD_GLOBAL_SERVICES=STABLE
|
||||
```
|
||||
|
||||
#### Generate Files
|
||||
|
||||
Create a build directory in the root of your checkout and then run the CMake build from there. This will keep the rest of the directory clean.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
```
|
||||
|
||||
If CMake gives you the same error message repeatedly after the build fails, try removing `CMakeCache.txt`.
|
||||
|
||||
##### Generating a release/debug only vcpkg build
|
||||
#### Generating a release/debug only vcpkg build
|
||||
|
||||
In order to generate a release or debug only vcpkg package, you could use the use the `VCPKG_BUILD_TYPE` define in your cmake generate command. Building a release only vcpkg can drastically decrease the total build time.
|
||||
In order to generate a release or debug only vcpkg package, you could use the use the `VCPKG_BUILD_TYPE` define in your CMake generate command. Building a release only vcpkg can drastically decrease the total build time.
|
||||
|
||||
For release only vcpkg:
|
||||
|
||||
|
@ -120,15 +157,17 @@ For debug only vcpkg:
|
|||
|
||||
`cmake .. -DVCPKG_BUILD_TYPE=debug`
|
||||
|
||||
#### Variables
|
||||
### Variables
|
||||
|
||||
Any variables that need to be set for CMake to find dependencies can be set as ENV variables in your shell profile, or passed directly to CMake with a `-D` flag appended to the `cmake ..` command.
|
||||
|
||||
For example, to pass the QT_CMAKE_PREFIX_PATH variable (if not using the vcpkg'ed version) during build file generation:
|
||||
|
||||
cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.12.3/lib/cmake
|
||||
```bash
|
||||
cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.12.3/lib/cmake
|
||||
```
|
||||
|
||||
#### Finding Dependencies
|
||||
### Finding Dependencies
|
||||
|
||||
The following applies for dependencies we do not grab via CMake ExternalProject (OpenSSL is an example), or for dependencies you have opted not to grab as a CMake ExternalProject (via -DUSE_LOCAL_$NAME=0). The list of dependencies we grab by default as external projects can be found in [the CMake External Project Dependencies section](#cmake-external-project-dependencies).
|
||||
|
||||
|
@ -140,9 +179,9 @@ In the examples below the variable $NAME would be replaced by the name of the de
|
|||
* $NAME_ROOT_DIR - set this variable in your ENV
|
||||
* HIFI_LIB_DIR - set this variable in your ENV to your Vircadia lib folder, should contain a folder '$name'
|
||||
|
||||
### Optional Components
|
||||
## Optional Components
|
||||
|
||||
#### Build Options
|
||||
### Build Options
|
||||
|
||||
The following build options can be used when running CMake
|
||||
|
||||
|
@ -153,12 +192,12 @@ The following build options can be used when running CMake
|
|||
* CLIENT_ONLY // Will package only the Interface
|
||||
* SERVER_ONLY // Will package only the Server
|
||||
|
||||
#### Developer Build Options
|
||||
### Developer Build Options
|
||||
|
||||
* USE_GLES
|
||||
* DISABLE_UI
|
||||
|
||||
#### Devices
|
||||
### Devices
|
||||
|
||||
You can support external input/output devices such as Leap Motion, MIDI, and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device.
|
||||
|
||||
|
||||
|
|
|
@ -42,11 +42,13 @@ Follow the directions [here](https://developer.android.com/studio/publish/app-si
|
|||
|
||||
Create a `gradle.properties` file in the `.gradle` folder (`$HOME/.gradle` on Unix, `Users/<yourname>/.gradle` on Windows). Edit the file to contain the following
|
||||
|
||||
HIFI_ANDROID_PRECOMPILED=<your_home_directory>/Android/hifi_externals
|
||||
HIFI_ANDROID_KEYSTORE=<key_store_directory>/<keystore_name>.jks
|
||||
HIFI_ANDROID_KEYSTORE_PASSWORD=<password>
|
||||
HIFI_ANDROID_KEY_ALIAS=<key_alias>
|
||||
HIFI_ANDROID_KEY_PASSWORD=<key_passwords>
|
||||
```properties
|
||||
HIFI_ANDROID_PRECOMPILED=<your_home_directory>/Android/hifi_externals
|
||||
HIFI_ANDROID_KEYSTORE=<key_store_directory>/<keystore_name>.jks
|
||||
HIFI_ANDROID_KEYSTORE_PASSWORD=<password>
|
||||
HIFI_ANDROID_KEY_ALIAS=<key_alias>
|
||||
HIFI_ANDROID_KEY_PASSWORD=<key_passwords>
|
||||
```
|
||||
|
||||
Note, do not use $HOME for the path. It must be a fully qualified path name. Also, be sure to use forward slashes in your path.
|
||||
|
||||
|
@ -54,21 +56,26 @@ Note, do not use $HOME for the path. It must be a fully qualified path name. Als
|
|||
|
||||
Add these lines to `gradle.properties`
|
||||
|
||||
SUPPRESS_QUEST_INTERFACE
|
||||
SUPPRESS_QUEST_FRAME_PLAYER
|
||||
```properties
|
||||
SUPPRESS_QUEST_INTERFACE
|
||||
SUPPRESS_QUEST_FRAME_PLAYER
|
||||
```
|
||||
|
||||
#### If you are building for an Oculus Quest
|
||||
|
||||
Add these lines to `gradle.properties`
|
||||
|
||||
SUPPRESS_INTERFACE
|
||||
SUPPRESS_FRAME_PLAYER
|
||||
|
||||
```properties
|
||||
SUPPRESS_INTERFACE
|
||||
SUPPRESS_FRAME_PLAYER
|
||||
```
|
||||
|
||||
#### The Frame Player for both Android Phone and Oculus Quest is optional, so if you encounter problems with these during your build, you can skip them by adding these lines to `gradle.properties`
|
||||
|
||||
SUPPRESS_FRAME_PLAYER
|
||||
SUPPRESS_QUEST_FRAME_PLAYER
|
||||
```properties
|
||||
SUPPRESS_FRAME_PLAYER
|
||||
SUPPRESS_QUEST_FRAME_PLAYER
|
||||
```
|
||||
|
||||
### Clone the repository
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -168,39 +171,3 @@ If your goal is to set up a development environment, it is desirable to set the
|
|||
directory that vcpkg builds into with the `HIFI_VCPKG_BASE` environment variable.
|
||||
For example, you might set `HIFI_VCPKG_BASE` to `/home/$USER/vcpkg`.
|
||||
By default, vcpkg will build in the system `/tmp` directory.
|
||||
|
||||
##### Ubuntu 18.04 only
|
||||
|
||||
In Ubuntu 18.04 there is a problem related with NVidia driver library version.
|
||||
|
||||
It can be worked around following these steps:
|
||||
|
||||
1. Uninstall incompatible nvtt libraries:
|
||||
`sudo apt-get remove libnvtt2 libnvtt-dev`
|
||||
|
||||
1. Install libssl1.0-dev:
|
||||
`sudo apt-get -y install libssl1.0-dev`
|
||||
|
||||
1. Clone castano nvidia-texture-tools:
|
||||
`git clone https://github.com/castano/nvidia-texture-tools`
|
||||
`cd nvidia-texture-tools/`
|
||||
|
||||
1. Make these changes in repo:
|
||||
* In file **VERSION** set `2.2.1`
|
||||
* In file **configure**:
|
||||
* set `build="release"`
|
||||
* set `-DNVTT_SHARED=1`
|
||||
|
||||
1. Configure, build and install:
|
||||
`./configure`
|
||||
`make`
|
||||
`sudo make install`
|
||||
|
||||
1. Link compiled files:
|
||||
`sudo ln -s /usr/local/lib/libnvcore.so /usr/lib/libnvcore.so`
|
||||
`sudo ln -s /usr/local/lib/libnvimage.so /usr/lib/libnvimage.so`
|
||||
`sudo ln -s /usr/local/lib/libnvmath.so /usr/lib/libnvmath.so`
|
||||
`sudo ln -s /usr/local/lib/libnvtt.so /usr/lib/libnvtt.so`
|
||||
|
||||
1. After running these steps you can run interface:
|
||||
`interface/interface`
|
||||
|
|
44
BUILD_OSX.md
44
BUILD_OSX.md
|
@ -1,55 +1,63 @@
|
|||
# Build OSX
|
||||
|
||||
*Last Updated on August 26, 2020*
|
||||
*Last Updated on January 16, 2021*
|
||||
|
||||
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only macOS specific instructions are found in this document.
|
||||
|
||||
### Homebrew
|
||||
## Homebrew
|
||||
|
||||
[Homebrew](https://brew.sh/) is an excellent package manager for macOS. It makes install of some Vircadia dependencies very simple.
|
||||
|
||||
brew install cmake openssl npm
|
||||
```bash
|
||||
brew install cmake openssl npm
|
||||
```
|
||||
|
||||
### Python 3
|
||||
Note: cmake versions > 3.18.x have known problems building Vircadia, so alternatively you can download cmake 3.18.4 (or earlier versions) from [Github](https://github.com/Kitware/CMake/releases).
|
||||
|
||||
Download an install Python 3.6.6 or higher from [here](https://www.python.org/downloads/).
|
||||
## Python 3
|
||||
|
||||
Download an install Python 3.6.6 or higher from [here](https://www.python.org/downloads/).
|
||||
Execute the `Update Shell Profile.command` script that is provided with the installer.
|
||||
|
||||
### OSX SDK
|
||||
## OSX SDK
|
||||
|
||||
You will need version `10.12` of the OSX SDK for building, otherwise you may have crashing or other unintended issues due to the deprecation of OpenGL on OSX. You can get that SDK from [here](https://github.com/phracker/MacOSX-SDKs). You must copy it in to your Xcode SDK directory, e.g.
|
||||
|
||||
cp -rp ~/Downloads/MacOSX10.12.sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
|
||||
```bash
|
||||
cp -rp ~/Downloads/MacOSX10.12.sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
|
||||
```
|
||||
|
||||
### OpenSSL
|
||||
## OpenSSL
|
||||
|
||||
Assuming you've installed OpenSSL using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR so CMake can find your installations.
|
||||
Assuming you've installed OpenSSL using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR so CMake can find your installations.
|
||||
For OpenSSL installed via homebrew, set OPENSSL_ROOT_DIR via
|
||||
`export OPENSSL_ROOT_DIR=/usr/local/opt/openssl`
|
||||
or by appending `-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl` to `cmake`
|
||||
|
||||
### Xcode
|
||||
## Xcode
|
||||
|
||||
You can ask CMake to generate Xcode project files instead of Unix Makefiles using the `-G Xcode` parameter after CMake. You will need to select the Xcode installation in the terminal first if you have not done so already.
|
||||
|
||||
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
|
||||
|
||||
cmake ../ -DCMAKE_OSX_SYSROOT="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOSX_SDK=10.12 ..
|
||||
|
||||
If `cmake` complains about Python 3 being missing, you may need to update your CMake binary with command `brew upgrade cmake`, or by downloading and running the latest CMake installer, depending on how you originally instaled CMake
|
||||
```bash
|
||||
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
|
||||
|
||||
cmake ../ -DCMAKE_OSX_SYSROOT="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOSX_SDK=10.12 ..
|
||||
```
|
||||
|
||||
If `cmake` complains about Python 3 being missing, you may need to update your CMake binary with command `brew upgrade cmake`, or by downloading and running the latest CMake installer, depending on how you originally installed CMake.
|
||||
|
||||
After running CMake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run.
|
||||
|
||||
If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories.
|
||||
|
||||
### make
|
||||
## make
|
||||
|
||||
If you build with make rather than Xcode, you can append `-j4` for assigning more threads. The number indicates the number of threads, e.g. 4.
|
||||
|
||||
To package the installation, you can simply run `make package` afterwards.
|
||||
|
||||
### FAQ
|
||||
## FAQ
|
||||
|
||||
1. **Problem:** Running the scheme `interface.app` from Xcode causes a crash for Interface related to `libgl`
|
||||
1. **Cause:** The target `gl` generates a binary called `libgl`. A macOS `libGL.framework` item gets loaded instead by Xcode.
|
||||
1. **Cause:** The target `gl` generates a binary called `libgl`. A macOS `libGL.framework` item gets loaded instead by Xcode.
|
||||
1. **Solution:** In the Xcode target settings for `libgl`, set the version to 1.0.0
|
||||
|
|
101
BUILD_WIN.md
101
BUILD_WIN.md
|
@ -1,40 +1,35 @@
|
|||
# Build Windows
|
||||
|
||||
*Last Updated on May 17, 2020*
|
||||
*Last Updated on 15 Apr 2021*
|
||||
|
||||
This is a stand-alone guide for creating your first Vircadia build for Windows 64-bit.
|
||||
This is a stand-alone guide for creating your first Vircadia build for Windows 64-bit.
|
||||
|
||||
Note: We are now using Visual Studio 2017 or 2019 and Qt 5.12.3.
|
||||
If you are upgrading from previous versions, do a clean uninstall of those versions before going through this guide.
|
||||
Note: We are now using Visual Studio 2019 and Qt 5.15.2.
|
||||
If you are upgrading from previous versions, do a clean uninstall of those versions before going through this guide.
|
||||
|
||||
**Note: The prerequisites will require about 10 GB of space on your drive. You will also need a system with at least 8GB of main memory.**
|
||||
|
||||
### Step 1. Visual Studio & Python 3.x
|
||||
## Step 1. Visual Studio & Python 3.x
|
||||
|
||||
If you don’t have Community or Professional edition of Visual Studio, download [Visual Studio Community 2019](https://visualstudio.microsoft.com/vs/). If you have Visual Studio 2017, you are not required to download Visual Studio 2019.
|
||||
If you don't have Community or Professional edition of Visual Studio 2019, download [Visual Studio Community 2019](https://visualstudio.microsoft.com/vs/). If you have Visual Studio 2017, you need to download Visual Studio 2019.
|
||||
|
||||
When selecting components, check "Desktop development with C++".
|
||||
When selecting components, check "Desktop development with C++".
|
||||
|
||||
If you do not already have a Python 3.x development environment installed and want to install it with Visual Studio, check "Python Development". If you already have Visual Studio installed and need to add Python, open the "Add or remove programs" control panel and find the "Microsoft Visual Studio Installer". Select it and click "Modify". In the installer, select "Modify" again, then check "Python Development" and allow the installer to apply the changes.
|
||||
|
||||
On the right on the Summary toolbar, select the following components based on your Visual Studio version.
|
||||
### Visual Studio 2019
|
||||
|
||||
#### If you're installing Visual Studio 2017
|
||||
|
||||
* Windows 8.1 SDK and UCRT SDK
|
||||
* VC++ 2015.3 v14.00 (v140) toolset for desktop
|
||||
|
||||
#### If you're installing Visual Studio 2019
|
||||
On the right on the Summary toolbar, select the following components.
|
||||
|
||||
* MSVC v142 - VS 2019 C++ X64/x86 build tools
|
||||
* MSVC v141 - VS 2017 C++ x64/x86 build tools
|
||||
* MSVC v140 - VS 2015 C++ build tools (v14.00)
|
||||
|
||||
### Step 1a. Alternate Python
|
||||
## Step 1a. Alternate Python
|
||||
|
||||
If you do not wish to use the Python installation bundled with Visual Studio, you can download the installer from [here](https://www.python.org/downloads/). Ensure that you get version 3.6.6 or higher.
|
||||
|
||||
### Step 2. Python Dependencies
|
||||
## Step 2. Python Dependencies
|
||||
|
||||
In an administrator command-line that can access Python's pip you will need to run the following command:
|
||||
|
||||
|
@ -42,52 +37,68 @@ In an administrator command-line that can access Python's pip you will need to r
|
|||
|
||||
If you do not use an administrator command-line, you will get errors.
|
||||
|
||||
### Step 3. Installing CMake
|
||||
## Step 3. Installing CMake
|
||||
|
||||
Download and install the latest version of CMake 3.15.
|
||||
Download and install the latest version of CMake 3.15.
|
||||
* Note that earlier versions of CMake will work, but there is a specific bug related to the interaction of Visual Studio 2019 and CMake versions prior to 3.15 that will cause Visual Studio to rebuild far more than it needs to on every build
|
||||
|
||||
Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.15 Version page](https://cmake.org/files/v3.15/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted.
|
||||
|
||||
### Step 4. Node.JS and NPM
|
||||
## Step 4. Node.JS and NPM
|
||||
|
||||
Install version 10.15.0 LTS (or greater) of [Node.JS and NPM](<https://nodejs.org/en/download/>).
|
||||
|
||||
### Step 5. Create VCPKG environment variable
|
||||
## Step 5. (Optional) Install Qt
|
||||
|
||||
If you would like to compile Qt instead of using the precompiled package provided during CMake, you can do so now. Install version 5.12.3 of [Qt](<https://www.qt.io/download-open-source>), as well as the following packages:
|
||||
* Qt 5.15.2
|
||||
* MSVC 2019 64-bit
|
||||
* Qt WebEngine
|
||||
* Qt Script (Deprecated)
|
||||
|
||||
For convenience, you may also want the "Qt Debug Information" and "Sources" packages.
|
||||
|
||||
You'll need to create the environment variable that CMake uses to find your system's Qt install.
|
||||
|
||||
To create this variable:
|
||||
* Navigate to 'Edit the System Environment Variables' through the Start menu.
|
||||
* Click on 'Environment Variables'
|
||||
* Select 'New'
|
||||
* Set "Variable name" to `QT_CMAKE_PREFIX_PATH`
|
||||
* Set "Variable value" to `%QT_INSTALL_DIR%\5.15.2\msvc2019_64\lib\cmake`, where `%QT_INSTALL_DIR%` is the directory you specified for Qt's installation. The default is `C:\Qt`.
|
||||
|
||||
## Step 6. Create VCPKG environment variable
|
||||
In the next step, you will use CMake to build Vircadia. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them.
|
||||
|
||||
To create this variable:
|
||||
* Naviagte to 'Edit the System Environment Variables' Through the start menu.
|
||||
* Navigate to 'Edit the System Environment Variables' Through the Start menu.
|
||||
* Click on 'Environment Variables'
|
||||
* Select 'New'
|
||||
* Select 'New'
|
||||
* Set "Variable name" to `HIFI_VCPKG_BASE`
|
||||
* Set "Variable value" to any directory that you have control over.
|
||||
|
||||
Additionally, if you have Visual Studio 2019 installed and _only_ Visual Studio 2019 (i.e. you do not have Visual Studio 2017 installed) you must add an additional environment variable `HIFI_VCPKG_BOOTSTRAP` that will fix a bug in our `vcpkg` pre-build step.
|
||||
Additionally, if you have Visual Studio 2019 installed and _only_ Visual Studio 2019 (i.e., you do not have Visual Studio 2017 installed) you must add an additional environment variable `HIFI_VCPKG_BOOTSTRAP` that will fix a bug in our `vcpkg` pre-build step.
|
||||
|
||||
To create this variable:
|
||||
* Naviagte to 'Edit the System Environment Variables' Through the start menu.
|
||||
* Navigate to 'Edit the System Environment Variables' through the Start menu.
|
||||
* Click on 'Environment Variables'
|
||||
* Select 'New'
|
||||
* Select 'New'
|
||||
* Set "Variable name" to `HIFI_VCPKG_BOOTSTRAP`
|
||||
* Set "Variable value" to `1`
|
||||
|
||||
### Step 6. Running CMake to Generate Build Files
|
||||
## Step 7. Running CMake to Generate Build Files
|
||||
|
||||
Run Command Prompt from Start and run the following commands:
|
||||
`cd "%VIRCADIA_DIR%"`
|
||||
`mkdir build`
|
||||
`cd build`
|
||||
Run Command Prompt from Start and run the following commands:
|
||||
`cd "%VIRCADIA_DIR%"`
|
||||
`mkdir build`
|
||||
`cd build`
|
||||
|
||||
#### If you're using Visual Studio 2017,
|
||||
Run `cmake .. -G "Visual Studio 15 Win64"`.
|
||||
|
||||
#### If you're using Visual Studio 2019,
|
||||
### Visual Studio 2019
|
||||
Run `cmake .. -G "Visual Studio 16 2019" -A x64`.
|
||||
|
||||
Where `%VIRCADIA_DIR%` is the directory for the Vircadia repository.
|
||||
|
||||
### Step 7. Making a Build
|
||||
## Step 8. Making a Build
|
||||
|
||||
Open `%VIRCADIA_DIR%\build\vircadia.sln` using Visual Studio.
|
||||
|
||||
|
@ -95,7 +106,7 @@ Change the Solution Configuration (menu ribbon under the menu bar, next to the g
|
|||
|
||||
Run from the menu bar `Build > Build Solution`.
|
||||
|
||||
### Step 8. Testing Interface
|
||||
## Step 9. Testing Interface
|
||||
|
||||
Create another environment variable (see Step #3)
|
||||
* Set "Variable name": `_NO_DEBUG_HEAP`
|
||||
|
@ -103,24 +114,24 @@ Create another environment variable (see Step #3)
|
|||
|
||||
Restart Visual Studio again.
|
||||
|
||||
In Visual Studio, right+click "interface" under the Apps folder in Solution Explorer and select "Set as Startup Project". Run from the menu bar `Debug > Start Debugging`.
|
||||
In Visual Studio, right-click "interface" under the Apps folder in Solution Explorer and select "Set as Startup Project". Run from the menu bar `Debug > Start Debugging`.
|
||||
|
||||
Now, you should have a full build of Vircadia and be able to run the Interface using Visual Studio.
|
||||
|
||||
Note: You can also run Interface by launching it from command line or File Explorer from `%VIRCADIA_DIR%\build\interface\Release\interface.exe`
|
||||
|
||||
## Troubleshooting
|
||||
# Troubleshooting
|
||||
|
||||
For any problems after Step #7, first try this:
|
||||
* Delete your locally cloned copy of the Vircadia repository
|
||||
* Restart your computer
|
||||
* Redownload the [repository](https://github.com/vircadia/vircadia)
|
||||
* Restart directions from Step #7
|
||||
For any problems after Step #7, first try this:
|
||||
* Delete your locally cloned copy of the Vircadia repository
|
||||
* Restart your computer
|
||||
* Redownload the [repository](https://github.com/vircadia/vircadia)
|
||||
* Restart directions from Step #7
|
||||
|
||||
#### CMake gives you the same error message repeatedly after the build fails
|
||||
## CMake gives you the same error message repeatedly after the build fails
|
||||
|
||||
Remove `CMakeCache.txt` found in the `%VIRCADIA_DIR%\build` directory.
|
||||
|
||||
#### CMake can't find OpenSSL
|
||||
## CMake can't find OpenSSL
|
||||
|
||||
Remove `CMakeCache.txt` found in the `%VIRCADIA_DIR%\build` directory. Verify that your HIFI_VCPKG_BASE environment variable is set and pointing to the correct location. Verify that the file `${HIFI_VCPKG_BASE}/installed/x64-windows/include/openssl/ssl.h` exists.
|
||||
|
|
|
@ -41,8 +41,15 @@ endif()
|
|||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" "${EXTERNAL_BUILD_ASSETS}")
|
||||
MESSAGE(STATUS "EXTERNAL_BUILD_ASSETS: ${EXTERNAL_BUILD_ASSETS}")
|
||||
|
||||
# read USE_GLES enviroment variable and sets it as GLES option
|
||||
# TODO still gets overwritten by "use GLES on linux aarch64"
|
||||
set(GLES_OPTION "$ENV{USE_GLES}")
|
||||
|
||||
# use GLES on linux aarch64
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
set(GLES_OPTION ON)
|
||||
endif()
|
||||
|
||||
# Will affect VCPKG dependencies
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/_env/USE_GLES.txt" "${GLES_OPTION}")
|
||||
MESSAGE(STATUS "GLES_OPTION: ${GLES_OPTION}")
|
||||
|
@ -70,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 "")
|
||||
|
@ -79,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)
|
||||
|
@ -87,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()
|
||||
|
@ -94,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)
|
||||
|
@ -125,6 +140,15 @@ else()
|
|||
set(MOBILE 0)
|
||||
endif()
|
||||
|
||||
set(SCREENSHARE 0)
|
||||
if (WIN32)
|
||||
set(SCREENSHARE 1)
|
||||
endif()
|
||||
if (APPLE AND NOT CLIENT_ONLY)
|
||||
# Don't include Screenshare in OSX client-only builds.
|
||||
set(SCREENSHARE 1)
|
||||
endif()
|
||||
|
||||
# Use default time server if none defined in environment
|
||||
set_from_env(TIMESERVER_URL TIMESERVER_URL "http://timestamp.comodoca.com?td=sha256")
|
||||
|
||||
|
@ -187,7 +211,7 @@ else ()
|
|||
set(PLATFORM_QT_COMPONENTS WebEngine Xml)
|
||||
endif ()
|
||||
|
||||
if (USE_GLES AND (NOT ANDROID))
|
||||
if (USE_GLES AND (NOT ANDROID AND NOT UNIX))
|
||||
set(DISABLE_QML_OPTION ON)
|
||||
endif()
|
||||
|
||||
|
@ -258,17 +282,26 @@ add_custom_target(cmake SOURCES ${CMAKE_SRC})
|
|||
GroupSources("cmake")
|
||||
unset(CMAKE_SRC)
|
||||
|
||||
file(GLOB_RECURSE JS_SRC scripts/*.js unpublishedScripts/*.js)
|
||||
file(GLOB_RECURSE JS_SRC scripts/*.* unpublishedScripts/*.*)
|
||||
add_custom_target(js SOURCES ${JS_SRC})
|
||||
GroupSources("scripts")
|
||||
GroupSources("unpublishedScripts")
|
||||
unset(JS_SRC)
|
||||
|
||||
file(GLOB_RECURSE WEB_APP_SRC vircadia-web/*.*)
|
||||
list(FILTER WEB_APP_SRC EXCLUDE REGEX "vircadia-web/(dist|node_modules|public)/*" )
|
||||
add_custom_target(vircadia-web SOURCES ${WEB_APP_SRC})
|
||||
GroupSources("vircadia-web")
|
||||
unset(WEB_APP_SRC)
|
||||
|
||||
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 )
|
||||
|
||||
|
@ -316,8 +349,11 @@ endif()
|
|||
|
||||
if (BUILD_CLIENT)
|
||||
add_subdirectory(interface)
|
||||
add_subdirectory(screenshare)
|
||||
set_target_properties(interface PROPERTIES FOLDER "Apps")
|
||||
if (APPLE)
|
||||
set_target_properties(Vircadia PROPERTIES FOLDER "Apps")
|
||||
else()
|
||||
set_target_properties(interface PROPERTIES FOLDER "Apps")
|
||||
endif()
|
||||
|
||||
option(USE_SIXENSE "Build Interface with sixense library/plugin" OFF)
|
||||
endif()
|
||||
|
@ -327,6 +363,10 @@ if (BUILD_CLIENT OR BUILD_SERVER)
|
|||
add_subdirectory(server-console)
|
||||
endif()
|
||||
|
||||
if (SCREENSHARE)
|
||||
add_subdirectory(screenshare)
|
||||
endif()
|
||||
|
||||
# BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway
|
||||
add_subdirectory(tools)
|
||||
|
||||
|
|
213
INSTALLER.md
213
INSTALLER.md
|
@ -1,6 +1,6 @@
|
|||
# Creating an Installer
|
||||
|
||||
*Last Updated on August 24, 2020*
|
||||
*Last Updated on June 16, 2021*
|
||||
|
||||
Follow the [build guide](BUILD.md) to figure out how to build Vircadia for your platform.
|
||||
|
||||
|
@ -9,13 +9,13 @@ During generation, CMake should produce an `install` target and a `package` targ
|
|||
The `install` target will copy the Vircadia targets and their dependencies to your `CMAKE_INSTALL_PREFIX`.
|
||||
This variable is set by the `project(hifi)` command in `CMakeLists.txt` to `C:/Program Files/hifi` and stored in `build/CMakeCache.txt`
|
||||
|
||||
### Packaging
|
||||
## Packaging
|
||||
|
||||
To produce an installer, run the `package` target. However you will want to follow the steps specific to your platform below.
|
||||
|
||||
#### Windows
|
||||
### Windows
|
||||
|
||||
##### Prerequisites
|
||||
#### Prerequisites
|
||||
|
||||
To produce an executable installer on Windows, the following are required:
|
||||
|
||||
|
@ -63,11 +63,11 @@ To produce an executable installer on Windows, the following are required:
|
|||
1. [Node.JS and NPM](<https://nodejs.org/en/download/>)
|
||||
1. Install version 10.15.0 LTS (or greater)
|
||||
|
||||
##### Code Signing (optional)
|
||||
#### Code Signing (optional)
|
||||
|
||||
For code signing to work, you will need to set the `HF_PFX_FILE` and `HF_PFX_PASSPHRASE` environment variables to be present during CMake runtime and globally as we proceed to package the installer.
|
||||
|
||||
##### Creating the Installer
|
||||
#### Creating the Installer
|
||||
|
||||
1. Perform a clean cmake from a new terminal.
|
||||
1. Open the `vircadia.sln` solution with elevated (administrator) permissions on Visual Studio and select the **Release** configuration.
|
||||
|
@ -79,20 +79,195 @@ For code signing to work, you will need to set the `HF_PFX_FILE` and `HF_PFX_PAS
|
|||
1. Build CMakeTargets->PACKAGE
|
||||
The installer is now available in `build\_CPack_Packages\win64\NSIS`
|
||||
|
||||
#### OS X
|
||||
1. [npm](<https://www.npmjs.com/get-npm>)
|
||||
Install version 12.16.3 LTS
|
||||
|
||||
1. Perform a clean CMake.
|
||||
1. Perform a Release build of ALL_BUILD
|
||||
1. Perform a Release build of `packaged-server-console`
|
||||
This will add a folder to `build\server-console\` -
|
||||
Sandbox-darwin-x64
|
||||
1. Perform a Release build of `package`
|
||||
Installer is now available in `build/_CPack_Packages/Darwin/DragNDrop
|
||||
|
||||
### FAQ
|
||||
#### Create an MSIX Package
|
||||
|
||||
1. Get the 'MSIX Packaging Tool' from the Windows Store.
|
||||
2. Run the process to create a new MSIX package from an existing .exe or .msi installer. This process will allow you to install Vircadia with the usual installer, however it will monitor changes to the computer to replicate the functionality in the MSIX Package. Therefore, you will want to avoid doing anything else on your computer during this process.
|
||||
3. Be sure to select no shortcuts and install only the Vircadia Interface.
|
||||
4. When asked for "Entry" points, select only the Interface entry and not the uninstaller. This is because the MSIX package is uninstalled by Windows itself. If for some reason the uninstaller shows up anyway, you can edit the manifest to manually remove it from view even if the uninstaller is present in the package. This is necessary to uplaod to the Windows Store.
|
||||
5. Once completed, you can sign the package with this application or with other tools such as 'MSIX Hero'. It must be signed with a local certificate to test, and with a proper certificate to distribute.
|
||||
6. If uploading to the Windows Store, you will have to ensure all your manifest info including publisher information matches what is registered with your Microsoft Developer account for Windows. You will see these errors and the expected values when validating it.
|
||||
|
||||
#### FAQ
|
||||
|
||||
1. **Problem:** Failure to open a file. ```File: failed opening file "\FOLDERSHARE\XYZSRelease\...\Credits.rtf" Error in script "C:\TFS\XYZProject\Releases\NullsoftInstaller\XYZWin7Installer.nsi" on line 77 -- aborting creation process```
|
||||
1. **Cause:** The complete path (current directory + relative path) has to be < 260 characters to any of the relevant files.
|
||||
1. **Solution:** Move your build and packaging folder as high up in the drive as possible to prevent an overage.
|
||||
|
||||
### MacOS
|
||||
|
||||
1. Ensure you have all the prerequisites fulfilled from the [MacOS Build Guide](BUILD_OSX.md).
|
||||
2. Perform a clean CMake in your build folder. e.g.
|
||||
```bash
|
||||
BUILD_GLOBAL_SERVICES=STABLE USE_STABLE_GLOBAL_SERVICES=1 RELEASE_BUILD=PRODUCTION BUILD_NUMBER="Insert Build Identifier here e.g. short hash of your last Git commit" RELEASE_NAME="Insert Release Name Here" STABLE_BUILD=1 PRODUCTION_BUILD=1 RELEASE_NUMBER="Insert Release Version Here e.g. 1.1.0" RELEASE_TYPE=PRODUCTION cmake -DCMAKE_OSX_SYSROOT="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk" -DCLIENT_ONLY=1 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOSX_SDK=10.12 ..
|
||||
```
|
||||
3. Pick a method to build and package your release.
|
||||
|
||||
#### Option A: Use Xcode GUI
|
||||
|
||||
1. Perform a Release build of ALL_BUILD
|
||||
2. Perform a Release build of `packaged-server-console`
|
||||
This will add a folder to `build\server-console\` -
|
||||
Sandbox-darwin-x64
|
||||
3. Perform a Release build of `package`
|
||||
Installer is now available in `build/_CPack_Packages/Darwin/DragNDrop`
|
||||
|
||||
#### Option B: Use Terminal
|
||||
|
||||
1. Navigate to your build folder with your terminal.
|
||||
2. `make -j4`, you can change the number to match the number of threads you would like to use.
|
||||
3. `make package` to create the package.
|
||||
|
||||
### Linux
|
||||
|
||||
#### Server
|
||||
|
||||
##### Ubuntu 18.04 | .deb
|
||||
|
||||
1. Ensure you are using an Ubuntu 18.04 system. There is no required minimum to the amount of CPU cores needed, however it's recommended that you use as many as you have available in order to have an efficient experience.
|
||||
```text
|
||||
Recommended CPU Cores: 16
|
||||
Minimum Disk Space: 40GB
|
||||
```
|
||||
3. Get and bootstrap Vircadia Builder.
|
||||
```bash
|
||||
git clone https://github.com/vircadia/vircadia-builder.git
|
||||
cd vircadia-builder
|
||||
```
|
||||
3. Run Vircadia Builder.
|
||||
```bash
|
||||
./vircadia-builder --build server
|
||||
```
|
||||
4. If Vircadia Builder needed to install dependencies and asks you to run it again then do so. Otherwise, skip to the next step.
|
||||
```bash
|
||||
./vircadia-builder --build server
|
||||
```
|
||||
5. Vircadia Builder will ask you to configure it to build the server. The values will be prefilled with defaults, the following steps will explain what they are and what you might want to put. *Advanced users: See [here](BUILD.md#possible-environment-variables) for possible environment variables and settings.*
|
||||
6. This value is the Git repository of Vircadia. You can set this URL to your fork of the Vircadia repository if you need to.
|
||||
```text
|
||||
Git repository: https://github.com/vircadia/vircadia/
|
||||
# OR, for example
|
||||
Git repository: https://github.com/digisomni/vircadia/
|
||||
```
|
||||
7. This value is the tag on the repository. If you would like to use a specific version of Vircadia, typically tags will be named like this: "v2021.1.0-rc"
|
||||
```text
|
||||
Git tag: master
|
||||
# OR, for example
|
||||
Git tag: v2021.1.0-rc
|
||||
```
|
||||
8. This value is the release type. For example, the options are `production`, `pr`, or `dev`. If you are making a build for yourself and others to use then use `production`.
|
||||
```text
|
||||
Release type: DEV
|
||||
# OR, for example we recommend you use
|
||||
Release type: PRODUCTION
|
||||
```
|
||||
9. This value is the release version. Release numbers should be in a format of `YEAR-MAJORVERSION-MINORVERSION` which might look like this: `2021.1.0`.
|
||||
```text
|
||||
Release number: 2021.1.0
|
||||
```
|
||||
10. This value is the build number. We typically use the hash of the most recent commit on that Git tag which might look like this: `fd6973b`.
|
||||
```text
|
||||
Build number: fd6973b
|
||||
```
|
||||
11. This value is the directory that Vircadia will get installed to. You should leave this as the default value unless you are an advanced user.
|
||||
```text
|
||||
Installation dir: /home/ubuntu/Vircadia
|
||||
```
|
||||
12. This value is the number of CPU cores that the Vircadia Builder will use to compile the Vircadia server. By default it will use all cores available on your build server. You should leave this as the default value it gives you for your build server.
|
||||
```text
|
||||
CPU cores to use for Vircadia: 16
|
||||
```
|
||||
13. This value is the number of CPU cores that the Vircadia Builder will use to compile Qt5 (a required component for Vircadia). By default it will use all cores available on your build server. You should leave this as the default value it gives you for your build server.
|
||||
```text
|
||||
CPU cores to use for Qt5: 16
|
||||
```
|
||||
14. It will ask you if you would like to proceed with the specified values. If you're happy with the configuration, type `yes`, otherwise enter `no` and press enter to start over. You can press `Ctrl` + `C` simultaneously on your keyboard to exit.
|
||||
15. Vircadia Builder will now run, it may take a while. See this [table](https://github.com/vircadia/vircadia-builder#how-long-does-it-take) for estimated times.
|
||||
16. Navigate to the `pkg-scripts` directory.
|
||||
```bash
|
||||
cd ../Vircadia/source/pkg-scripts/
|
||||
```
|
||||
17. Generate the .rpm package. Set `RPMVERSION` to the same version you entered for the `Release number` on Vircadia Builder. *Advanced users: the version cannot begin with a letter and cannot include underscores or dashes in it.*
|
||||
```bash
|
||||
DEBVERSION="2021.1.0" DEBEMAIL="your-email@somewhere.com" DEBFULLNAME="Your Full Name" ./make-deb-server
|
||||
```
|
||||
18. If successful, the generated .deb package will be in the `pkg-scripts` folder.
|
||||
|
||||
##### Amazon Linux 2 | .rpm
|
||||
|
||||
1. Ensure you are using an Amazon Linux 2 system. You will need many CPU cores to complete this process within a reasonable time. As an alternative to AWS EC2, you may use a [virtual machine](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/amazon-linux-2-virtual-machine.html). Here are the recommended specs:
|
||||
```text
|
||||
AWS EC2 Instance Type: C5a.4xlarge
|
||||
Recommended CPU Cores: 16
|
||||
Minimum Disk Space: 40GB
|
||||
```
|
||||
2. Update the system and install dependencies.
|
||||
```bash
|
||||
sudo yum update -y
|
||||
sudo yum install git -y
|
||||
sudo yum install rpm-build
|
||||
```
|
||||
3. Get and bootstrap Vircadia Builder.
|
||||
```bash
|
||||
git clone https://github.com/vircadia/vircadia-builder.git
|
||||
cd vircadia-builder
|
||||
sudo ./install_amazon_linux_deps.sh
|
||||
```
|
||||
4. Run Vircadia Builder.
|
||||
```bash
|
||||
./vircadia-builder --build server
|
||||
```
|
||||
5. If Vircadia Builder needed to install dependencies and asks you to run it again then do so. Otherwise, skip to the next step.
|
||||
```bash
|
||||
./vircadia-builder --build server
|
||||
```
|
||||
6. Vircadia Builder will ask you to configure it to build the server. The values will be prefilled with defaults, the following steps will explain what they are and what you might want to put. *Advanced users: See [here](BUILD.md#possible-environment-variables) for possible environment variables and settings.*
|
||||
7. This value is the Git repository of Vircadia. You can set this URL to your fork of the Vircadia repository if you need to.
|
||||
```text
|
||||
Git repository: https://github.com/vircadia/vircadia/
|
||||
# OR, for example
|
||||
Git repository: https://github.com/digisomni/vircadia/
|
||||
```
|
||||
8. This value is the tag on the repository. If you would like to use a specific version of Vircadia, typically tags will be named like this: "v2021.1.0-rc".
|
||||
```text
|
||||
Git tag: master
|
||||
# OR, for example
|
||||
Git tag: v2021.1.0-rc
|
||||
```
|
||||
9. This value is the release type. For example, the options are `production`, `pr`, or `dev`. If you are making a build for yourself and others to use then use `production`.
|
||||
```text
|
||||
Release type: DEV
|
||||
# OR, for example we recommend you use
|
||||
Release type: PRODUCTION
|
||||
```
|
||||
10. This value is the release version. Release numbers typically should be in a format of `YEAR-MAJORVERSION-MINORVERSION` which might look like this: `2021.1.0`.
|
||||
```text
|
||||
Release number: 2021.1.0
|
||||
```
|
||||
11. This value is the build number. We typically use the hash of the most recent commit on that Git tag which might look like this: `fd6973b`.
|
||||
```text
|
||||
Build number: fd6973b
|
||||
```
|
||||
12. This value is the directory that Vircadia will get installed to. You should leave this as the default value unless you are an advanced user.
|
||||
```text
|
||||
Installation dir: /root/Vircadia
|
||||
```
|
||||
13. This value is the number of CPU cores that the Vircadia Builder will use to compile the Vircadia server. By default it will use all cores available on your build server given you have enough memory. You should leave this as the default value it gives you for your build server.
|
||||
```text
|
||||
CPU cores to use for Vircadia: 16
|
||||
```
|
||||
14. This value is the number of CPU cores that the Vircadia Builder will use to compile Qt5 (a required component for Vircadia). By default it will use all cores available on your build server given you have enough memory. You should leave this as the default value it gives you for your build server.
|
||||
```text
|
||||
CPU cores to use for Qt5: 16
|
||||
```
|
||||
15. It will ask you if you would like to proceed with the specified values. If you're happy with the configuration, type `yes`, otherwise enter `no` and press enter to start over. You can press `Ctrl` + `C` simultaneously on your keyboard to exit.
|
||||
16. Vircadia Builder will now run, it may take a while. See this [table](https://github.com/vircadia/vircadia-builder#how-long-does-it-take) for estimated times.
|
||||
17. Navigate to the `pkg-scripts` directory.
|
||||
```bash
|
||||
cd ../Vircadia/source/pkg-scripts/
|
||||
```
|
||||
18. Generate the .rpm package. Set `RPMVERSION` to the same version you entered for the `Release number` on Vircadia Builder. *Advanced users: the version cannot begin with a letter and cannot include underscores or dashes in it.*
|
||||
```bash
|
||||
RPMVERSION="2021.1.0" ./make-rpm-server
|
||||
```
|
||||
19. If successful, the generated .rpm package will be in the `pkg-scripts` folder of the Vircadia source files.
|
||||
|
|
53
README.md
53
README.md
|
@ -1,37 +1,52 @@
|
|||
# Vircadia (Codename Athena)
|
||||
<p align="center"><a href="https://vircadia.com/"><img src="interface/resources/images/vircadia-banner.svg" alt="Vircadia - Codename Athena" width="350"/></a></p>
|
||||
<h3 align="center"><a href="https://vircadia.com/">Website</a> | <a href="https://discordapp.com/invite/Pvx2vke">Discord</a> | <a href="https://vircadia.com/download-vircadia/">Download</a></h3>
|
||||
<p align="center"><a href="CONTRIBUTING.md"><img alt="GitHub contributors" src="https://img.shields.io/github/contributors/vircadia/vircadia"></a> <a href="https://github.com/vircadia/vircadia/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/vircadia/vircadia"></a> <a href="https://github.com/vircadia/vircadia/network"><img alt="GitHub forks" src="https://img.shields.io/github/forks/vircadia/vircadia"></a> <a href="https://www.apache.org/licenses/LICENSE-2.0"><img alt="Apache 2.0" src="https://img.shields.io/badge/license-Apache--2.0-%230A7BBB?style=flat"></a> <a href="https://discordapp.com/invite/Pvx2vke"><img alt="Discord" src="https://img.shields.io/discord/564926326025224212?style=flat"></a></p>
|
||||
<h3 align="center">Build Status</h3>
|
||||
<p align="center"><a href="https://github.com/vircadia/vircadia/actions/workflows/master_build.yml"><img alt="Master CI Build" src="https://github.com/vircadia/vircadia/actions/workflows/master_build.yml/badge.svg"></a></p>
|
||||
|
||||
### What is this?
|
||||
|
||||
Vircadia™ is a 3D social software project seeking to incrementally bring about a truly free and open metaverse, in desktop and XR.
|
||||
Vircadia™ is a 3D social software project seeking to incrementally bring about a truly free and open metaverse.
|
||||
|
||||
### [Website](https://vircadia.com/) | [Discord](https://discordapp.com/invite/Pvx2vke) | [Download](https://vircadia.com/download-vircadia/)
|
||||
* Desktop and VR use
|
||||
* Hundreds of users simultaneously
|
||||
* Full-body avatars
|
||||
* FBX, glTF, and OBJ support
|
||||
* JavaScript scripting engine
|
||||
* 16km³ world space in a server
|
||||
* Fully self-hosted
|
||||
* Apache 2.0
|
||||
|
||||
### Releases
|
||||
|
||||
[View Releases here](https://github.com/vircadia/vircadia/releases/)
|
||||
|
||||
### How to build the Interface
|
||||
### How to deploy a Server
|
||||
|
||||
- [For Windows and Linux](https://vircadia.com/deploy-a-server/)
|
||||
|
||||
### Building
|
||||
|
||||
#### How to build the Interface
|
||||
|
||||
- [For Windows](https://github.com/vircadia/vircadia/blob/master/BUILD_WIN.md)
|
||||
- [For Mac](https://github.com/vircadia/vircadia/blob/master/BUILD_OSX.md)
|
||||
- [For Linux](https://github.com/vircadia/vircadia/blob/master/BUILD_LINUX.md)
|
||||
- [For Linux - Vircadia Builder](https://github.com/vircadia/vircadia-builder)
|
||||
|
||||
### How to deploy a Server
|
||||
|
||||
- [For Windows and Linux](https://vircadia.com/deploy-a-server/)
|
||||
|
||||
### How to build a Server
|
||||
#### How to build a Server
|
||||
|
||||
- [For Windows](https://github.com/vircadia/vircadia/blob/master/BUILD_WIN.md)
|
||||
- [For Linux](https://github.com/vircadia/vircadia/blob/master/BUILD_LINUX.md)
|
||||
- [For Linux - Vircadia Builder](https://github.com/vircadia/vircadia-builder)
|
||||
|
||||
### How to generate an Installer
|
||||
#### How to generate an Installer
|
||||
|
||||
- [For Windows](https://github.com/vircadia/vircadia/blob/master/INSTALLER.md)
|
||||
- [For Mac](https://github.com/vircadia/vircadia/blob/master/INSTALLER.md#os-x)
|
||||
- [For Linux - AppImage - Vircadia Builder](https://github.com/vircadia/vircadia-builder/blob/master/README.md#building-appimages)
|
||||
- [For Windows - Interface & Server](https://github.com/vircadia/vircadia/blob/master/INSTALLER.md)
|
||||
- [For Mac - Interface](https://github.com/vircadia/vircadia/blob/master/INSTALLER.md#os-x)
|
||||
- [For Linux - Server .deb - Vircadia Builder](INSTALLER.md#ubuntu-1804--deb)
|
||||
- [For Linux - Server .rpm - Vircadia Builder](INSTALLER.md#amazon-linux-2--rpm)
|
||||
- [For Linux - Interface AppImage - Vircadia Builder](https://github.com/vircadia/vircadia-builder/blob/master/README.md#building-appimages)
|
||||
|
||||
### Boot to Metaverse: [The Goal](https://vircadia.com/vision/)
|
||||
|
||||
|
@ -43,14 +58,16 @@ Vircadia consists of many projects and codebases with its unifying structure's g
|
|||
|
||||
- The Interface (Codename Athena) - You are here!
|
||||
- The Server (Codename Athena) - You are also here!
|
||||
- The UI Framework (Codename Nyx) - Codebase coming soon.
|
||||
- [The Metaverse (Codename Iamus)](https://github.com/vircadia/Iamus/)
|
||||
- [The Metaverse Dashboard (Codename Iamus)](https://github.com/vircadia/project-iamus-dashboard/)
|
||||
- [The Launcher (Codename Pantheon)](https://github.com/vircadia/pantheon-launcher/)
|
||||
- [The Web Interface (Codename Aether)](https://github.com/vircadia/vircadia-web/)
|
||||
- [The Web SDK (Codename Ananke)](https://github.com/vircadia/vircadia-web-sdk/)
|
||||
- [The Metaverse Server (Codename Iamus)](https://github.com/vircadia/Iamus/)
|
||||
- [The Metaverse Server Dashboard (Codename Iamus)](https://github.com/vircadia/project-iamus-dashboard/)
|
||||
- [The Launcher (Codename Pantheon)](https://github.com/vircadia/pantheon-launcher/) - Currently Windows only.
|
||||
|
||||
#### Child Projects
|
||||
- [Vircadia Builder for Linux](https://github.com/vircadia/vircadia-builder/)
|
||||
- [General Documentation](https://github.com/vircadia/vircadia-docs-sphinx/)
|
||||
- [User Documentation](https://github.com/vircadia/vircadia-docs-sphinx/)
|
||||
- [Developer Documentation](https://github.com/vircadia/vircadia-dev-docs/)
|
||||
|
||||
### Contribution
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME native-lib)
|
||||
setup_hifi_library()
|
||||
link_hifi_libraries(shared task networking gl gpu qml image fbx hfm render-utils physics entities octree ${PLATFORM_GL_BACKEND})
|
||||
link_hifi_libraries(shared task networking gl gpu qml image model-serializers hfm render-utils physics entities octree ${PLATFORM_GL_BACKEND})
|
||||
target_opengl()
|
||||
target_bullet()
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ set(TARGET_NAME questInterface)
|
|||
setup_hifi_library()
|
||||
link_hifi_libraries(
|
||||
shared task networking qml
|
||||
image fbx hfm render-utils physics entities octree
|
||||
image model-serializers hfm render-utils physics entities octree
|
||||
oculusMobile oculusMobilePlugin
|
||||
gl gpu ${PLATFORM_GL_BACKEND}
|
||||
)
|
||||
|
|
|
@ -8,10 +8,11 @@ if (APPLE)
|
|||
endif ()
|
||||
|
||||
setup_memory_debugger()
|
||||
setup_thread_debugger()
|
||||
|
||||
# link in the shared libraries
|
||||
link_hifi_libraries(
|
||||
audio avatars octree gpu graphics shaders fbx hfm entities
|
||||
audio avatars octree gpu graphics shaders model-serializers hfm entities
|
||||
networking animation recording shared script-engine embedded-webserver
|
||||
controllers physics plugins midi image
|
||||
material-networking model-networking ktx shaders
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "Agent.h"
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* The <code>Agent</code> API enables an assignment client to emulate an avatar. Setting <code>isAvatar = true</code> connects
|
||||
* the assignment client to the avatar and audio mixers, and enables the {@link Avatar} API to be used.
|
||||
*
|
||||
|
@ -62,7 +62,7 @@ public:
|
|||
QUuid getSessionUUID() const { return _agent->getSessionUUID(); }
|
||||
|
||||
public slots:
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Sets whether the script should emulate an avatar.
|
||||
* @function Agent.setIsAvatar
|
||||
* @param {boolean} isAvatar - <code>true</code> if the script emulates an avatar, otherwise <code>false</code>.
|
||||
|
@ -75,7 +75,7 @@ public slots:
|
|||
*/
|
||||
void setIsAvatar(bool isAvatar) const { _agent->setIsAvatar(isAvatar); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Checks whether the script is emulating an avatar.
|
||||
* @function Agent.isAvatar
|
||||
* @returns {boolean} <code>true</code> if the script is emulating an avatar, otherwise <code>false</code>.
|
||||
|
@ -87,7 +87,7 @@ public slots:
|
|||
*/
|
||||
bool isAvatar() const { return _agent->isAvatar(); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Plays a sound from the position and with the orientation of the emulated avatar's head. No sound is played unless
|
||||
* <code>isAvatar == true</code>.
|
||||
* @function Agent.playAvatarSound
|
||||
|
|
|
@ -269,7 +269,13 @@ void AvatarMixerClientData::processSetTraitsMessage(ReceivedMessage& message,
|
|||
// the avatar mixer uses the negative value of the sent version
|
||||
instanceVersionRef = -packetTraitVersion;
|
||||
} else {
|
||||
_avatar->processTraitInstance(traitType, instanceID, message.read(traitSize));
|
||||
// Don't accept avatar entity data for distribution unless sender has rez permissions on the domain.
|
||||
// The sender shouldn't be sending avatar entity data, however this provides a back-up.
|
||||
auto trait = message.read(traitSize);
|
||||
if (sendingNode.getCanRezAvatarEntities()) {
|
||||
_avatar->processTraitInstance(traitType, instanceID, trait);
|
||||
}
|
||||
|
||||
instanceVersionRef = packetTraitVersion;
|
||||
}
|
||||
|
||||
|
@ -290,6 +296,29 @@ void AvatarMixerClientData::processSetTraitsMessage(ReceivedMessage& message,
|
|||
}
|
||||
}
|
||||
|
||||
void AvatarMixerClientData::emulateDeleteEntitiesTraitsMessage(const QList<QUuid>& avatarEntityIDs) {
|
||||
// Emulates processSetTraitsMessage() actions on behalf of an avatar whose canRezAvatarEntities permission has been removed.
|
||||
// The source avatar should be removing its avatar entities. However, using this method provides a back-up.
|
||||
|
||||
auto traitType = AvatarTraits::AvatarEntity;
|
||||
for (const auto& entityID : avatarEntityIDs) {
|
||||
auto& instanceVersionRef = _lastReceivedTraitVersions.getInstanceValueRef(traitType, entityID);
|
||||
|
||||
_avatar->processDeletedTraitInstance(traitType, entityID);
|
||||
// Mixer doesn't need deleted IDs.
|
||||
_avatar->getAndClearRecentlyRemovedIDs();
|
||||
|
||||
// to track a deleted instance but keep version information
|
||||
// the avatar mixer uses the negative value of the sent version
|
||||
// Because there is no originating message from an avatar we enlarge the magnitude by 1.
|
||||
// If a user subsequently has canRezAvatarEntities permission granted, they will have to relog in order for their
|
||||
// avatar entities to be visible to others.
|
||||
instanceVersionRef = -instanceVersionRef - 1;
|
||||
}
|
||||
|
||||
_lastReceivedTraitsChange = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void AvatarMixerClientData::processBulkAvatarTraitsAckMessage(ReceivedMessage& message) {
|
||||
// Avatar Traits flow control marks each outgoing avatar traits packet with a
|
||||
// sequence number. The mixer caches the traits sent in the traits packet.
|
||||
|
|
|
@ -132,6 +132,7 @@ public:
|
|||
int processPackets(const SlaveSharedData& slaveSharedData); // returns number of packets processed
|
||||
|
||||
void processSetTraitsMessage(ReceivedMessage& message, const SlaveSharedData& slaveSharedData, Node& sendingNode);
|
||||
void emulateDeleteEntitiesTraitsMessage(const QList<QUuid>& avatarEntityIDs);
|
||||
void processBulkAvatarTraitsAckMessage(ReceivedMessage& message);
|
||||
void checkSkeletonURLAgainstWhitelist(const SlaveSharedData& slaveSharedData, Node& sendingNode,
|
||||
AvatarTraits::TraitVersion traitVersion);
|
||||
|
|
|
@ -432,6 +432,17 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
|||
}
|
||||
}
|
||||
|
||||
// The source avatar should be removing its avatar entities. However, provide a back-up.
|
||||
if (sendAvatar) {
|
||||
if (!sourceAvatarNode->getCanRezAvatarEntities()) {
|
||||
auto sourceAvatarNodeData = reinterpret_cast<AvatarMixerClientData*>(sourceAvatarNode->getLinkedData());
|
||||
auto avatarEntityIDs = sourceAvatarNodeData->getAvatar().getAvatarEntityIDs();
|
||||
if (avatarEntityIDs.count() > 0) {
|
||||
sourceAvatarNodeData->emulateDeleteEntitiesTraitsMessage(avatarEntityIDs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sendAvatar) {
|
||||
AvatarDataSequenceNumber lastSeqToReceiver = destinationNodeData->getLastBroadcastSequenceNumber(sourceAvatarNode->getLocalID());
|
||||
AvatarDataSequenceNumber lastSeqFromSender = sourceAvatarNodeData->getLastReceivedSequenceNumber();
|
||||
|
|
|
@ -398,7 +398,7 @@ void ScriptableAvatar::setAvatarEntityData(const AvatarEntityMap& avatarEntityDa
|
|||
|
||||
// clear deleted traits
|
||||
for (const auto& id : idsToClear) {
|
||||
clearAvatarEntity(id);
|
||||
clearAvatarEntityInternal(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,7 +408,7 @@ void ScriptableAvatar::updateAvatarEntity(const QUuid& entityID, const QByteArra
|
|||
std::map<QUuid, EntityItemPointer>::iterator itr = _entities.find(entityID);
|
||||
if (itr != _entities.end()) {
|
||||
_entities.erase(itr);
|
||||
clearAvatarEntity(entityID);
|
||||
clearAvatarEntityInternal(entityID);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <ScriptEngine.h>
|
||||
#include <EntityItem.h>
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* The <code>Avatar</code> API is used to manipulate scriptable avatars on the domain. This API is a subset of the
|
||||
* {@link MyAvatar} API. To enable this API, set {@link Agent|Agent.isAvatar} to <code>true</code>.
|
||||
*
|
||||
|
@ -110,7 +110,7 @@ public:
|
|||
|
||||
ScriptableAvatar();
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Starts playing an animation on the avatar.
|
||||
* @function Avatar.startAnimation
|
||||
* @param {string} url - The animation file's URL. Animation files need to be in glTF or FBX format but only need to
|
||||
|
@ -130,13 +130,13 @@ public:
|
|||
bool hold = false, float firstFrame = 0.0f, float lastFrame = FLT_MAX,
|
||||
const QStringList& maskedJoints = QStringList());
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Stops playing the current animation.
|
||||
* @function Avatar.stopAnimation
|
||||
*/
|
||||
Q_INVOKABLE void stopAnimation();
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Gets the details of the current avatar animation that is being or was recently played.
|
||||
* @function Avatar.getAnimationDetails
|
||||
* @returns {Avatar.AnimationDetails} The current or recent avatar animation.
|
||||
|
@ -146,30 +146,30 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE AnimationDetails getAnimationDetails();
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @comment Uses the base class's JSDoc.
|
||||
*/
|
||||
Q_INVOKABLE virtual QStringList getJointNames() const override;
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @comment Uses the base class's JSDoc.
|
||||
*/
|
||||
/// Returns the index of the joint with the specified name, or -1 if not found/unknown.
|
||||
Q_INVOKABLE virtual int getJointIndex(const QString& name) const override;
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @comment Uses the base class's JSDoc.
|
||||
*/
|
||||
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @comment Uses the base class's JSDoc.
|
||||
*/
|
||||
int sendAvatarDataPacket(bool sendAll = false) override;
|
||||
|
||||
virtual QByteArray toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking = false) override;
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Gets details of all avatar entities.
|
||||
* <p><strong>Warning:</strong> Potentially an expensive call. Do not use if possible.</p>
|
||||
* @function Avatar.getAvatarEntityData
|
||||
|
@ -184,7 +184,7 @@ public:
|
|||
|
||||
AvatarEntityMap getAvatarEntityDataInternal(bool allProperties) const;
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Sets all avatar entities from an object.
|
||||
* <p><strong>Warning:</strong> Potentially an expensive call. Do not use if possible.</p>
|
||||
* @function Avatar.setAvatarEntityData
|
||||
|
@ -192,20 +192,20 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE void setAvatarEntityData(const AvatarEntityMap& avatarEntityData) override;
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @comment Uses the base class's JSDoc.
|
||||
*/
|
||||
Q_INVOKABLE void updateAvatarEntity(const QUuid& entityID, const QByteArray& entityData) override;
|
||||
|
||||
public slots:
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @function Avatar.update
|
||||
* @param {number} deltaTime - Delta time.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
void update(float deltatime);
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @function Avatar.setJointMappingsFromNetworkReply
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
class EntitySimulation;
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* The <code>EntityViewer</code> API provides a headless viewer for assignment client scripts, so that they can "see" entities
|
||||
* in order for them to be available in the {@link Entities} API.
|
||||
*
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <udt/PacketHeaders.h>
|
||||
|
||||
const QString MESSAGES_MIXER_LOGGING_NAME = "messages-mixer";
|
||||
const int MESSAGES_MIXER_RATE_LIMITER_INTERVAL = 1000; // 1 second
|
||||
|
||||
MessagesMixer::MessagesMixer(ReceivedMessage& message) : ThreadedAssignment(message)
|
||||
{
|
||||
|
@ -44,10 +45,20 @@ void MessagesMixer::handleMessages(QSharedPointer<ReceivedMessage> receivedMessa
|
|||
QByteArray data;
|
||||
QUuid senderID;
|
||||
bool isText;
|
||||
auto senderUUID = senderNode->getUUID();
|
||||
MessagesClient::decodeMessagesPacket(receivedMessage, channel, isText, message, data, senderID);
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
auto itr = _allSubscribers.find(senderUUID);
|
||||
if (itr == _allSubscribers.end()) {
|
||||
_allSubscribers[senderUUID] = 1;
|
||||
} else if (*itr >= _maxMessagesPerSecond) {
|
||||
return;
|
||||
} else {
|
||||
*itr += 1;
|
||||
}
|
||||
|
||||
nodeList->eachMatchingNode(
|
||||
[&](const SharedNodePointer& node)->bool {
|
||||
return node->getActiveSocket() && _channelSubscribers[channel].contains(node->getUUID());
|
||||
|
@ -60,14 +71,18 @@ void MessagesMixer::handleMessages(QSharedPointer<ReceivedMessage> receivedMessa
|
|||
}
|
||||
|
||||
void MessagesMixer::handleMessagesSubscribe(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
auto senderUUID = senderNode->getUUID();
|
||||
QString channel = QString::fromUtf8(message->getMessage());
|
||||
_channelSubscribers[channel] << senderNode->getUUID();
|
||||
|
||||
_channelSubscribers[channel] << senderUUID;
|
||||
}
|
||||
|
||||
void MessagesMixer::handleMessagesUnsubscribe(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
auto senderUUID = senderNode->getUUID();
|
||||
QString channel = QString::fromUtf8(message->getMessage());
|
||||
|
||||
if (_channelSubscribers.contains(channel)) {
|
||||
_channelSubscribers[channel].remove(senderNode->getUUID());
|
||||
_channelSubscribers[channel].remove(senderUUID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +103,48 @@ void MessagesMixer::sendStatsPacket() {
|
|||
}
|
||||
|
||||
void MessagesMixer::run() {
|
||||
ThreadedAssignment::commonInit(MESSAGES_MIXER_LOGGING_NAME, NodeType::MessagesMixer);
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
nodeList->addSetOfNodeTypesToNodeInterestSet({ NodeType::Agent, NodeType::EntityScriptServer });
|
||||
DomainHandler& domainHandler = nodeList->getDomainHandler();
|
||||
connect(&domainHandler, &DomainHandler::settingsReceived, this, &MessagesMixer::domainSettingsRequestComplete);
|
||||
|
||||
ThreadedAssignment::commonInit(MESSAGES_MIXER_LOGGING_NAME, NodeType::MessagesMixer);
|
||||
|
||||
startMaxMessagesProcessor();
|
||||
}
|
||||
|
||||
void MessagesMixer::domainSettingsRequestComplete() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
// parse the settings to pull out the values we need
|
||||
parseDomainServerSettings(nodeList->getDomainHandler().getSettingsObject());
|
||||
}
|
||||
|
||||
void MessagesMixer::parseDomainServerSettings(const QJsonObject& domainSettings) {
|
||||
const QString MESSAGES_MIXER_SETTINGS_KEY = "messages_mixer";
|
||||
QJsonObject messagesMixerGroupObject = domainSettings[MESSAGES_MIXER_SETTINGS_KEY].toObject();
|
||||
|
||||
const QString NODE_MESSAGES_PER_SECOND_KEY = "max_node_messages_per_second";
|
||||
QJsonValue maxMessagesPerSecondValue = messagesMixerGroupObject.value(NODE_MESSAGES_PER_SECOND_KEY);
|
||||
_maxMessagesPerSecond = maxMessagesPerSecondValue.toInt(DEFAULT_NODE_MESSAGES_PER_SECOND);
|
||||
}
|
||||
|
||||
void MessagesMixer::processMaxMessagesContainer() {
|
||||
_allSubscribers.clear();
|
||||
}
|
||||
|
||||
void MessagesMixer::startMaxMessagesProcessor() {
|
||||
if (_maxMessagesTimer) {
|
||||
stopMaxMessagesProcessor();
|
||||
}
|
||||
|
||||
_maxMessagesTimer = new QTimer();
|
||||
connect(_maxMessagesTimer, &QTimer::timeout, this, &MessagesMixer::processMaxMessagesContainer);
|
||||
_maxMessagesTimer->start(MESSAGES_MIXER_RATE_LIMITER_INTERVAL); // Clear the container every second.
|
||||
}
|
||||
|
||||
void MessagesMixer::stopMaxMessagesProcessor() {
|
||||
_maxMessagesTimer->stop();
|
||||
_maxMessagesTimer->deleteLater();
|
||||
_maxMessagesTimer = nullptr;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,21 @@ private slots:
|
|||
void handleMessages(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleMessagesSubscribe(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleMessagesUnsubscribe(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void parseDomainServerSettings(const QJsonObject& domainSettings);
|
||||
void domainSettingsRequestComplete();
|
||||
|
||||
void startMaxMessagesProcessor();
|
||||
void stopMaxMessagesProcessor();
|
||||
void processMaxMessagesContainer();
|
||||
|
||||
private:
|
||||
QHash<QString,QSet<QUuid>> _channelSubscribers;
|
||||
QHash<QString, QSet<QUuid>> _channelSubscribers;
|
||||
QHash<QUuid, int> _allSubscribers;
|
||||
|
||||
const int DEFAULT_NODE_MESSAGES_PER_SECOND = 1000;
|
||||
int _maxMessagesPerSecond { 0 };
|
||||
|
||||
QTimer* _maxMessagesTimer { nullptr };
|
||||
};
|
||||
|
||||
#endif // hifi_MessagesMixer_h
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Updates the entities currently in view.
|
||||
* @function EntityViewer.queryOctree
|
||||
*/
|
||||
|
@ -36,28 +36,28 @@ public slots:
|
|||
|
||||
// setters for camera attributes
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Sets the position of the view frustum.
|
||||
* @function EntityViewer.setPosition
|
||||
* @param {Vec3} position - The position of the view frustum.
|
||||
*/
|
||||
void setPosition(const glm::vec3& position) { _hasViewFrustum = true; _viewFrustum.setPosition(position); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Sets the orientation of the view frustum.
|
||||
* @function EntityViewer.setOrientation
|
||||
* @param {Quat} orientation - The orientation of the view frustum.
|
||||
*/
|
||||
void setOrientation(const glm::quat& orientation) { _hasViewFrustum = true; _viewFrustum.setOrientation(orientation); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Sets the radius of the center "keyhole" in the view frustum.
|
||||
* @function EntityViewer.setCenterRadius
|
||||
* @param {number} radius - The radius of the center "keyhole" in the view frustum.
|
||||
*/
|
||||
void setCenterRadius(float radius) { _hasViewFrustum = true; _viewFrustum.setCenterRadius(radius); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Sets the radius of the center "keyhole" in the view frustum.
|
||||
* @function EntityViewer.setKeyholeRadius
|
||||
* @param {number} radius - The radius of the center "keyhole" in the view frustum.
|
||||
|
@ -69,21 +69,21 @@ public slots:
|
|||
|
||||
// setters for LOD and PPS
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @function EntityViewer.setVoxelSizeScale
|
||||
* @param {number} sizeScale - The voxel size scale.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
void setVoxelSizeScale(float sizeScale) { _octreeQuery.setOctreeSizeScale(sizeScale) ; }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @function EntityViewer.setBoundaryLevelAdjust
|
||||
* @param {number} boundaryLevelAdjust - The boundary level adjust factor.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _octreeQuery.setBoundaryLevelAdjust(boundaryLevelAdjust); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Sets the maximum number of entity packets to receive from the domain server per second.
|
||||
* @function EntityViewer.setMaxPacketsPerSecond
|
||||
* @param {number} maxPacketsPerSecond - The maximum number of entity packets to receive per second.
|
||||
|
@ -92,14 +92,14 @@ public slots:
|
|||
|
||||
// getters for camera attributes
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Gets the position of the view frustum.
|
||||
* @function EntityViewer.getPosition
|
||||
* @returns {Vec3} The position of the view frustum.
|
||||
*/
|
||||
const glm::vec3& getPosition() const { return _viewFrustum.getPosition(); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Gets the orientation of the view frustum.
|
||||
* @function EntityViewer.getOrientation
|
||||
* @returns {Quat} The orientation of the view frustum.
|
||||
|
@ -109,21 +109,21 @@ public slots:
|
|||
|
||||
// getters for LOD and PPS
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @function EntityViewer.getVoxelSizeScale
|
||||
* @returns {number} The voxel size scale.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
float getVoxelSizeScale() const { return _octreeQuery.getOctreeSizeScale(); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* @function EntityViewer.getBoundaryLevelAdjust
|
||||
* @returns {number} The boundary level adjust factor.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
int getBoundaryLevelAdjust() const { return _octreeQuery.getBoundaryLevelAdjust(); }
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Gets the maximum number of entity packets to receive from the domain server per second.
|
||||
* @function EntityViewer.getMaxPacketsPerSecond
|
||||
* @returns {number} The maximum number of entity packets to receive per second.
|
||||
|
@ -131,7 +131,7 @@ public slots:
|
|||
int getMaxPacketsPerSecond() const { return _octreeQuery.getMaxQueryPacketsPerSecond(); }
|
||||
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Gets the number of nodes in the octree.
|
||||
* @function EntityViewer.getOctreeElementsCount
|
||||
* @returns {number} The number of nodes in the octree.
|
||||
|
|
2
cmake/externals/steamworks/CMakeLists.txt
vendored
2
cmake/externals/steamworks/CMakeLists.txt
vendored
|
@ -54,7 +54,7 @@ elseif(APPLE)
|
|||
LOG 1
|
||||
)
|
||||
|
||||
elseif(NOT ANDROID)
|
||||
elseif(NOT ANDROID AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
|
||||
# FIXME need to account for different architectures
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/redistributable_bin/linux64/libsteam_api.so CACHE STRING INTERNAL)
|
||||
|
|
|
@ -21,9 +21,9 @@ macro(GENERATE_INSTALLERS)
|
|||
set(INSTALLER_TYPE "client_only")
|
||||
string(REGEX REPLACE "Vircadia" "Vircadia Interface" _DISPLAY_NAME ${BUILD_ORGANIZATION})
|
||||
elseif (SERVER_ONLY)
|
||||
set(_PACKAGE_NAME_EXTRA "-Sandbox")
|
||||
set(_PACKAGE_NAME_EXTRA "-Server")
|
||||
set(INSTALLER_TYPE "server_only")
|
||||
string(REGEX REPLACE "Vircadia" "Vircadia Sandbox" _DISPLAY_NAME ${BUILD_ORGANIZATION})
|
||||
string(REGEX REPLACE "Vircadia" "Vircadia Server" _DISPLAY_NAME ${BUILD_ORGANIZATION})
|
||||
else ()
|
||||
set(_DISPLAY_NAME ${BUILD_ORGANIZATION})
|
||||
set(INSTALLER_TYPE "full")
|
||||
|
@ -96,19 +96,23 @@ macro(GENERATE_INSTALLERS)
|
|||
set(CPACK_PACKAGING_INSTALL_PREFIX /)
|
||||
set(CPACK_OSX_PACKAGE_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
|
||||
|
||||
# make sure a High Fidelity directory exists, in case this hits prior to other installs
|
||||
install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DMG_SUBFOLDER_NAME}\")")
|
||||
# Create folder if used.
|
||||
if (NOT INTERFACE_INSTALL_DIR STREQUAL ".")
|
||||
# make sure a High Fidelity directory exists, in case this hits prior to other installs
|
||||
install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DMG_SUBFOLDER_NAME}\")")
|
||||
|
||||
# add the resource file to the Icon file inside the folder
|
||||
install(CODE
|
||||
"execute_process(COMMAND Rez -append ${DMG_SUBFOLDER_ICON} -o \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME}/Icon\\r)"
|
||||
)
|
||||
# add the resource file to the Icon file inside the folder
|
||||
install(CODE
|
||||
"execute_process(COMMAND Rez -append ${DMG_SUBFOLDER_ICON} -o \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME}/Icon\\r)"
|
||||
)
|
||||
|
||||
# modify the folder to use that custom icon
|
||||
install(CODE "execute_process(COMMAND SetFile -a C \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME})")
|
||||
# modify the folder to use that custom icon
|
||||
install(CODE "execute_process(COMMAND SetFile -a C \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME})")
|
||||
|
||||
# hide the special Icon? file
|
||||
install(CODE "execute_process(COMMAND SetFile -a V \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME}/Icon\\r)")
|
||||
endif ()
|
||||
|
||||
# hide the special Icon? file
|
||||
install(CODE "execute_process(COMMAND SetFile -a V \${CMAKE_INSTALL_PREFIX}/${ESCAPED_DMG_SUBFOLDER_NAME}/Icon\\r)")
|
||||
endif ()
|
||||
|
||||
# configure a cpack properties file for custom variables in template
|
||||
|
@ -123,7 +127,7 @@ macro(GENERATE_INSTALLERS)
|
|||
endif ()
|
||||
|
||||
if (BUILD_SERVER)
|
||||
cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "Vircadia Sandbox")
|
||||
cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "Vircadia Server")
|
||||
endif ()
|
||||
|
||||
include(CPack)
|
||||
|
|
|
@ -26,5 +26,6 @@ function(LINK_HIFI_LIBRARIES)
|
|||
endforeach()
|
||||
|
||||
setup_memory_debugger()
|
||||
setup_thread_debugger()
|
||||
|
||||
endfunction()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
# Created by Stephen Birarda on 1/15/16.
|
||||
# Copyright 2014 High Fidelity, Inc.
|
||||
# Copyright 2020 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
|
||||
|
@ -19,13 +20,13 @@ macro(manually_install_openssl_for_qt)
|
|||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
install(
|
||||
FILES "${VCPKG_INSTALL_ROOT}/bin/ssleay32.dll"
|
||||
FILES "${VCPKG_INSTALL_ROOT}/bin/libcrypto-1_1-x64.dll"
|
||||
DESTINATION ${TARGET_INSTALL_DIR}
|
||||
COMPONENT ${TARGET_INSTALL_COMPONENT}
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${VCPKG_INSTALL_ROOT}/bin/libeay32.dll"
|
||||
FILES "${VCPKG_INSTALL_ROOT}/bin/libssl-1_1-x64.dll"
|
||||
DESTINATION ${TARGET_INSTALL_DIR}
|
||||
COMPONENT ${TARGET_INSTALL_COMPONENT}
|
||||
)
|
||||
|
|
|
@ -8,23 +8,43 @@
|
|||
#
|
||||
|
||||
macro(SETUP_MEMORY_DEBUGGER)
|
||||
if (DEFINED ENV{HIFI_MEMORY_DEBUGGING})
|
||||
SET( HIFI_MEMORY_DEBUGGING true )
|
||||
if ("$ENV{VIRCADIA_MEMORY_DEBUGGING}")
|
||||
if (VIRCADIA_THREAD_DEBUGGING)
|
||||
message(FATAL_ERROR "Thread debugging and memory debugging can't be enabled at the same time." )
|
||||
endif()
|
||||
|
||||
SET( VIRCADIA_MEMORY_DEBUGGING true )
|
||||
endif ()
|
||||
|
||||
if (HIFI_MEMORY_DEBUGGING)
|
||||
if (UNIX)
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# for clang on Linux
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -shared-libasan -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -shared-libasan -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -shared-libasan -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
else ()
|
||||
# for gcc on Linux
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fsanitize=address -U_FORTIFY_SOURCE -fno-stack-protector -fno-omit-frame-pointer")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=undefined -fsanitize=address")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=undefined -fsanitize=address")
|
||||
if (VIRCADIA_MEMORY_DEBUGGING)
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize-recover=address")
|
||||
if (UNIX)
|
||||
# Only supported on Linux and OSX
|
||||
# https://clang.llvm.org/docs/LeakSanitizer.html
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=leak")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=leak")
|
||||
endif()
|
||||
endif (UNIX)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
# for gcc
|
||||
# For some reason, using -fstack-protector results in this error:
|
||||
# usr/bin/ld: ../../libraries/audio/libaudio.so: undefined reference to `FIR_1x4_AVX512(float*, float*, float*, float*, float*, float (*) [64], int)'
|
||||
# The '-DSTACK_PROTECTOR' argument below disables the usage of this function in the code. This should be fine as it only works on the latest Intel hardware,
|
||||
# and is an optimization that should make no functional difference.
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize=leak -U_FORTIFY_SOURCE -DSTACK_PROTECTOR -fstack-protector-strong -fno-omit-frame-pointer")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize=leak ")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address -fsanitize=leak")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
# https://docs.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-160
|
||||
# Supported experimentally starting from VS2019 v16.4, and officially from v16.9.
|
||||
# UBSan and leak detection don't seem to be implemented yet.
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /Zi")
|
||||
else()
|
||||
message(FATAL_ERROR "Memory debugging is not supported on this compiler.")
|
||||
endif()
|
||||
endif ()
|
||||
endmacro(SETUP_MEMORY_DEBUGGER)
|
||||
|
|
|
@ -25,7 +25,10 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set_from_env(RELEASE_NUMBER RELEASE_NUMBER "")
|
||||
set_from_env(RELEASE_NAME RELEASE_NAME "")
|
||||
set_from_env(STABLE_BUILD STABLE_BUILD 0)
|
||||
set_from_env(INITIAL_STARTUP_LOCATION INITIAL_STARTUP_LOCATION "")
|
||||
|
||||
set_from_env(PRELOADED_STARTUP_LOCATION PRELOADED_STARTUP_LOCATION "")
|
||||
set_from_env(PRELOADED_SCRIPT_WHITELIST PRELOADED_SCRIPT_WHITELIST "")
|
||||
|
||||
set_from_env(BYPASS_SIGNING BYPASS_SIGNING 0)
|
||||
|
||||
message(STATUS "The RELEASE_TYPE variable is: ${RELEASE_TYPE}")
|
||||
|
@ -35,6 +38,12 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(CLIENT_COMPONENT client)
|
||||
set(SERVER_COMPONENT server)
|
||||
|
||||
if (APPLE)
|
||||
set(INTERFACE_BUNDLE_NAME "Vircadia")
|
||||
else()
|
||||
set(INTERFACE_BUNDLE_NAME "interface")
|
||||
endif()
|
||||
|
||||
if (RELEASE_TYPE STREQUAL "PRODUCTION")
|
||||
set(DEPLOY_PACKAGE TRUE)
|
||||
set(PRODUCTION_BUILD 1)
|
||||
|
@ -42,7 +51,6 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(BUILD_ORGANIZATION "Vircadia")
|
||||
set(HIGH_FIDELITY_PROTOCOL "hifi")
|
||||
set(HIGH_FIDELITY_APP_PROTOCOL "hifiapp")
|
||||
set(INTERFACE_BUNDLE_NAME "interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface")
|
||||
|
||||
# add definition for this release type
|
||||
|
@ -65,7 +73,6 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(PR_BUILD 1)
|
||||
set(BUILD_VERSION "PR${RELEASE_NUMBER}")
|
||||
set(BUILD_ORGANIZATION "Vircadia - PR${RELEASE_NUMBER}")
|
||||
set(INTERFACE_BUNDLE_NAME "interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface-beta")
|
||||
|
||||
# add definition for this release type
|
||||
|
@ -74,7 +81,6 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(DEV_BUILD 1)
|
||||
set(BUILD_VERSION "dev")
|
||||
set(BUILD_ORGANIZATION "Vircadia - ${BUILD_VERSION}")
|
||||
set(INTERFACE_BUNDLE_NAME "interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface-beta")
|
||||
|
||||
# add definition for this release type
|
||||
|
@ -82,7 +88,11 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
endif ()
|
||||
|
||||
set(NITPICK_BUNDLE_NAME "nitpick")
|
||||
set(NITPICK_ICON_PREFIX "nitpick")
|
||||
if (RELEASE_TYPE STREQUAL "PRODUCTION")
|
||||
set(NITPICK_ICON_PREFIX "nitpick")
|
||||
else ()
|
||||
set(NITPICK_ICON_PREFIX "nitpick-beta")
|
||||
endif ()
|
||||
|
||||
string(TIMESTAMP BUILD_TIME "%d/%m/%Y")
|
||||
|
||||
|
@ -122,10 +132,10 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
|
||||
set(DMG_SUBFOLDER_ICON "${HF_CMAKE_DIR}/installer/install-folder.rsrc")
|
||||
|
||||
set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||
set(INTERFACE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||
set(SCREENSHARE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||
set(NITPICK_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
|
||||
set(CONSOLE_INSTALL_DIR ".")
|
||||
set(INTERFACE_INSTALL_DIR ".")
|
||||
set(SCREENSHARE_INSTALL_DIR ".")
|
||||
set(NITPICK_INSTALL_DIR ".")
|
||||
|
||||
if (CLIENT_ONLY)
|
||||
set(CONSOLE_EXEC_NAME "Console.app")
|
||||
|
@ -144,7 +154,7 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
|
||||
set(SCREENSHARE_APP_CONTENTS "${SCREENSHARE_INSTALL_APP_PATH}/Contents")
|
||||
|
||||
set(INTERFACE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${INTERFACE_BUNDLE_NAME}.app")
|
||||
set(INTERFACE_INSTALL_APP_PATH "${INTERFACE_INSTALL_DIR}/${INTERFACE_BUNDLE_NAME}.app")
|
||||
set(INTERFACE_ICON_FILENAME "${INTERFACE_ICON_PREFIX}.icns")
|
||||
set(NITPICK_ICON_FILENAME "${NITPICK_ICON_PREFIX}.icns")
|
||||
else ()
|
||||
|
@ -177,12 +187,12 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
if (PRODUCTION_BUILD)
|
||||
set(INTERFACE_SHORTCUT_NAME "Vircadia")
|
||||
set(CONSOLE_SHORTCUT_NAME "Console")
|
||||
set(SANDBOX_SHORTCUT_NAME "Sandbox")
|
||||
set(SANDBOX_SHORTCUT_NAME "Server")
|
||||
set(APP_USER_MODEL_ID "com.vircadia.console")
|
||||
else ()
|
||||
set(INTERFACE_SHORTCUT_NAME "Vircadia - ${BUILD_VERSION_NO_SHA}")
|
||||
set(CONSOLE_SHORTCUT_NAME "Console - ${BUILD_VERSION_NO_SHA}")
|
||||
set(SANDBOX_SHORTCUT_NAME "Sandbox - ${BUILD_VERSION_NO_SHA}")
|
||||
set(SANDBOX_SHORTCUT_NAME "Server - ${BUILD_VERSION_NO_SHA}")
|
||||
endif ()
|
||||
|
||||
set(INTERFACE_HF_SHORTCUT_NAME "${INTERFACE_SHORTCUT_NAME}")
|
||||
|
|
|
@ -11,7 +11,11 @@ macro(SETUP_HIFI_CLIENT_SERVER_PLUGIN)
|
|||
setup_hifi_library()
|
||||
|
||||
if (BUILD_CLIENT)
|
||||
add_dependencies(interface ${TARGET_NAME})
|
||||
if (APPLE)
|
||||
add_dependencies(Vircadia ${TARGET_NAME})
|
||||
else()
|
||||
add_dependencies(interface ${TARGET_NAME})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (BUILD_SERVER)
|
||||
|
|
|
@ -30,7 +30,7 @@ macro(SETUP_HIFI_LIBRARY)
|
|||
foreach(SRC ${AVX2_SRCS})
|
||||
if (WIN32)
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS /arch:AVX2)
|
||||
elseif (APPLE OR (UNIX AND NOT ANDROID))
|
||||
elseif (APPLE OR (UNIX AND NOT ANDROID AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64"))
|
||||
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS "-mavx2 -mfma")
|
||||
endif()
|
||||
endforeach()
|
||||
|
@ -53,6 +53,7 @@ macro(SETUP_HIFI_LIBRARY)
|
|||
endforeach()
|
||||
|
||||
setup_memory_debugger()
|
||||
setup_thread_debugger()
|
||||
|
||||
# create a library and set the property so it can be referenced later
|
||||
if (${${TARGET_NAME}_SHARED})
|
||||
|
|
|
@ -9,7 +9,11 @@ macro(SETUP_HIFI_PLUGIN)
|
|||
set(${TARGET_NAME}_SHARED 1)
|
||||
setup_hifi_library(${ARGV})
|
||||
if (BUILD_CLIENT)
|
||||
add_dependencies(interface ${TARGET_NAME})
|
||||
if (APPLE)
|
||||
add_dependencies(Vircadia ${TARGET_NAME})
|
||||
else()
|
||||
add_dependencies(interface ${TARGET_NAME})
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Plugins")
|
||||
|
|
|
@ -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 "")
|
||||
|
@ -18,13 +21,16 @@ endfunction()
|
|||
|
||||
function(calculate_qt5_version result _QT_DIR)
|
||||
# All Qt5 packages have little "private" include directories named with the actual Qt version such as:
|
||||
# .../include/QtCore/5.12.3/QtCore/private
|
||||
# .../include/QtCore/5.15.2/QtCore/private
|
||||
# Sometimes we need to include these private headers for debug hackery.
|
||||
# Hence we find one of these directories and pick apart its path to determine the actual QT_VERSION.
|
||||
if (APPLE)
|
||||
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()
|
||||
|
|
36
cmake/macros/ThreadDebugger.cmake
Normal file
36
cmake/macros/ThreadDebugger.cmake
Normal file
|
@ -0,0 +1,36 @@
|
|||
#
|
||||
# MemoryDebugger.cmake
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
macro(SETUP_THREAD_DEBUGGER)
|
||||
if ("$ENV{VIRCADIA_THREAD_DEBUGGING}")
|
||||
if (VIRCADIA_MEMORY_DEBUGGING )
|
||||
message(FATAL_ERROR "Thread debugging and memory debugging can't be enabled at the same time." )
|
||||
endif ()
|
||||
|
||||
SET(VIRCADIA_THREAD_DEBUGGING true)
|
||||
endif ()
|
||||
|
||||
if (VIRCADIA_THREAD_DEBUGGING)
|
||||
if (UNIX)
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# for clang on Linux
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -fno-omit-frame-pointer")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-fsanitize=thread ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "-fsanitize=thread ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
else ()
|
||||
# for gcc on Linux
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -fno-omit-frame-pointer")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS " -fsanitize=thread ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "-fsanitize=thread ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Thread debugging is not supported on this platform.")
|
||||
endif()
|
||||
endif ()
|
||||
endmacro(SETUP_THREAD_DEBUGGER)
|
|
@ -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)
|
|
@ -19,9 +19,9 @@ include(vcpkg_common_functions)
|
|||
|
||||
vcpkg_from_github(
|
||||
OUT_SOURCE_PATH SOURCE_PATH
|
||||
REPO google/draco
|
||||
REF 1.3.3
|
||||
SHA512 80ed5a623046822f5bb26b2454c8ee8cc93ffe9eb3012e8461cefdfc577b26d69a92ea0f0c5e14f5f48c1ef99f9a7263b01710df376792e74358ae14e49c3897
|
||||
REPO vircadia/draco
|
||||
REF 1.3.5-fixed
|
||||
SHA512 68bb15de013093077946d431ab1f4080b84a66d45d20873f2c0dc44aa28034fb4ec1f6e24f9300fde563da53943b73d47163b9c6acf2667312128c50c6d075bd
|
||||
HEAD_REF master
|
||||
)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Source: hifi-client-deps
|
||||
Version: 0.1
|
||||
Description: Collected dependencies for High Fidelity applications
|
||||
Build-Depends: hifi-deps, aristo (windows), glslang, liblo (windows), nlohmann-json, openvr (linux|windows), quazip (!android), sdl2 (!android), spirv-cross (!android), spirv-tools (!android), sranipal (windows), vulkanmemoryallocator
|
||||
Build-Depends: hifi-deps, aristo (windows), glslang, liblo (windows), nlohmann-json, openvr ((linux&!arm)|windows), quazip (!android), sdl2 (!android), spirv-cross (!android), spirv-tools (!android), sranipal (windows), vulkanmemoryallocator
|
||||
|
|
|
@ -10,8 +10,8 @@ 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
|
||||
)
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Source: openssl-windows
|
||||
Version: 1.0.2p-1
|
||||
Version: 1.1.1h
|
||||
Description: OpenSSL is an open source project that provides a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library.
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
diff --git a/Configure b/Configure
|
||||
index c98107a..77ad9d3 100644
|
||||
--- a/Configure
|
||||
+++ b/Configure
|
||||
@@ -972,7 +972,7 @@ PROCESS_ARGS:
|
||||
}
|
||||
elsif (/^--with-zlib-include=(.*)$/)
|
||||
{
|
||||
- $withargs{"zlib-include"}="-I$1";
|
||||
+ $withargs{"zlib-include"}="-I\"$1\"";
|
||||
}
|
||||
elsif (/^--with-fipsdir=(.*)$/)
|
||||
{
|
|
@ -1,25 +0,0 @@
|
|||
diff --git a/util/pl/VC-32.pl b/util/pl/VC-32.pl
|
||||
index dba96cb..5722f6e 100644
|
||||
--- a/util/pl/VC-32.pl
|
||||
+++ b/util/pl/VC-32.pl
|
||||
@@ -154,9 +154,17 @@ else
|
||||
$cflags=$opt_cflags.$base_cflags;
|
||||
}
|
||||
|
||||
-# generate symbols.pdb unconditionally
|
||||
-$app_cflag.=" /Zi /Fd\$(TMP_D)/app";
|
||||
-$lib_cflag.=" /Zi /Fd\$(TMP_D)/lib";
|
||||
+# generate symbols.pdb when building dlls and embed symbols when building static libs
|
||||
+if ($shlib)
|
||||
+ {
|
||||
+ $app_cflag.=" /Zi /Fd\$(TMP_D)/app.pdb";
|
||||
+ $lib_cflag.=" /Zi /Fd\$(TMP_D)/lib.pdb";
|
||||
+ }
|
||||
+else
|
||||
+ {
|
||||
+ $app_cflag.=" /Z7";
|
||||
+ $lib_cflag.=" /Z7";
|
||||
+ }
|
||||
$lflags.=" /debug";
|
||||
|
||||
$obj='.obj';
|
|
@ -1,23 +0,0 @@
|
|||
diff --git a/crypto/cversion.c b/crypto/cversion.c
|
||||
index bfff699..17b7912 100644
|
||||
--- a/crypto/cversion.c
|
||||
+++ b/crypto/cversion.c
|
||||
@@ -56,6 +56,9 @@
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
+#define STRINGIFY2(x) #x
|
||||
+#define STRINGIFY(x) STRINGIFY2(x)
|
||||
+
|
||||
#include "cryptlib.h"
|
||||
|
||||
#ifndef NO_WINDOWS_BRAINDEATH
|
||||
@@ -79,7 +82,7 @@ const char *SSLeay_version(int t)
|
||||
}
|
||||
if (t == SSLEAY_CFLAGS) {
|
||||
#ifdef CFLAGS
|
||||
- return (CFLAGS);
|
||||
+ return STRINGIFY(CFLAGS);
|
||||
#else
|
||||
return ("compiler: information not available");
|
||||
#endif
|
|
@ -3,7 +3,7 @@ if(VCPKG_CMAKE_SYSTEM_NAME)
|
|||
endif()
|
||||
|
||||
include(vcpkg_common_functions)
|
||||
set(OPENSSL_VERSION 1.0.2p)
|
||||
set(OPENSSL_VERSION 1.1.1h)
|
||||
set(MASTER_COPY_SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/openssl-${OPENSSL_VERSION})
|
||||
|
||||
vcpkg_find_acquire_program(PERL)
|
||||
|
@ -12,18 +12,12 @@ get_filename_component(PERL_EXE_PATH ${PERL} DIRECTORY)
|
|||
set(ENV{PATH} "$ENV{PATH};${PERL_EXE_PATH}")
|
||||
|
||||
vcpkg_download_distfile(OPENSSL_SOURCE_ARCHIVE
|
||||
URLS "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz" "https://www.openssl.org/source/old/1.0.2/openssl-${OPENSSL_VERSION}.tar.gz"
|
||||
URLS "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz" "https://www.openssl.org/source/old/1.1.1/openssl-${OPENSSL_VERSION}.tar.gz"
|
||||
FILENAME "openssl-${OPENSSL_VERSION}.tar.gz"
|
||||
SHA512 958c5a7c3324bbdc8f07dfb13e11329d9a1b4452c07cf41fbd2d42b5fe29c95679332a3476d24c2dc2b88be16e4a24744aba675a05a388c0905756c77a8a2f16
|
||||
SHA512 da50fd99325841ed7a4367d9251c771ce505a443a73b327d8a46b2c6a7d2ea99e43551a164efc86f8743b22c2bdb0020bf24a9cbd445e9d68868b2dc1d34033a
|
||||
)
|
||||
|
||||
vcpkg_extract_source_archive(${OPENSSL_SOURCE_ARCHIVE})
|
||||
vcpkg_apply_patches(
|
||||
SOURCE_PATH ${MASTER_COPY_SOURCE_PATH}
|
||||
PATCHES ${CMAKE_CURRENT_LIST_DIR}/ConfigureIncludeQuotesFix.patch
|
||||
${CMAKE_CURRENT_LIST_DIR}/STRINGIFYPatch.patch
|
||||
${CMAKE_CURRENT_LIST_DIR}/EmbedSymbolsInStaticLibsZ7.patch
|
||||
)
|
||||
|
||||
vcpkg_find_acquire_program(NASM)
|
||||
get_filename_component(NASM_EXE_PATH ${NASM} DIRECTORY)
|
||||
|
@ -40,39 +34,26 @@ set(CONFIGURE_COMMAND ${PERL} Configure
|
|||
|
||||
if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86")
|
||||
set(OPENSSL_ARCH VC-WIN32)
|
||||
set(OPENSSL_DO "ms\\do_nasm.bat")
|
||||
elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64")
|
||||
set(OPENSSL_ARCH VC-WIN64A)
|
||||
set(OPENSSL_DO "ms\\do_win64a.bat")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported target architecture: ${VCPKG_TARGET_ARCHITECTURE}")
|
||||
endif()
|
||||
|
||||
if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
|
||||
set(OPENSSL_MAKEFILE "ms\\ntdll.mak")
|
||||
else()
|
||||
set(OPENSSL_MAKEFILE "ms\\nt.mak")
|
||||
endif()
|
||||
|
||||
file(REMOVE_RECURSE ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg)
|
||||
|
||||
|
||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
||||
message(STATUS "Configure ${TARGET_TRIPLET}-rel")
|
||||
file(COPY ${MASTER_COPY_SOURCE_PATH} DESTINATION ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel)
|
||||
set(SOURCE_PATH_RELEASE ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/openssl-${OPENSSL_VERSION})
|
||||
set(OPENSSLDIR_RELEASE ${CURRENT_PACKAGES_DIR})
|
||||
|
||||
message(STATUS "Configure ${TARGET_TRIPLET}-rel")
|
||||
vcpkg_execute_required_process(
|
||||
COMMAND ${CONFIGURE_COMMAND} ${OPENSSL_ARCH} "--prefix=${OPENSSLDIR_RELEASE}" "--openssldir=${OPENSSLDIR_RELEASE}" -FS
|
||||
WORKING_DIRECTORY ${SOURCE_PATH_RELEASE}
|
||||
LOGNAME configure-perl-${TARGET_TRIPLET}-${CMAKE_BUILD_TYPE}-rel
|
||||
)
|
||||
vcpkg_execute_required_process(
|
||||
COMMAND ${OPENSSL_DO}
|
||||
WORKING_DIRECTORY ${SOURCE_PATH_RELEASE}
|
||||
LOGNAME configure-do-${TARGET_TRIPLET}-${CMAKE_BUILD_TYPE}-rel
|
||||
)
|
||||
message(STATUS "Configure ${TARGET_TRIPLET}-rel done")
|
||||
|
||||
message(STATUS "Build ${TARGET_TRIPLET}-rel")
|
||||
|
@ -80,16 +61,16 @@ if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|||
# This is ok; we just do as much work as we can in parallel first, then follow up with a single-threaded build.
|
||||
make_directory(${SOURCE_PATH_RELEASE}/inc32/openssl)
|
||||
execute_process(
|
||||
COMMAND ${JOM} -k -j $ENV{NUMBER_OF_PROCESSORS} -f ${OPENSSL_MAKEFILE}
|
||||
COMMAND ${JOM} -k -j $ENV{NUMBER_OF_PROCESSORS}
|
||||
WORKING_DIRECTORY ${SOURCE_PATH_RELEASE}
|
||||
OUTPUT_FILE ${CURRENT_BUILDTREES_DIR}/build-${TARGET_TRIPLET}-rel-0-out.log
|
||||
ERROR_FILE ${CURRENT_BUILDTREES_DIR}/build-${TARGET_TRIPLET}-rel-0-err.log
|
||||
)
|
||||
vcpkg_execute_required_process(
|
||||
COMMAND nmake -f ${OPENSSL_MAKEFILE} install
|
||||
COMMAND nmake install
|
||||
WORKING_DIRECTORY ${SOURCE_PATH_RELEASE}
|
||||
LOGNAME build-${TARGET_TRIPLET}-rel-1)
|
||||
|
||||
LOGNAME build-${TARGET_TRIPLET}-rel-1
|
||||
)
|
||||
message(STATUS "Build ${TARGET_TRIPLET}-rel done")
|
||||
endif()
|
||||
|
||||
|
@ -101,39 +82,46 @@ if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|||
set(OPENSSLDIR_DEBUG ${CURRENT_PACKAGES_DIR}/debug)
|
||||
|
||||
vcpkg_execute_required_process(
|
||||
COMMAND ${CONFIGURE_COMMAND} debug-${OPENSSL_ARCH} "--prefix=${OPENSSLDIR_DEBUG}" "--openssldir=${OPENSSLDIR_DEBUG}" -FS
|
||||
COMMAND ${CONFIGURE_COMMAND} ${OPENSSL_ARCH} --debug "--prefix=${OPENSSLDIR_DEBUG}" "--openssldir=${OPENSSLDIR_DEBUG}" -FS
|
||||
WORKING_DIRECTORY ${SOURCE_PATH_DEBUG}
|
||||
LOGNAME configure-perl-${TARGET_TRIPLET}-${CMAKE_BUILD_TYPE}-dbg
|
||||
)
|
||||
vcpkg_execute_required_process(
|
||||
COMMAND ${OPENSSL_DO}
|
||||
WORKING_DIRECTORY ${SOURCE_PATH_DEBUG}
|
||||
LOGNAME configure-do-${TARGET_TRIPLET}-${CMAKE_BUILD_TYPE}-dbg
|
||||
)
|
||||
message(STATUS "Configure ${TARGET_TRIPLET}-dbg done")
|
||||
|
||||
message(STATUS "Build ${TARGET_TRIPLET}-dbg")
|
||||
make_directory(${SOURCE_PATH_DEBUG}/inc32/openssl)
|
||||
execute_process(
|
||||
COMMAND ${JOM} -k -j $ENV{NUMBER_OF_PROCESSORS} -f ${OPENSSL_MAKEFILE}
|
||||
COMMAND ${JOM} -k -j $ENV{NUMBER_OF_PROCESSORS}
|
||||
WORKING_DIRECTORY ${SOURCE_PATH_DEBUG}
|
||||
OUTPUT_FILE ${CURRENT_BUILDTREES_DIR}/build-${TARGET_TRIPLET}-dbg-0-out.log
|
||||
ERROR_FILE ${CURRENT_BUILDTREES_DIR}/build-${TARGET_TRIPLET}-dbg-0-err.log
|
||||
)
|
||||
vcpkg_execute_required_process(
|
||||
COMMAND nmake -f ${OPENSSL_MAKEFILE} install
|
||||
COMMAND nmake install
|
||||
WORKING_DIRECTORY ${SOURCE_PATH_DEBUG}
|
||||
LOGNAME build-${TARGET_TRIPLET}-dbg-1)
|
||||
|
||||
LOGNAME build-${TARGET_TRIPLET}-dbg-1
|
||||
)
|
||||
message(STATUS "Build ${TARGET_TRIPLET}-dbg done")
|
||||
endif()
|
||||
|
||||
|
||||
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/certs)
|
||||
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/lib/engines-1_1)
|
||||
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/private)
|
||||
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/certs)
|
||||
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)
|
||||
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/lib/engines-1_1)
|
||||
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/private)
|
||||
file(REMOVE
|
||||
${CURRENT_PACKAGES_DIR}/debug/bin/openssl.exe
|
||||
${CURRENT_PACKAGES_DIR}/debug/openssl.cnf
|
||||
${CURRENT_PACKAGES_DIR}/openssl.cnf
|
||||
${CURRENT_PACKAGES_DIR}/openssl.cnf.dist
|
||||
${CURRENT_PACKAGES_DIR}/ct_log_list.cnf
|
||||
${CURRENT_PACKAGES_DIR}/ct_log_list.cnf.dist
|
||||
${CURRENT_PACKAGES_DIR}/debug/openssl.cnf
|
||||
${CURRENT_PACKAGES_DIR}/debug/openssl.cnf.dist
|
||||
${CURRENT_PACKAGES_DIR}/debug/ct_log_list.cnf
|
||||
${CURRENT_PACKAGES_DIR}/debug/ct_log_list.cnf.dist
|
||||
${CURRENT_PACKAGES_DIR}/debug/bin/openssl.exe
|
||||
)
|
||||
|
||||
file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/tools/openssl/)
|
||||
|
@ -147,14 +135,6 @@ if(VCPKG_LIBRARY_LINKAGE STREQUAL static)
|
|||
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin/)
|
||||
endif()
|
||||
|
||||
file(READ "${CURRENT_PACKAGES_DIR}/include/openssl/dtls1.h" _contents)
|
||||
string(REPLACE "<winsock.h>" "<winsock2.h>" _contents "${_contents}")
|
||||
file(WRITE "${CURRENT_PACKAGES_DIR}/include/openssl/dtls1.h" "${_contents}")
|
||||
|
||||
file(READ "${CURRENT_PACKAGES_DIR}/include/openssl/rand.h" _contents)
|
||||
string(REPLACE "# include <windows.h>" "#ifndef _WINSOCKAPI_\n#define _WINSOCKAPI_\n#endif\n# include <windows.h>" _contents "${_contents}")
|
||||
file(WRITE "${CURRENT_PACKAGES_DIR}/include/openssl/rand.h" "${_contents}")
|
||||
|
||||
vcpkg_copy_pdbs()
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_LIST_DIR}/usage DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT})
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -29,7 +29,8 @@ namespace BuildInfo {
|
|||
const QString BUILD_NUMBER = "@BUILD_NUMBER@";
|
||||
const QString BUILD_GLOBAL_SERVICES = "@BUILD_GLOBAL_SERVICES@";
|
||||
const QString BUILD_TIME = "@BUILD_TIME@";
|
||||
const QString INITIAL_STARTUP_LOCATION = "@INITIAL_STARTUP_LOCATION@";
|
||||
const QString PRELOADED_STARTUP_LOCATION = "@PRELOADED_STARTUP_LOCATION@";
|
||||
const QString PRELOADED_SCRIPT_WHITELIST = "@PRELOADED_SCRIPT_WHITELIST@";
|
||||
|
||||
enum BuildType {
|
||||
Dev,
|
||||
|
|
|
@ -251,8 +251,8 @@ Var substringResult
|
|||
|
||||
!macro InitSection SecName
|
||||
; This macro reads component installed flag from the registry and
|
||||
;changes checked state of the section on the components page.
|
||||
;Input: section index constant name specified in Section command.
|
||||
; changes checked state of the section on the components page.
|
||||
; Input: section index constant name specified in Section command.
|
||||
|
||||
ClearErrors
|
||||
;Reading component status from registry
|
||||
|
@ -718,7 +718,7 @@ Function InstallTypesPage
|
|||
StrCpy $OffsetUnits u
|
||||
StrCpy $Express "0"
|
||||
|
||||
${NSD_CreateRadioButton} 30% $CurrentOffset$OffsetUnits 100% 10u "Express Install (Recommended)"; $\nInstalls Vircadia Interface and Vircadia Sandbox"
|
||||
${NSD_CreateRadioButton} 30% $CurrentOffset$OffsetUnits 100% 10u "Express Install (Recommended)"; $\nInstalls Vircadia Interface"
|
||||
pop $ExpressInstallRadioButton
|
||||
${NSD_OnClick} $ExpressInstallRadioButton ChangeExpressLabel
|
||||
IntOp $CurrentOffset $CurrentOffset + 15
|
||||
|
@ -1346,6 +1346,7 @@ Section "-Core installation"
|
|||
${EndIf}
|
||||
|
||||
${If} @SERVER_COMPONENT_CONDITIONAL@
|
||||
${AndIf} $Express != "1"
|
||||
; handling for server console shortcut
|
||||
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk"
|
||||
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_HF_SHORTCUT_NAME@.lnk" \
|
||||
|
|
|
@ -15,6 +15,7 @@ if (APPLE)
|
|||
endif ()
|
||||
|
||||
setup_memory_debugger()
|
||||
setup_thread_debugger()
|
||||
|
||||
# TODO: find a solution that will handle web file changes in resources on windows without a re-build.
|
||||
# Currently the resources are only copied on post-build. If one is changed but the domain-server is not, they will
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": 2.4,
|
||||
"version": 2.5,
|
||||
"settings": [
|
||||
{
|
||||
"name": "metaverse",
|
||||
|
@ -295,10 +295,10 @@
|
|||
},
|
||||
{
|
||||
"name": "approved_safe_urls",
|
||||
"label": "Approved Script and QML URLs",
|
||||
"label": "Approved Script and QML URLs (Not Enabled)",
|
||||
"help": "These URLs will be sent to the Interface as safe URLs to allow through the whitelist if the Interface has this security option enabled.",
|
||||
"placeholder": "0",
|
||||
"default": "1",
|
||||
"placeholder": "",
|
||||
"default": "",
|
||||
"advanced": false
|
||||
},
|
||||
{
|
||||
|
@ -338,7 +338,7 @@
|
|||
"name": "standard_permissions",
|
||||
"type": "table",
|
||||
"label": "Domain-Wide User Permissions",
|
||||
"help": "Indicate which types of users can have which <a data-toggle='tooltip' data-html=true title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether a user can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether a user can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Rez Certified</strong><br />Sets whether a user can create new certified entities.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let’s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>domain-wide permissions</a>.",
|
||||
"help": "Indicate which types of users can have which <a data-toggle='tooltip' data-html=true title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether a user can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether a user can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether a user can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Rez Certified</strong><br />Sets whether a user can create new certified entities.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let’s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>domain-wide permissions</a>.",
|
||||
"caption": "Standard Permissions",
|
||||
"can_add_new_rows": false,
|
||||
"groups": [
|
||||
|
@ -347,8 +347,8 @@
|
|||
"span": 1
|
||||
},
|
||||
{
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether a user can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether a user can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether a user can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let’s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>?</a>",
|
||||
"span": 11
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether a user can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether a user can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether a user can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether a user can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level permissions that might otherwise apply to that user. Additionally, if more than one parameter is applicable to a given user, the permissions given to that user will be the sum of all applicable parameters. For example, let’s say only localhost users can connect and only logged in users can lock and unlock entities. If a user is both logged in and on localhost then they will be able to both connect and lock/unlock entities.</p>'>?</a>",
|
||||
"span": 12
|
||||
}
|
||||
],
|
||||
"columns": [
|
||||
|
@ -363,6 +363,13 @@
|
|||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_rez_avatar_entities",
|
||||
"label": "Avatar Entities",
|
||||
"type": "checkbox",
|
||||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_adjust_locks",
|
||||
"label": "Lock / Unlock",
|
||||
|
@ -439,17 +446,20 @@
|
|||
"default": [
|
||||
{
|
||||
"id_can_connect": true,
|
||||
"id_can_rez_avatar_entities": true,
|
||||
"id_can_rez_tmp_certified": true,
|
||||
"permissions_id": "anonymous"
|
||||
},
|
||||
{
|
||||
"id_can_connect": true,
|
||||
"id_can_rez_avatar_entities": true,
|
||||
"id_can_rez_tmp_certified": true,
|
||||
"permissions_id": "friends"
|
||||
},
|
||||
{
|
||||
"id_can_adjust_locks": true,
|
||||
"id_can_connect": true,
|
||||
"id_can_rez_avatar_entities": true,
|
||||
"id_can_adjust_locks": true,
|
||||
"id_can_connect_past_max_capacity": true,
|
||||
"id_can_kick": true,
|
||||
"id_can_replace_content": true,
|
||||
|
@ -463,6 +473,7 @@
|
|||
},
|
||||
{
|
||||
"id_can_connect": true,
|
||||
"id_can_rez_avatar_entities": true,
|
||||
"id_can_rez_tmp_certified": true,
|
||||
"permissions_id": "logged-in"
|
||||
}
|
||||
|
@ -484,8 +495,8 @@
|
|||
"span": 1
|
||||
},
|
||||
{
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users in specific groups can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users in specific groups can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users in specific groups can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether a users in specific groups can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether a user can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users in specific groups can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether user in specific groups can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether a user can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Permissions granted to a specific user will be a union of the permissions granted to the groups they are in, as well as permissions from the previous section. Group permissions are only granted if the user doesn’t have their own row in the per-account section, below.</p>'>?</a>",
|
||||
"span": 11
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users in specific groups can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether users in specific groups can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users in specific groups can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users in specific groups can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether users in specific groups can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether users in specific groups can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users in specific groups can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether user in specific groups can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether a user can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Permissions granted to a specific user will be a union of the permissions granted to the groups they are in, as well as permissions from the previous section. Group permissions are only granted if the user doesn’t have their own row in the per-account section, below.</p>'>?</a>",
|
||||
"span": 12
|
||||
}
|
||||
],
|
||||
"columns": [
|
||||
|
@ -525,6 +536,13 @@
|
|||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_rez_avatar_entities",
|
||||
"label": "Avatar Entities",
|
||||
"type": "checkbox",
|
||||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_adjust_locks",
|
||||
"label": "Lock / Unlock",
|
||||
|
@ -613,8 +631,8 @@
|
|||
"span": 1
|
||||
},
|
||||
{
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users in specific groups can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users in specific groups can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users in specific groups can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether a users in specific groups can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether a user can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users in specific groups can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether user in specific groups can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether users in specific groups can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property</li></ul><p>Permissions granted to a specific user will be a union of the permissions granted to the groups they are in. Group permissions are only granted if the user doesn’t have their own row in the per-account section, below.</p>'>?</a>",
|
||||
"span": 11
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users in specific groups can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether users in specific groups can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users in specific groups can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users in specific groups can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether users in specific groups can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether users in specific groups can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users in specific groups can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether user in specific groups can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether users in specific groups can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property</li></ul><p>Permissions granted to a specific user will be a union of the permissions granted to the groups they are in. Group permissions are only granted if the user doesn’t have their own row in the per-account section, below.</p>'>?</a>",
|
||||
"span": 12
|
||||
}
|
||||
],
|
||||
"columns": [
|
||||
|
@ -651,6 +669,13 @@
|
|||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_rez_avatar_entities",
|
||||
"label": "Avatar Entities",
|
||||
"type": "checkbox",
|
||||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_adjust_locks",
|
||||
"label": "Lock / Unlock",
|
||||
|
@ -734,8 +759,8 @@
|
|||
"span": 1
|
||||
},
|
||||
{
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether a user can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether a user can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether a user can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level or group permissions that might otherwise apply to that user.</p>'>?</a>",
|
||||
"span": 11
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether a user can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether a user can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether a user change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether a user can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether a user can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether a user can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether a user can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether a user can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether a user can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific user will supersede any parameter-level or group permissions that might otherwise apply to that user.</p>'>?</a>",
|
||||
"span": 12
|
||||
}
|
||||
],
|
||||
"columns": [
|
||||
|
@ -750,6 +775,13 @@
|
|||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_rez_avatar_entities",
|
||||
"label": "Avatar Entities",
|
||||
"type": "checkbox",
|
||||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_adjust_locks",
|
||||
"label": "Lock / Unlock",
|
||||
|
@ -833,8 +865,8 @@
|
|||
"span": 1
|
||||
},
|
||||
{
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide IP Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users from specific IPs can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users from specific IPs can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users from specific IPs can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users from specific IPs can create new entities with a finite lifetime.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether users from specific IPs can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether users from specific IPs can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users from specific IPs can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether users from specific IPs can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether users from specific IPs can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific IP will supersede any parameter-level permissions that might otherwise apply to that user (from groups or standard permissions above). IP address permissions are overriden if the user has their own row in the users section.</p>'>?</a>",
|
||||
"span": 11
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide IP Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users from specific IPs can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether users from specific IPs can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users from specific IPs can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users from specific IPs can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users from specific IPs can create new entities with a finite lifetime.</li><li><strong>Rez Temporary</strong><br />Sets whether a user can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether users from specific IPs can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether users from specific IPs can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users from specific IPs can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether users from specific IPs can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether users from specific IPs can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific IP will supersede any parameter-level permissions that might otherwise apply to that user (from groups or standard permissions above). IP address permissions are overriden if the user has their own row in the users section.</p>'>?</a>",
|
||||
"span": 12
|
||||
}
|
||||
],
|
||||
"columns": [
|
||||
|
@ -849,6 +881,13 @@
|
|||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_rez_avatar_entities",
|
||||
"label": "Avatar Entities",
|
||||
"type": "checkbox",
|
||||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_adjust_locks",
|
||||
"label": "Lock / Unlock",
|
||||
|
@ -932,8 +971,8 @@
|
|||
"span": 1
|
||||
},
|
||||
{
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide MAC Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users with specific MACs can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users from specific MACs can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users with specific MACs can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users with specific MACs can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether users with specific MACs can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether users with specific MACs can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users with specific MACs can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether users with specific MACs can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether users with specific MACs can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific MAC will supersede any parameter-level permissions that might otherwise apply to that user (from groups or standard permissions above). MAC address permissions are overriden if the user has their own row in the users section.</p>'>?</a>",
|
||||
"span": 11
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide MAC Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users with specific MACs can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether users with specific MACs can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users from specific MACs can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users with specific MACs can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users with specific MACs can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether users with specific MACs can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether users with specific MACs can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users with specific MACs can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether users with specific MACs can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether users with specific MACs can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific MAC will supersede any parameter-level permissions that might otherwise apply to that user (from groups or standard permissions above). MAC address permissions are overriden if the user has their own row in the users section.</p>'>?</a>",
|
||||
"span": 12
|
||||
}
|
||||
],
|
||||
"columns": [
|
||||
|
@ -948,6 +987,13 @@
|
|||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_rez_avatar_entities",
|
||||
"label": "Avatar Entities",
|
||||
"type": "checkbox",
|
||||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_adjust_locks",
|
||||
"label": "Lock / Unlock",
|
||||
|
@ -1031,8 +1077,8 @@
|
|||
"span": 1
|
||||
},
|
||||
{
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide Machine Fingerprint Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users with specific Machine Fingerprints can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users from specific Machine Fingerprints can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users with specific Machine Fingerprints can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users with specific Machine Fingerprints can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether users with specific Machine Fingerprints can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether users with specific Machine Fingerprints can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users with specific Machine Fingerprints can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether users with specific Machine Fingerprints can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether users with specific Machine Fingerprints can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific Machine Fingerprint will supersede any parameter-level permissions that might otherwise apply to that user (from groups or standard permissions above). Machine Fingerprint address permissions are overriden if the user has their own row in the users section.</p>'>?</a>",
|
||||
"span": 11
|
||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide Machine Fingerprint Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users with specific Machine Fingerprints can connect to the domain.</li><li><strong>Avatar Entities</strong><br />Sets whether users with specific Machine Fingerprints can use avatar entities on the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users from specific Machine Fingerprints can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users with specific Machine Fingerprints can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users with specific Machine Fingerprints can create new entities with a finite lifetime.</li><li><strong>Rez Certified</strong><br />Sets whether users with specific Machine Fingerprints can create new certified entities.</li><li><strong>Rez Temporary Certified</strong><br />Sets whether users with specific Machine Fingerprints can create new certified entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users with specific Machine Fingerprints can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether users with specific Machine Fingerprints can connect even if the domain has reached or exceeded its maximum allowed agents.</li><li><strong>Replace Content</strong><br>Sets whether users with specific Machine Fingerprints can replace entire content sets by wiping existing domain content.</li><li><strong>Get and Set Private User Data</strong><br>Sets whether a user can get and set the privateUserData entity property.</li></ul><p>Note that permissions assigned to a specific Machine Fingerprint will supersede any parameter-level permissions that might otherwise apply to that user (from groups or standard permissions above). Machine Fingerprint address permissions are overriden if the user has their own row in the users section.</p>'>?</a>",
|
||||
"span": 12
|
||||
}
|
||||
],
|
||||
"columns": [
|
||||
|
@ -1047,6 +1093,13 @@
|
|||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_rez_avatar_entities",
|
||||
"label": "Avatar Entities",
|
||||
"type": "checkbox",
|
||||
"editable": true,
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "id_can_adjust_locks",
|
||||
"label": "Lock / Unlock",
|
||||
|
@ -1488,6 +1541,24 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "messages_mixer",
|
||||
"label": "Messages Mixer",
|
||||
"assignment-types": [
|
||||
4
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"name": "max_node_messages_per_second",
|
||||
"type": "int",
|
||||
"label": "Maximum Message Rate",
|
||||
"help": "Maximum message send rate (messages per second) per node",
|
||||
"placeholder": 1000,
|
||||
"default": 1000,
|
||||
"advanced": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "entity_server_settings",
|
||||
"label": "Entities",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -465,6 +465,7 @@ function savePermissions() {
|
|||
"standard_permissions": [
|
||||
{
|
||||
"id_can_connect": anonymousCanConnect,
|
||||
"id_can_rez_avatar_entities": anonymousCanConnect,
|
||||
"id_can_rez": anonymousCanRez,
|
||||
"id_can_rez_certified": anonymousCanRez,
|
||||
"id_can_rez_tmp": anonymousCanRez,
|
||||
|
@ -473,6 +474,7 @@ function savePermissions() {
|
|||
},
|
||||
{
|
||||
"id_can_connect": friendsCanConnect,
|
||||
"id_can_rez_avatar_entities": friendsCanConnect,
|
||||
"id_can_rez": friendsCanRez,
|
||||
"id_can_rez_certified": friendsCanRez,
|
||||
"id_can_rez_tmp": friendsCanRez,
|
||||
|
@ -481,6 +483,7 @@ function savePermissions() {
|
|||
},
|
||||
{
|
||||
"id_can_connect": loggedInCanConnect,
|
||||
"id_can_rez_avatar_entities": loggedInCanConnect,
|
||||
"id_can_rez": loggedInCanRez,
|
||||
"id_can_rez_certified": loggedInCanRez,
|
||||
"id_can_rez_tmp": loggedInCanRez,
|
||||
|
@ -490,6 +493,7 @@ function savePermissions() {
|
|||
{
|
||||
"id_can_adjust_locks": localhostPermissions,
|
||||
"id_can_connect": localhostPermissions,
|
||||
"id_can_rez_avatar_entities": localhostPermissions,
|
||||
"id_can_connect_past_max_capacity": localhostPermissions,
|
||||
"id_can_kick": localhostPermissions,
|
||||
"id_can_replace_content": localhostPermissions,
|
||||
|
|
|
@ -353,6 +353,7 @@ void DomainGatekeeper::updateNodePermissions() {
|
|||
userPerms.permissions |= NodePermissions::Permission::canWriteToAssetServer;
|
||||
userPerms.permissions |= NodePermissions::Permission::canReplaceDomainContent;
|
||||
userPerms.permissions |= NodePermissions::Permission::canGetAndSetPrivateUserData;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezAvatarEntities;
|
||||
} 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
|
||||
|
@ -448,6 +449,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
|
|||
userPerms.permissions |= NodePermissions::Permission::canWriteToAssetServer;
|
||||
userPerms.permissions |= NodePermissions::Permission::canReplaceDomainContent;
|
||||
userPerms.permissions |= NodePermissions::Permission::canGetAndSetPrivateUserData;
|
||||
userPerms.permissions |= NodePermissions::Permission::canRezAvatarEntities;
|
||||
newNode->setPermissions(userPerms);
|
||||
return newNode;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ using namespace std::chrono;
|
|||
|
||||
Q_LOGGING_CATEGORY(domain_server, "hifi.domain_server")
|
||||
Q_LOGGING_CATEGORY(domain_server_ice, "hifi.domain_server.ice")
|
||||
Q_LOGGING_CATEGORY(domain_server_auth, "vircadia.domain_server.auth")
|
||||
|
||||
const QString ACCESS_TOKEN_KEY_PATH = "metaverse.access_token";
|
||||
const QString DomainServer::REPLACEMENT_FILE_EXTENSION = ".replace";
|
||||
|
@ -660,7 +661,7 @@ bool DomainServer::isPacketVerified(const udt::Packet& packet) {
|
|||
|
||||
// if this is a mismatching connect packet, we can't simply drop it on the floor
|
||||
// send back a packet to the interface that tells them we refuse connection for a mismatch
|
||||
if (headerType == PacketType::DomainConnectRequest
|
||||
if ((headerType == PacketType::DomainConnectRequest || headerType == PacketType::DomainConnectRequestPending)
|
||||
&& headerVersion != versionForPacketType(PacketType::DomainConnectRequest)) {
|
||||
DomainGatekeeper::sendProtocolMismatchConnectionDenial(packet.getSenderSockAddr());
|
||||
}
|
||||
|
@ -806,6 +807,8 @@ void DomainServer::setupNodeListAndAssignments() {
|
|||
// register the gatekeeper for the packets it needs to receive
|
||||
packetReceiver.registerListener(PacketType::DomainConnectRequest,
|
||||
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processConnectRequestPacket));
|
||||
packetReceiver.registerListener(PacketType::DomainConnectRequestPending,
|
||||
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processConnectRequestPacket));
|
||||
packetReceiver.registerListener(PacketType::ICEPing,
|
||||
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processICEPingPacket));
|
||||
packetReceiver.registerListener(PacketType::ICEPingReply,
|
||||
|
@ -1545,9 +1548,9 @@ void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress, const
|
|||
|
||||
static const QString PORT_SETTINGS_KEY = "domain_server." + PUBLIC_SOCKET_PORT_KEY;
|
||||
const int portFromSettings = _settingsManager.valueForKeyPath(PORT_SETTINGS_KEY).toInt();
|
||||
if (port != NULL) {
|
||||
if (port != 0) {
|
||||
domainObject[PUBLIC_SOCKET_PORT_KEY] = port;
|
||||
} else if (portFromSettings != NULL) {
|
||||
} else if (portFromSettings != 0) {
|
||||
domainObject[PUBLIC_SOCKET_PORT_KEY] = portFromSettings;
|
||||
}
|
||||
|
||||
|
@ -2771,6 +2774,20 @@ void DomainServer::profileRequestFinished() {
|
|||
}
|
||||
}
|
||||
|
||||
QString DomainServer::operationToString(const QNetworkAccessManager::Operation &op) {
|
||||
switch(op) {
|
||||
case QNetworkAccessManager::Operation::HeadOperation: return "HEAD";
|
||||
case QNetworkAccessManager::Operation::GetOperation: return "GET";
|
||||
case QNetworkAccessManager::Operation::PutOperation: return "PUT";
|
||||
case QNetworkAccessManager::Operation::PostOperation: return "POST";
|
||||
case QNetworkAccessManager::Operation::DeleteOperation: return "DELETE";
|
||||
case QNetworkAccessManager::Operation::CustomOperation: return "CUSTOM";
|
||||
case QNetworkAccessManager::Operation::UnknownOperation:
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* connection) {
|
||||
|
||||
static const QByteArray HTTP_COOKIE_HEADER_KEY = "Cookie";
|
||||
|
@ -2784,6 +2801,9 @@ std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* c
|
|||
|
||||
QVariant adminUsersVariant = _settingsManager.valueForKeyPath(ADMIN_USERS_CONFIG_KEY);
|
||||
QVariant adminRolesVariant = _settingsManager.valueForKeyPath(ADMIN_ROLES_CONFIG_KEY);
|
||||
QString httpPeerAddress = connection->peerAddress().toString();
|
||||
QString httpOperation = operationToString(connection->requestOperation());
|
||||
|
||||
|
||||
if (_oauthEnable) {
|
||||
QString cookieString = connection->requestHeader(HTTP_COOKIE_HEADER_KEY);
|
||||
|
@ -2817,11 +2837,15 @@ std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* c
|
|||
foreach(const QString& userRole, sessionData.getRoles()) {
|
||||
if (adminRolesArray.contains(userRole)) {
|
||||
// this user has a role that allows them to administer the domain-server
|
||||
qCInfo(domain_server_auth) << httpPeerAddress << "- OAuth:" << profileUsername << " - "
|
||||
<< httpOperation << " " << connection->requestUrl();
|
||||
return { true, profileUsername };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qCWarning(domain_server_auth) << httpPeerAddress << "- OAuth authentication failed for " << profileUsername << "-"
|
||||
<< httpOperation << " " << connection->requestUrl();
|
||||
connection->respond(HTTPConnection::StatusCode401, UNAUTHENTICATED_BODY);
|
||||
|
||||
// the user does not have allowed username or role, return 401
|
||||
|
@ -2833,6 +2857,9 @@ std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* c
|
|||
if (connection->requestHeader(REQUESTED_WITH_HEADER) == XML_REQUESTED_WITH) {
|
||||
// unauthorized XHR requests get a 401 and not a 302, since there isn't an XHR
|
||||
// path to OAuth authorize
|
||||
|
||||
qCWarning(domain_server_auth) << httpPeerAddress << "- OAuth unauthorized XHR -"
|
||||
<< httpOperation << " " << connection->requestUrl();
|
||||
connection->respond(HTTPConnection::StatusCode401, UNAUTHENTICATED_BODY);
|
||||
} else {
|
||||
// re-direct this user to OAuth page
|
||||
|
@ -2849,6 +2876,8 @@ std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* c
|
|||
|
||||
redirectHeaders.insert("Location", authURL.toEncoded());
|
||||
|
||||
qCWarning(domain_server_auth) << httpPeerAddress << "- OAuth redirecting -"
|
||||
<< httpOperation << " " << connection->requestUrl();
|
||||
connection->respond(HTTPConnection::StatusCode302,
|
||||
QByteArray(), HTTPConnection::DefaultContentType, redirectHeaders);
|
||||
}
|
||||
|
@ -2883,7 +2912,12 @@ std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* c
|
|||
"" : QCryptographicHash::hash(headerPassword.toUtf8(), QCryptographicHash::Sha256).toHex();
|
||||
|
||||
if (settingsUsername == headerUsername && hexHeaderPassword == settingsPassword) {
|
||||
qCInfo(domain_server_auth) << httpPeerAddress << "- Basic:" << headerUsername << "-"
|
||||
<< httpOperation << " " << connection->requestUrl();
|
||||
return { true, headerUsername };
|
||||
} else {
|
||||
qCWarning(domain_server_auth) << httpPeerAddress << "- Basic auth failed for" << headerUsername << "-"
|
||||
<< httpOperation << " " << connection->requestUrl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2904,11 +2938,13 @@ std::pair<bool, QString> DomainServer::isAuthenticatedRequest(HTTPConnection* c
|
|||
connection->respond(HTTPConnection::StatusCode401, UNAUTHENTICATED_BODY,
|
||||
HTTPConnection::DefaultContentType, basicAuthHeader);
|
||||
|
||||
qCWarning(domain_server_auth) << httpPeerAddress << "- Basic auth required -" << httpOperation << " " << connection->requestUrl();
|
||||
// not authenticated, bubble up false
|
||||
return { false, QString() };
|
||||
|
||||
} else {
|
||||
// we don't have an OAuth URL + admin roles/usernames, so all users are authenticated
|
||||
qCWarning(domain_server_auth) << httpPeerAddress << "- OPEN ACCESS -" << httpOperation << " " << connection->requestUrl();
|
||||
return { true, QString() };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
Q_DECLARE_LOGGING_CATEGORY(domain_server)
|
||||
Q_DECLARE_LOGGING_CATEGORY(domain_server_ice)
|
||||
Q_DECLARE_LOGGING_CATEGORY(domain_server_auth)
|
||||
|
||||
typedef QSharedPointer<Assignment> SharedAssignmentPointer;
|
||||
typedef QMultiHash<QUuid, WalletTransaction*> TransactionHash;
|
||||
|
@ -233,6 +234,8 @@ private:
|
|||
std::initializer_list<QString> optionalData = { },
|
||||
bool requireAccessToken = true);
|
||||
|
||||
QString operationToString(const QNetworkAccessManager::Operation &op);
|
||||
|
||||
SubnetList _acSubnetWhitelist;
|
||||
|
||||
std::vector<QString> _replicatedUsernames;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <SettingHandle.h>
|
||||
#include <SettingHelpers.h>
|
||||
#include <FingerprintUtils.h>
|
||||
#include <ModerationFlags.h>
|
||||
|
||||
#include "DomainServerNodeData.h"
|
||||
|
||||
|
@ -527,6 +528,28 @@ void DomainServerSettingsManager::setupConfigMap(const QString& userConfigFilena
|
|||
*newAdminRoles = adminRoles;
|
||||
}
|
||||
|
||||
if (oldVersion < 2.5) {
|
||||
// Default values for new canRezAvatarEntities permission.
|
||||
unpackPermissions();
|
||||
std::list<std::unordered_map<NodePermissionsKey, NodePermissionsPointer>> permissionsSets{
|
||||
_standardAgentPermissions.get(),
|
||||
_agentPermissions.get(),
|
||||
_ipPermissions.get(),
|
||||
_macPermissions.get(),
|
||||
_machineFingerprintPermissions.get(),
|
||||
_groupPermissions.get(),
|
||||
_groupForbiddens.get()
|
||||
};
|
||||
foreach (auto permissionsSet, permissionsSets) {
|
||||
for (auto entry : permissionsSet) {
|
||||
const auto& userKey = entry.first;
|
||||
if (permissionsSet[userKey]->can(NodePermissions::Permission::canConnectToDomain)) {
|
||||
permissionsSet[userKey]->set(NodePermissions::Permission::canRezAvatarEntities);
|
||||
}
|
||||
}
|
||||
}
|
||||
packPermissions();
|
||||
}
|
||||
|
||||
// write the current description version to our settings
|
||||
*versionVariant = _descriptionVersion;
|
||||
|
@ -863,6 +886,20 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer<Re
|
|||
// pull the UUID being kicked from the packet
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
bool hasOptionalBanParameters = false;
|
||||
int banParameters;
|
||||
bool banByUsername;
|
||||
bool banByFingerprint;
|
||||
bool banByIP;
|
||||
// pull optional ban parameters from the packet
|
||||
if (message.data()->getSize() == (NUM_BYTES_RFC4122_UUID + sizeof(int))) {
|
||||
hasOptionalBanParameters = true;
|
||||
message->readPrimitive(&banParameters);
|
||||
banByUsername = banParameters & ModerationFlags::BanFlags::BAN_BY_USERNAME;
|
||||
banByFingerprint = banParameters & ModerationFlags::BanFlags::BAN_BY_FINGERPRINT;
|
||||
banByIP = banParameters & ModerationFlags::BanFlags::BAN_BY_IP;
|
||||
}
|
||||
|
||||
if (!nodeUUID.isNull() && nodeUUID != sendingNode->getUUID()) {
|
||||
// make sure we actually have a node with this UUID
|
||||
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||
|
@ -881,16 +918,20 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer<Re
|
|||
if (!verifiedUsername.isEmpty()) {
|
||||
// if we have a verified user name for this user, we first apply the kick to the username
|
||||
|
||||
// check if there were already permissions
|
||||
bool hadPermissions = havePermissionsForName(verifiedUsername);
|
||||
// if we have optional ban parameters, we should ban the username based on the parameter
|
||||
if (!hasOptionalBanParameters || banByUsername) {
|
||||
// check if there were already permissions
|
||||
bool hadPermissions = havePermissionsForName(verifiedUsername);
|
||||
|
||||
// grab or create permissions for the given username
|
||||
auto userPermissions = _agentPermissions[matchingNode->getPermissions().getKey()];
|
||||
// grab or create permissions for the given username
|
||||
auto userPermissions = _agentPermissions[matchingNode->getPermissions().getKey()];
|
||||
|
||||
newPermissions = !hadPermissions || userPermissions->can(NodePermissions::Permission::canConnectToDomain);
|
||||
newPermissions =
|
||||
!hadPermissions || userPermissions->can(NodePermissions::Permission::canConnectToDomain);
|
||||
|
||||
// ensure that the connect permission is clear
|
||||
userPermissions->clear(NodePermissions::Permission::canConnectToDomain);
|
||||
// ensure that the connect permission is clear
|
||||
userPermissions->clear(NodePermissions::Permission::canConnectToDomain);
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't have a username, or this domain-server uses the "multi-kick" setting to
|
||||
|
@ -898,7 +939,7 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer<Re
|
|||
// then we remove connect permissions for the machine fingerprint (or IP as fallback)
|
||||
const QString MULTI_KICK_SETTINGS_KEYPATH = "security.multi_kick_logged_in";
|
||||
|
||||
if (verifiedUsername.isEmpty() || valueOrDefaultValueForKeyPath(MULTI_KICK_SETTINGS_KEYPATH).toBool()) {
|
||||
if (banByFingerprint || verifiedUsername.isEmpty() || valueOrDefaultValueForKeyPath(MULTI_KICK_SETTINGS_KEYPATH).toBool()) {
|
||||
// remove connect permissions for the machine fingerprint
|
||||
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(matchingNode->getLinkedData());
|
||||
if (nodeData) {
|
||||
|
@ -923,36 +964,39 @@ void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer<Re
|
|||
fingerprintPermissions->clear(NodePermissions::Permission::canConnectToDomain);
|
||||
}
|
||||
} else {
|
||||
// if no node data, all we can do is IP address
|
||||
auto& kickAddress = matchingNode->getActiveSocket()
|
||||
? matchingNode->getActiveSocket()->getAddress()
|
||||
: matchingNode->getPublicSocket().getAddress();
|
||||
// if no node data, all we can do is ban by IP address
|
||||
banByIP = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (banByIP) {
|
||||
auto& kickAddress = matchingNode->getActiveSocket()
|
||||
? matchingNode->getActiveSocket()->getAddress()
|
||||
: matchingNode->getPublicSocket().getAddress();
|
||||
|
||||
// probably isLoopback covers it, as whenever I try to ban an agent on same machine as the domain-server
|
||||
// it is always 127.0.0.1, but looking at the public and local addresses just to be sure
|
||||
// TODO: soon we will have feedback (in the form of a message to the client) after we kick. When we
|
||||
// do, we will have a success flag, and perhaps a reason for failure. For now, just don't do it.
|
||||
if (kickAddress == limitedNodeList->getPublicSockAddr().getAddress() ||
|
||||
kickAddress == limitedNodeList->getLocalSockAddr().getAddress() ||
|
||||
kickAddress.isLoopback() ) {
|
||||
qWarning() << "attempt to kick node running on same machine as domain server, ignoring KickRequest";
|
||||
return;
|
||||
}
|
||||
// probably isLoopback covers it, as whenever I try to ban an agent on same machine as the domain-server
|
||||
// it is always 127.0.0.1, but looking at the public and local addresses just to be sure
|
||||
// TODO: soon we will have feedback (in the form of a message to the client) after we kick. When we
|
||||
// do, we will have a success flag, and perhaps a reason for failure. For now, just don't do it.
|
||||
if (kickAddress == limitedNodeList->getPublicSockAddr().getAddress() ||
|
||||
kickAddress == limitedNodeList->getLocalSockAddr().getAddress() ||
|
||||
kickAddress.isLoopback() ) {
|
||||
qWarning() << "attempt to kick node running on same machine as domain server, ignoring KickRequest";
|
||||
return;
|
||||
}
|
||||
|
||||
NodePermissionsKey ipAddressKey(kickAddress.toString(), QUuid());
|
||||
|
||||
NodePermissionsKey ipAddressKey(kickAddress.toString(), QUuid());
|
||||
// check if there were already permissions for the IP
|
||||
bool hadIPPermissions = hasPermissionsForIP(kickAddress);
|
||||
|
||||
// check if there were already permissions for the IP
|
||||
bool hadIPPermissions = hasPermissionsForIP(kickAddress);
|
||||
// grab or create permissions for the given IP address
|
||||
auto ipPermissions = _ipPermissions[ipAddressKey];
|
||||
|
||||
// grab or create permissions for the given IP address
|
||||
auto ipPermissions = _ipPermissions[ipAddressKey];
|
||||
if (!hadIPPermissions || ipPermissions->can(NodePermissions::Permission::canConnectToDomain)) {
|
||||
newPermissions = true;
|
||||
|
||||
if (!hadIPPermissions || ipPermissions->can(NodePermissions::Permission::canConnectToDomain)) {
|
||||
newPermissions = true;
|
||||
|
||||
ipPermissions->clear(NodePermissions::Permission::canConnectToDomain);
|
||||
}
|
||||
ipPermissions->clear(NodePermissions::Permission::canConnectToDomain);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1448,6 +1492,8 @@ QJsonObject DomainServerSettingsManager::settingsResponseObjectForType(const QSt
|
|||
SettingsBackupFlag settingsBackupFlag) {
|
||||
QJsonObject responseObject;
|
||||
|
||||
responseObject["version"] = _descriptionVersion; // Domain settings version number.
|
||||
|
||||
if (!typeValue.isEmpty() || authentication == Authenticated) {
|
||||
// convert the string type value to a QJsonValue
|
||||
QJsonValue queryType = typeValue.isEmpty() ? QJsonValue() : QJsonValue(typeValue.toInt());
|
||||
|
|
232
hifi_qt.py
232
hifi_qt.py
|
@ -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
|
||||
|
@ -27,68 +52,152 @@ endif()
|
|||
def __init__(self, args):
|
||||
self.args = args
|
||||
self.configFilePath = os.path.join(args.build_root, 'qt.cmake')
|
||||
self.version = os.getenv('VIRCADIA_USE_QT_VERSION', '5.12.3')
|
||||
|
||||
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()
|
||||
|
||||
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.12.3-windows3.tar.gz%3FversionId=5ADqP0M0j5ZfimUHrx4zJld6vYceHEsI'
|
||||
self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.15.2-windows.tar.gz'
|
||||
elif 'Darwin' == system:
|
||||
self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz%3FversionId=bLAgnoJ8IMKpqv8NFDcAu8hsyQy3Rwwz'
|
||||
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 distro.id() == 'ubuntu':
|
||||
u_major = int( distro.major_version() )
|
||||
u_minor = int( distro.minor_version() )
|
||||
if 'x86_64' == cpu_architecture:
|
||||
if distro.id() == 'ubuntu':
|
||||
u_major = int( distro.major_version() )
|
||||
u_minor = int( distro.minor_version() )
|
||||
|
||||
if u_major == 16:
|
||||
self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz'
|
||||
elif u_major == 18:
|
||||
self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz'
|
||||
elif u_major == 19 and u_minor == 10:
|
||||
self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.6-ubuntu-19.10.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!!!')
|
||||
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:
|
||||
self.__no_qt_package_error()
|
||||
else:
|
||||
self.__unsupported_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.__no_qt_package_error()
|
||||
|
||||
elif 'aarch64' == cpu_architecture:
|
||||
if distro.id() == 'ubuntu':
|
||||
u_major = int( distro.major_version() )
|
||||
u_minor = int( distro.minor_version() )
|
||||
|
||||
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:
|
||||
self.__no_qt_package_error()
|
||||
else:
|
||||
self.__unsupported_error()
|
||||
|
||||
elif distro.id() == 'debian':
|
||||
u_major = int( distro.major_version() )
|
||||
u_minor = int( distro.minor_version() )
|
||||
|
||||
if u_major == 10:
|
||||
#self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz'
|
||||
self.__no_qt_package_error()
|
||||
elif u_major > 10:
|
||||
self.__no_qt_package_error()
|
||||
else:
|
||||
self.__unsupported_error()
|
||||
|
||||
else:
|
||||
self.__no_qt_package_error()
|
||||
else:
|
||||
print("Sorry, " + distro.name(pretty=True) + " is not supported. 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!!!')
|
||||
raise Exception('UNKNOWN CPU ARCHITECTURE!!!')
|
||||
|
||||
else:
|
||||
print("System : " + platform.system())
|
||||
print("Architecture: " + platform.architecture())
|
||||
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
|
||||
|
@ -103,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)
|
||||
|
|
|
@ -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='')
|
|
@ -44,13 +44,14 @@ endif()
|
|||
self.assets_url = self.readVar('EXTERNAL_BUILD_ASSETS')
|
||||
|
||||
# The noClean flag indicates we're doing weird dependency maintenance stuff
|
||||
# i.e. we've got an explicit checkout of vcpkg and we don't want the script to
|
||||
# do stuff it might otherwise do. It typically indicates that we're using our
|
||||
# i.e. we've got an explicit checkout of vcpkg and we don't want the script to
|
||||
# do stuff it might otherwise do. It typically indicates that we're using our
|
||||
# own git checkout of vcpkg and manually managing it
|
||||
self.noClean = False
|
||||
|
||||
# OS dependent information
|
||||
system = platform.system()
|
||||
machine = platform.machine()
|
||||
|
||||
if 'HIFI_VCPKG_PATH' in os.environ:
|
||||
self.path = os.environ['HIFI_VCPKG_PATH']
|
||||
|
@ -59,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')
|
||||
|
@ -105,6 +106,12 @@ endif()
|
|||
self.bootstrapEnv['CXXFLAGS'] = '-D_CTERMID_H_'
|
||||
if usePrebuilt:
|
||||
self.prebuiltArchive = self.assets_url + "/dependencies/vcpkg/builds/vcpkg-osx.tgz%3FversionId=6JrIMTdvpBF3MAsjA92BMkO79Psjzs6Z"
|
||||
elif 'Linux' == system and 'aarch64' == machine:
|
||||
self.exe = os.path.join(self.path, 'vcpkg')
|
||||
self.bootstrapCmds = [ os.path.join(self.path, 'bootstrap-vcpkg.sh'), '-disableMetrics' ]
|
||||
self.vcpkgUrl = 'http://motofckr9k.ddns.net/vircadia_packages/vcpkg-2020.11-1_arm64.tar.xz'
|
||||
self.vcpkgHash = 'f39fa1c34d2ba820954b8ce4acc05e3d0ce5fa5efe5440516ba910ff222c85c658ba4bbfc92b3fa6cbb594f99be115cda69ebe44ed38d4d3988058fb1faefbb3'
|
||||
self.hostTriplet = 'arm64-linux'
|
||||
else:
|
||||
self.exe = os.path.join(self.path, 'vcpkg')
|
||||
self.bootstrapCmds = [ os.path.join(self.path, 'bootstrap-vcpkg.sh'), '-disableMetrics' ]
|
||||
|
|
|
@ -19,6 +19,7 @@ endif ()
|
|||
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
|
||||
|
||||
setup_memory_debugger()
|
||||
setup_thread_debugger()
|
||||
|
||||
# append OpenSSL to our list of libraries to link
|
||||
target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES})
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
set(TARGET_NAME interface)
|
||||
if (APPLE)
|
||||
# Make the OSX DMG app be Vircadia.app.
|
||||
set(TARGET_NAME Vircadia)
|
||||
else()
|
||||
set(TARGET_NAME interface)
|
||||
endif()
|
||||
|
||||
project(${TARGET_NAME})
|
||||
|
||||
file(GLOB_RECURSE QML_SRC resources/qml/*.qml resources/qml/*.js)
|
||||
|
@ -28,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()
|
||||
|
@ -47,6 +53,7 @@ add_custom_target(resources ALL DEPENDS ${GENERATE_QRC_DEPENDS})
|
|||
set(OPTIONAL_EXTERNALS "LeapMotion")
|
||||
|
||||
setup_memory_debugger()
|
||||
setup_thread_debugger()
|
||||
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
||||
|
@ -191,9 +198,12 @@ if (BUILD_TOOLS AND NPM_EXECUTABLE)
|
|||
endif()
|
||||
|
||||
if (WIN32 OR APPLE)
|
||||
add_dependencies(${TARGET_NAME} resources screenshare)
|
||||
add_dependencies(${TARGET_NAME} resources)
|
||||
endif()
|
||||
|
||||
if (SCREENSHARE)
|
||||
add_dependencies(${TARGET_NAME} screenshare)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
# These are external plugins, but we need to do the 'add dependency' here so that their
|
||||
|
@ -218,7 +228,7 @@ endif()
|
|||
# link required hifi libraries
|
||||
link_hifi_libraries(
|
||||
shared workload task octree ktx gpu gl procedural graphics graphics-scripting render
|
||||
pointers recording hfm fbx networking material-networking
|
||||
pointers recording hfm model-serializers networking material-networking
|
||||
model-networking model-baker entities avatars
|
||||
audio audio-client animation script-engine physics
|
||||
render-utils entities-renderer avatars-renderer ui qml auto-updater midi
|
||||
|
@ -299,7 +309,7 @@ target_link_libraries(
|
|||
${PLATFORM_QT_LIBRARIES}
|
||||
)
|
||||
|
||||
if (UNIX AND NOT ANDROID)
|
||||
if (UNIX AND NOT ANDROID AND NOT VIRCADIA_THREAD_DEBUGGING)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# Linux
|
||||
target_link_libraries(${TARGET_NAME} pthread atomic)
|
||||
|
@ -333,10 +343,6 @@ if (APPLE)
|
|||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${CMAKE_SOURCE_DIR}/scripts"
|
||||
"${RESOURCES_DEV_DIR}/scripts"
|
||||
# copy screenshare app to the resource folder
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/../screenshare/hifi-screenshare-darwin-x64/hifi-screenshare.app"
|
||||
"${RESOURCES_DEV_DIR}/hifi-screenshare.app"
|
||||
# copy JSDoc files beside the executable
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${CMAKE_SOURCE_DIR}/tools/jsdoc/out"
|
||||
|
@ -363,6 +369,15 @@ if (APPLE)
|
|||
"${RESOURCES_DEV_DIR}/serverless/redirect.json"
|
||||
)
|
||||
|
||||
if (SCREENSHARE)
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
# copy screenshare app to the resource folder
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/../screenshare/hifi-screenshare-darwin-x64/hifi-screenshare.app"
|
||||
"${RESOURCES_DEV_DIR}/hifi-screenshare.app"
|
||||
)
|
||||
endif()
|
||||
|
||||
# call the fixup_interface macro to add required bundling commands for installation
|
||||
fixup_interface()
|
||||
|
||||
|
@ -420,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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -73,9 +73,9 @@ SpinBox {
|
|||
}
|
||||
}
|
||||
|
||||
stepSize: realStepSize * factor
|
||||
to : realTo*factor
|
||||
from : realFrom*factor
|
||||
stepSize: Math.round(realStepSize * factor)
|
||||
to : Math.round(realTo*factor)
|
||||
from : Math.round(realFrom*factor)
|
||||
|
||||
font.family: "Fira Sans SemiBold"
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
|
@ -97,11 +97,11 @@ SpinBox {
|
|||
}
|
||||
|
||||
textFromValue: function(value, locale) {
|
||||
return parseFloat(value / factor).toFixed(decimals);
|
||||
return (value / factor).toFixed(decimals);
|
||||
}
|
||||
|
||||
valueFromText: function(text, locale) {
|
||||
return Number.fromLocaleString(locale, text) * factor;
|
||||
return Math.round(Number.fromLocaleString(locale, text) * factor);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ Preference {
|
|||
decimals: preference.decimals
|
||||
minimumValue: preference.min
|
||||
maximumValue: preference.max
|
||||
realStepSize: preference.step
|
||||
width: 100
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
|
|
|
@ -76,6 +76,7 @@ Preference {
|
|||
realValue: preference.value
|
||||
minimumValue: preference.min
|
||||
maximumValue: preference.max
|
||||
realStepSize: preference.step
|
||||
width: 100
|
||||
onValueChanged: {
|
||||
slider.value = realValue;
|
||||
|
|
|
@ -518,7 +518,12 @@ Rectangle {
|
|||
glyphText: "\ue02e"
|
||||
|
||||
onClicked: {
|
||||
adjustWearables.open(currentAvatar);
|
||||
if (!AddressManager.isConnected || Entities.canRezAvatarEntities()) {
|
||||
adjustWearables.open(currentAvatar);
|
||||
} else {
|
||||
Window.alert("You cannot use wearables on this domain.")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,7 +534,11 @@ Rectangle {
|
|||
glyphText: wearablesFrozen ? hifi.glyphs.lock : hifi.glyphs.unlock;
|
||||
|
||||
onClicked: {
|
||||
emitSendToScript({'method' : 'toggleWearablesFrozen'});
|
||||
if (!AddressManager.isConnected || Entities.canRezAvatarEntities()) {
|
||||
emitSendToScript({'method' : 'toggleWearablesFrozen'});
|
||||
} else {
|
||||
Window.alert("You cannot use wearables on this domain.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -478,7 +478,7 @@ Rectangle {
|
|||
visible: iAmAdmin;
|
||||
role: "mute";
|
||||
title: "SILENCE";
|
||||
width: actionButtonWidth;
|
||||
width: actionButtonWidth - 8;
|
||||
movable: false;
|
||||
resizable: false;
|
||||
}
|
||||
|
@ -506,6 +506,7 @@ Rectangle {
|
|||
id: itemCell;
|
||||
property bool isCheckBox: styleData.role === "personalMute" || styleData.role === "ignore";
|
||||
property bool isButton: styleData.role === "mute" || styleData.role === "kick";
|
||||
property bool isBan: styleData.role === "kick";
|
||||
property bool isAvgAudio: styleData.role === "avgAudioLevel";
|
||||
opacity: !isButton ? (model && model.isPresent ? 1.0 : 0.4) : 1.0; // Admin actions shouldn't turn gray
|
||||
|
||||
|
@ -605,7 +606,9 @@ Rectangle {
|
|||
color: 2; // Red
|
||||
visible: isButton;
|
||||
enabled: !nameCard.isReplicated;
|
||||
anchors.centerIn: parent;
|
||||
anchors.verticalCenter: itemCell.verticalCenter;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: styleData.role === "kick" ? 1 : 14;
|
||||
width: 32;
|
||||
height: 32;
|
||||
onClicked: {
|
||||
|
@ -620,7 +623,39 @@ Rectangle {
|
|||
HiFiGlyphs {
|
||||
text: (styleData.role === "kick") ? hifi.glyphs.error : hifi.glyphs.muted;
|
||||
// Size
|
||||
size: parent.height*1.3;
|
||||
size: parent.height * 1.3;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
// Style
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
color: enabled ? hifi.buttons.textColor[actionButton.color]
|
||||
: hifi.buttons.disabledTextColor[actionButton.colorScheme];
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: hardBanButton;
|
||||
color: 2; // Red
|
||||
visible: isBan;
|
||||
enabled: !nameCard.isReplicated;
|
||||
anchors.verticalCenter: itemCell.verticalCenter;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: actionButton.width + 3;
|
||||
width: 32;
|
||||
height: 32;
|
||||
onClicked: {
|
||||
Users[styleData.role](model.sessionId, Users.BAN_BY_USERNAME | Users.BAN_BY_FINGERPRINT | Users.BAN_BY_IP);
|
||||
UserActivityLogger["palAction"](styleData.role, model.sessionId);
|
||||
if (styleData.role === "kick") {
|
||||
nearbyUserModelData.splice(model.userIndex, 1);
|
||||
nearbyUserModel.remove(model.userIndex); // after changing nearbyUserModelData, b/c ListModel can frob the data
|
||||
}
|
||||
}
|
||||
// muted/error glyphs
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.alert;
|
||||
// Size
|
||||
size: parent.height * 1.3;
|
||||
// Anchors
|
||||
anchors.fill: parent;
|
||||
// Style
|
||||
|
@ -720,7 +755,8 @@ Rectangle {
|
|||
onClicked: letterbox(hifi.glyphs.question,
|
||||
"Admin Actions",
|
||||
"<b>Silence</b> mutes a user's microphone. Silenced users can unmute themselves by clicking "UNMUTE" on their toolbar.<br><br>" +
|
||||
"<b>Ban</b> removes a user from this domain and prevents them from returning. Admins can un-ban users from the Sandbox Domain Settings page.");
|
||||
"<b>Ban (left)</b> identifies a user by username (if applicable) and machine fingerprint, then removes them from this domain and prevents them from returning. Admins can un-ban users from the Server Domain Settings page.<br><br>" +
|
||||
"<b>Hard Ban (right)</b> identifies a user by username (if applicable), machine fingerprint, and IP address, then removes them from this domain and prevents them from returning. Admins can un-ban users from the Server Domain Settings page.");
|
||||
onEntered: adminHelpText.color = "#94132e";
|
||||
onExited: adminHelpText.color = hifi.colors.redHighlight;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import stylesUit 1.0
|
||||
import controlsUit 1.0 as HifiControlsUit
|
||||
|
@ -104,6 +105,11 @@ Rectangle {
|
|||
AudioScriptingInterface.setSystemInjectorGain(sliderValue);
|
||||
}
|
||||
}
|
||||
function updateNoiseReductionThresholdFromQML(sliderValue) {
|
||||
if (AudioScriptingInterface.getNoiseReductionThreshold() !== sliderValue) {
|
||||
AudioScriptingInterface.setNoiseReductionThreshold(sliderValue);
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
enablePeakValues();
|
||||
|
@ -164,7 +170,7 @@ Rectangle {
|
|||
x: 2 * margins.paddings;
|
||||
width: parent.width;
|
||||
// switch heights + 2 * top margins
|
||||
height: (root.switchHeight) * 6 + 48;
|
||||
height: (bar.currentIndex === 0) ? (root.switchHeight) * 2 + 48 : (root.switchHeight) * 4 + 48;
|
||||
anchors.top: firstSeparator.bottom;
|
||||
anchors.topMargin: 10;
|
||||
|
||||
|
@ -175,6 +181,7 @@ Rectangle {
|
|||
height: parent.height;
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left;
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: muteMic;
|
||||
height: root.switchHeight;
|
||||
|
@ -193,45 +200,11 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: noiseReductionSwitch;
|
||||
height: root.switchHeight;
|
||||
switchWidth: root.switchWidth;
|
||||
anchors.top: muteMic.bottom;
|
||||
anchors.topMargin: 24
|
||||
anchors.left: parent.left
|
||||
labelTextOn: "Noise Reduction";
|
||||
labelTextSize: 16;
|
||||
backgroundOnColor: "#E3E3E3";
|
||||
checked: AudioScriptingInterface.noiseReduction;
|
||||
onCheckedChanged: {
|
||||
AudioScriptingInterface.noiseReduction = checked;
|
||||
checked = Qt.binding(function() { return AudioScriptingInterface.noiseReduction; }); // restore binding
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: acousticEchoCancellationSwitch;
|
||||
height: root.switchHeight;
|
||||
switchWidth: root.switchWidth;
|
||||
anchors.top: noiseReductionSwitch.bottom
|
||||
anchors.topMargin: 24
|
||||
anchors.left: parent.left
|
||||
labelTextOn: "Echo Cancellation";
|
||||
labelTextSize: 16;
|
||||
backgroundOnColor: "#E3E3E3";
|
||||
checked: AudioScriptingInterface.acousticEchoCancellation;
|
||||
onCheckedChanged: {
|
||||
AudioScriptingInterface.acousticEchoCancellation = checked;
|
||||
checked = Qt.binding(function() { return AudioScriptingInterface.acousticEchoCancellation; });
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: pttSwitch
|
||||
height: root.switchHeight;
|
||||
switchWidth: root.switchWidth;
|
||||
anchors.top: acousticEchoCancellationSwitch.bottom;
|
||||
anchors.top: muteMic.bottom;
|
||||
anchors.topMargin: 24
|
||||
anchors.left: parent.left
|
||||
labelTextOn: (bar.currentIndex === 0) ? qsTr("Push To Talk (T)") : qsTr("Push To Talk");
|
||||
|
@ -254,6 +227,7 @@ Rectangle {
|
|||
height: parent.height;
|
||||
anchors.top: parent.top
|
||||
anchors.left: switchContainer.right;
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: warnMutedSwitch
|
||||
height: root.switchHeight;
|
||||
|
@ -271,7 +245,6 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: audioLevelSwitch
|
||||
height: root.switchHeight;
|
||||
|
@ -519,13 +492,282 @@ Rectangle {
|
|||
anchors.top: systemInjectorGainContainer.bottom;
|
||||
anchors.topMargin: 10;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: noiseReductionHeader
|
||||
x: margins.paddings;
|
||||
width: parent.width - margins.paddings * 2;
|
||||
height: 36;
|
||||
anchors.top: secondSeparator.bottom;
|
||||
anchors.topMargin: 10;
|
||||
|
||||
HiFiGlyphs {
|
||||
width: margins.sizeCheckBox;
|
||||
text: hifi.glyphs.mic;
|
||||
color: hifi.colors.white;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: -size / 4; // The glyph has empty space at left about 25%
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
size: 30;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
width: margins.sizeText + margins.sizeLevel;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: margins.sizeCheckBox;
|
||||
size: 22;
|
||||
color: hifi.colors.white;
|
||||
text: qsTr("Noise Reduction");
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: noiseReductionSwitches;
|
||||
x: 2 * margins.paddings;
|
||||
width: parent.width;
|
||||
// switch heights + 2 * top margins
|
||||
height: (root.switchHeight) * 5 + 48;
|
||||
anchors.top: noiseReductionHeader.bottom;
|
||||
anchors.topMargin: 0;
|
||||
|
||||
Item {
|
||||
id: noiseReductionSwitchContainer;
|
||||
x: margins.paddings;
|
||||
width: parent.width / 2;
|
||||
height: parent.height;
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: acousticEchoCancellationSwitch;
|
||||
height: root.switchHeight;
|
||||
switchWidth: root.switchWidth;
|
||||
anchors.top: noiseReductionSwitchContainer.top
|
||||
anchors.topMargin: 24
|
||||
anchors.left: parent.left
|
||||
labelTextOn: "Echo Cancellation";
|
||||
labelTextSize: 16;
|
||||
backgroundOnColor: "#E3E3E3";
|
||||
checked: AudioScriptingInterface.acousticEchoCancellation;
|
||||
onCheckedChanged: {
|
||||
AudioScriptingInterface.acousticEchoCancellation = checked;
|
||||
checked = Qt.binding(function () { return AudioScriptingInterface.acousticEchoCancellation; });
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: noiseReductionSwitch;
|
||||
height: root.switchHeight;
|
||||
switchWidth: root.switchWidth;
|
||||
anchors.top: acousticEchoCancellationSwitch.bottom;
|
||||
anchors.topMargin: 24
|
||||
anchors.left: parent.left
|
||||
labelTextOn: "Noise Reduction";
|
||||
labelTextSize: 16;
|
||||
backgroundOnColor: "#E3E3E3";
|
||||
checked: AudioScriptingInterface.noiseReduction;
|
||||
onCheckedChanged: {
|
||||
AudioScriptingInterface.noiseReduction = checked;
|
||||
checked = Qt.binding(function () { return AudioScriptingInterface.noiseReduction; }); // restore binding
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Switch {
|
||||
id: noiseReductionAutomaticSwitch;
|
||||
height: root.switchHeight;
|
||||
switchWidth: root.switchWidth;
|
||||
anchors.top: noiseReductionSwitch.bottom;
|
||||
anchors.topMargin: 24;
|
||||
anchors.left: parent.left;
|
||||
labelTextOn: "Manual Noise Reduction";
|
||||
labelTextSize: 16;
|
||||
backgroundOnColor: "#E3E3E3";
|
||||
checked: !AudioScriptingInterface.noiseReductionAutomatic;
|
||||
visible: AudioScriptingInterface.noiseReduction;
|
||||
onCheckedChanged: {
|
||||
AudioScriptingInterface.noiseReductionAutomatic = !checked;
|
||||
checked = Qt.binding(function () { return !AudioScriptingInterface.noiseReductionAutomatic; }); // restore binding
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: noiseReductionThresholdContainer
|
||||
x: margins.paddings;
|
||||
anchors.top: noiseReductionSwitches.bottom;
|
||||
anchors.topMargin: 16;
|
||||
width: parent.width - margins.paddings * 2;
|
||||
height: avatarGainSliderTextMetrics.height + 10;
|
||||
visible: AudioScriptingInterface.noiseReduction && !AudioScriptingInterface.noiseReductionAutomatic;
|
||||
|
||||
HifiControlsUit.Slider {
|
||||
id: noiseReductionThresholdSlider
|
||||
anchors.right: parent.right
|
||||
height: noiseReductionThresholdSliderTextMetrics.height
|
||||
width: 200
|
||||
minimumValue: 0.0
|
||||
maximumValue: 1.0
|
||||
stepSize: 0.05
|
||||
value: AudioScriptingInterface.getNoiseReductionThreshold()
|
||||
onValueChanged: {
|
||||
updateNoiseReductionThresholdFromQML(value);
|
||||
}
|
||||
onPressedChanged: {
|
||||
if (!pressed) {
|
||||
updateNoiseReductionThresholdFromQML(value);
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onWheel: {
|
||||
// Do nothing.
|
||||
}
|
||||
onDoubleClicked: {
|
||||
noiseReductionThresholdSlider.value = 0.0;
|
||||
}
|
||||
onPressed: {
|
||||
// Pass through to Slider
|
||||
mouse.accepted = false;
|
||||
}
|
||||
onReleased: {
|
||||
// the above mouse.accepted seems to make this
|
||||
// never get called, nonetheless...
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
TextMetrics {
|
||||
id: noiseReductionThresholdSliderTextMetrics
|
||||
text: noiseReductionThresholdSliderText.text
|
||||
font: noiseReductionThresholdSliderText.font
|
||||
}
|
||||
RalewayRegular {
|
||||
// The slider for my card is special, it controls the master gain
|
||||
id: noiseReductionThresholdSliderText;
|
||||
text: "Audio input threshold";
|
||||
size: 16;
|
||||
anchors.left: parent.left;
|
||||
color: hifi.colors.white;
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: noisePeak
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 5;
|
||||
anchors.top: noiseReductionThresholdSlider.bottom;
|
||||
|
||||
width: noiseReductionThresholdSlider.width - 10;
|
||||
height: 8;
|
||||
|
||||
Text {
|
||||
id: status;
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
}
|
||||
|
||||
visible: AudioScriptingInterface.muted;
|
||||
color: "#E2334D";
|
||||
|
||||
text: "MUTED";
|
||||
font.pointSize: 10;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: noiseBar;
|
||||
|
||||
property bool gated: false;
|
||||
property var level: AudioScriptingInterface.inputLevel;
|
||||
|
||||
width: parent.width;
|
||||
height: parent.height;
|
||||
|
||||
anchors { fill: parent }
|
||||
|
||||
visible: !status.visible;
|
||||
|
||||
function onNoiseGateOpened() {
|
||||
noiseBar.gated = false;
|
||||
}
|
||||
|
||||
function onNoiseGateClosed() {
|
||||
noiseBar.gated = true;
|
||||
}
|
||||
|
||||
function onInputLevelChanged(level) {
|
||||
noiseBar.level = level;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
AudioScriptingInterface.noiseGateOpened.connect(onNoiseGateOpened);
|
||||
AudioScriptingInterface.noiseGateClosed.connect(onNoiseGateClosed);
|
||||
AudioScriptingInterface.inputLevelChanged.connect(onInputLevelChanged);
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
AudioScriptingInterface.noiseGateOpened.disconnect(onNoiseGateOpened);
|
||||
AudioScriptingInterface.noiseGateClosed.disconnect(onNoiseGateClosed);
|
||||
AudioScriptingInterface.inputLevelChanged.disconnect(onInputLevelChanged);
|
||||
}
|
||||
|
||||
Rectangle { // base
|
||||
radius: 4;
|
||||
anchors { fill: parent }
|
||||
color: colors.gutter;
|
||||
}
|
||||
|
||||
Rectangle { // noiseMask
|
||||
id: noiseMask;
|
||||
width: parent.width * noiseBar.level;
|
||||
radius: 5;
|
||||
anchors {
|
||||
bottom: parent.bottom;
|
||||
bottomMargin: 0;
|
||||
top: parent.top;
|
||||
topMargin: 0;
|
||||
left: parent.left;
|
||||
leftMargin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
LinearGradient {
|
||||
anchors { fill: noiseMask }
|
||||
source: noiseMask
|
||||
start: Qt.point(0, 0);
|
||||
end: Qt.point(noiseBar.width, 0);
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0;
|
||||
color: noiseBar.gated ? "#E2334D" : "#39A38F";
|
||||
}
|
||||
GradientStop {
|
||||
position: 1;
|
||||
color: noiseBar.gated ? "#E2334D" : "#39A38F";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator {
|
||||
id: thirdSeparator;
|
||||
anchors.top: noiseReductionThresholdContainer.bottom;
|
||||
anchors.topMargin: 14;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: inputDeviceHeader
|
||||
x: margins.paddings;
|
||||
width: parent.width - margins.paddings*2;
|
||||
height: 36;
|
||||
anchors.top: secondSeparator.bottom;
|
||||
anchors.top: thirdSeparator.bottom;
|
||||
anchors.topMargin: 10;
|
||||
|
||||
HiFiGlyphs {
|
||||
|
@ -597,19 +839,19 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
AudioControls.InputPeak {
|
||||
id: inputLevel
|
||||
anchors.right: parent.right
|
||||
peak: model.peak;
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: ((bar.currentIndex === 1 && isVR) ||
|
||||
(bar.currentIndex === 0 && !isVR)) &&
|
||||
AudioScriptingInterface.devices.input.peakValuesAvailable;
|
||||
id: inputLevel
|
||||
anchors.right: parent.right
|
||||
peak: model.peak;
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: ((bar.currentIndex === 1 && isVR) ||
|
||||
(bar.currentIndex === 0 && !isVR)) &&
|
||||
AudioScriptingInterface.devices.input.peakValuesAvailable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator {
|
||||
id: thirdSeparator;
|
||||
id: fourthSeparator;
|
||||
anchors.top: inputView.bottom;
|
||||
anchors.topMargin: 10;
|
||||
}
|
||||
|
@ -617,7 +859,7 @@ Rectangle {
|
|||
Item {
|
||||
id: outputDeviceHeader;
|
||||
anchors.topMargin: 10;
|
||||
anchors.top: thirdSeparator.bottom;
|
||||
anchors.top: fourthSeparator.bottom;
|
||||
x: margins.paddings;
|
||||
width: parent.width - margins.paddings*2
|
||||
height: 36
|
||||
|
@ -684,4 +926,4 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 won’t 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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.
|
||||
|
|
BIN
interface/resources/serverless/Models/Planter.glb
Normal file
BIN
interface/resources/serverless/Models/Planter.glb
Normal file
Binary file not shown.
BIN
interface/resources/serverless/Models/Stands.fbx
Normal file
BIN
interface/resources/serverless/Models/Stands.fbx
Normal file
Binary file not shown.
BIN
interface/resources/serverless/Models/Trees1.glb
Normal file
BIN
interface/resources/serverless/Models/Trees1.glb
Normal file
Binary file not shown.
BIN
interface/resources/serverless/Models/VircadiaLogo.fbx
Normal file
BIN
interface/resources/serverless/Models/VircadiaLogo.fbx
Normal file
Binary file not shown.
BIN
interface/resources/serverless/Models/bowl2.fbx
Normal file
BIN
interface/resources/serverless/Models/bowl2.fbx
Normal file
Binary file not shown.
BIN
interface/resources/serverless/Models/dome2.glb
Normal file
BIN
interface/resources/serverless/Models/dome2.glb
Normal file
Binary file not shown.
BIN
interface/resources/serverless/Models/dome2_glass.glb
Normal file
BIN
interface/resources/serverless/Models/dome2_glass.glb
Normal file
Binary file not shown.
Binary file not shown.
BIN
interface/resources/serverless/Models/seagull-ANI.fbx
Normal file
BIN
interface/resources/serverless/Models/seagull-ANI.fbx
Normal file
Binary file not shown.
BIN
interface/resources/serverless/Models/temple5.glb
Normal file
BIN
interface/resources/serverless/Models/temple5.glb
Normal file
Binary file not shown.
59
interface/resources/serverless/Scripts/materialSequencer.js
Normal file
59
interface/resources/serverless/Scripts/materialSequencer.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
// 2020 Silverfish.
|
||||
//material sequencer, put on a material entity (server script) to make it iterate through discrete steps of X UV offset.
|
||||
|
||||
/*UserData:
|
||||
{
|
||||
"verticalOffset": 0,
|
||||
"segments": 16,
|
||||
"updateInterval": 250
|
||||
}
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var DEFAULT_VERTICAL_OFFSET = 0.0;
|
||||
var DEFAULT_HORIZONTAL_SPEED = 1;
|
||||
var DEFAULT_UPDATE_INTERVAL = 1000;
|
||||
var DEFAULT_SEGMENTS = 16;
|
||||
|
||||
var self = this;
|
||||
var _entityID;
|
||||
this.preload = function(entityID) {
|
||||
_entityID = entityID;
|
||||
var verticalOffset = DEFAULT_VERTICAL_OFFSET;
|
||||
var updateInterval = DEFAULT_UPDATE_INTERVAL;
|
||||
var moveDistance = 1 / DEFAULT_SEGMENTS;
|
||||
var verticalOffset = DEFAULT_VERTICAL_OFFSET;
|
||||
var oldPosition = 0;
|
||||
var currentPosition = 0;
|
||||
var userData = JSON.parse(Entities.getEntityProperties(_entityID, ["userData"]).userData);
|
||||
if (userData !== undefined) {
|
||||
if (userData.segments !== undefined) {
|
||||
moveDistance = 1 / userData.segments;
|
||||
}
|
||||
if (userData.verticalOffset !== undefined) {
|
||||
verticalOffset = userData.verticalOffset;
|
||||
}
|
||||
if (userData.updateInterval !== undefined) {
|
||||
updateInterval = userData.updateInterval;
|
||||
}
|
||||
}
|
||||
|
||||
self.intervalID = Script.setInterval(function() {
|
||||
if(currentPosition >= 1){
|
||||
currentPosition = 0;
|
||||
oldPosition = 0;
|
||||
}
|
||||
|
||||
Entities.editEntity(_entityID, { materialMappingPos: { x: currentPosition, y: verticalOffset}});
|
||||
// print("current Pos: " + currentPosition);
|
||||
currentPosition = oldPosition + moveDistance;
|
||||
oldPosition = currentPosition;
|
||||
}, updateInterval);
|
||||
};
|
||||
|
||||
this.unload = function() {
|
||||
Script.clearInterval(self.intervalID);
|
||||
}
|
||||
});
|
182
interface/resources/serverless/Scripts/mirrorClient.js
Normal file
182
interface/resources/serverless/Scripts/mirrorClient.js
Normal file
|
@ -0,0 +1,182 @@
|
|||
//
|
||||
// mirrorClient.js
|
||||
//
|
||||
// Created by Patrick Manalich
|
||||
// Edited by Rebecca Stankus on 8/30/17.
|
||||
// Edited by David Back on 11/17/17.
|
||||
// Edited by Anna Brewer on 7/12/19.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
// Attach `mirrorClient.js` to a box entity whose z dimension is very small,
|
||||
// and whose x and y dimensions are up to you. See comments in `mirrorReflection.js`
|
||||
// for more information about the mirror on/off zone.
|
||||
|
||||
"use strict";
|
||||
|
||||
(function () { // BEGIN LOCAL SCOPE
|
||||
|
||||
// VARIABLES
|
||||
/* globals utils, Render */
|
||||
var _this = this;
|
||||
var MAX_MIRROR_RESOLUTION_SIDE_PX = 960; // The max pixel resolution of the long side of the mirror
|
||||
var ZERO_ROT = { w: 1, x: 0, y: 0, z: 0 }; // Constant quaternion for a rotation of 0
|
||||
var FAR_CLIP_DISTANCE = 16; // The far clip distance for the spectator camera when the mirror is on
|
||||
var mirrorLocalEntityID = false; // The entity ID of the local entity that displays the mirror reflection
|
||||
var mirrorLocalEntityRunning; // True if mirror local entity is reflecting, false otherwise
|
||||
var mirrorLocalEntityOffset = 0.01; // The distance between the center of the mirror and the mirror local entity
|
||||
var spectatorCameraConfig = Render.getConfig("SecondaryCamera"); // Render configuration for the spectator camera
|
||||
var lastDimensions = { x: 0, y: 0 }; // The previous dimensions of the mirror
|
||||
var previousFarClipDistance; // Store the specator camera's previous far clip distance that we override for the mirror
|
||||
|
||||
// LOCAL FUNCTIONS
|
||||
function isPositionInsideBox(position, boxProperties) {
|
||||
var localPosition = Vec3.multiplyQbyV(Quat.inverse(boxProperties.rotation),
|
||||
Vec3.subtract(MyAvatar.position, boxProperties.position));
|
||||
var halfDimensions = Vec3.multiply(boxProperties.dimensions, 0.5);
|
||||
return -halfDimensions.x <= localPosition.x &&
|
||||
halfDimensions.x >= localPosition.x &&
|
||||
-halfDimensions.y <= localPosition.y &&
|
||||
halfDimensions.y >= localPosition.y &&
|
||||
-halfDimensions.z <= localPosition.z &&
|
||||
halfDimensions.z >= localPosition.z;
|
||||
}
|
||||
|
||||
// When x or y dimensions of the mirror change - reset the resolution of the
|
||||
// spectator camera and edit the mirror local entity to adjust for the new dimensions
|
||||
function updateMirrorDimensions(forceUpdate) {
|
||||
|
||||
if (!mirrorLocalEntityID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mirrorLocalEntityRunning) {
|
||||
var newDimensions = Entities.getEntityProperties(_this.entityID, 'dimensions').dimensions;
|
||||
|
||||
if (forceUpdate === true || (newDimensions.x != lastDimensions.x || newDimensions.y != lastDimensions.y)) {
|
||||
var mirrorResolution = _this.calculateMirrorResolution(newDimensions);
|
||||
spectatorCameraConfig.resetSizeSpectatorCamera(mirrorResolution.x, mirrorResolution.y);
|
||||
Entities.editEntity(mirrorLocalEntityID, {
|
||||
dimensions: {
|
||||
x: (Math.max(newDimensions.x, newDimensions.y)),
|
||||
y: (Math.max(newDimensions.x, newDimensions.y)),
|
||||
z: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
lastDimensions = newDimensions;
|
||||
}
|
||||
}
|
||||
|
||||
// Takes in an mirror scalar number which is used for the index of "halfDimSigns" that is needed to adjust the mirror
|
||||
// local entity's position. Deletes and re-adds the mirror local entity so the url and position are updated.
|
||||
function createMirrorLocalEntity() {
|
||||
|
||||
if (mirrorLocalEntityID) {
|
||||
Entities.deleteEntity(mirrorLocalEntityID);
|
||||
mirrorLocalEntityID = false;
|
||||
}
|
||||
|
||||
if (mirrorLocalEntityRunning) {
|
||||
mirrorLocalEntityID = Entities.addEntity({
|
||||
type: "Image",
|
||||
name: "mirrorLocalEntity",
|
||||
imageURL: "resource://spectatorCameraFrame",
|
||||
emissive: true,
|
||||
parentID: _this.entityID,
|
||||
alpha: 1,
|
||||
localPosition: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: mirrorLocalEntityOffset
|
||||
},
|
||||
localRotation: Quat.fromPitchYawRollDegrees(0, 0, 180),
|
||||
isVisibleInSecondaryCamera: false
|
||||
}, "local");
|
||||
|
||||
updateMirrorDimensions(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_this.calculateMirrorResolution = function(entityDimensions) {
|
||||
var mirrorResolutionX, mirrorResolutionY;
|
||||
if (entityDimensions.x > entityDimensions.y) {
|
||||
mirrorResolutionX = MAX_MIRROR_RESOLUTION_SIDE_PX;
|
||||
mirrorResolutionY = Math.round(mirrorResolutionX * entityDimensions.y / entityDimensions.x);
|
||||
} else {
|
||||
mirrorResolutionY = MAX_MIRROR_RESOLUTION_SIDE_PX;
|
||||
mirrorResolutionX = Math.round(mirrorResolutionY * entityDimensions.x / entityDimensions.y);
|
||||
}
|
||||
|
||||
var resolution = {
|
||||
"x": mirrorResolutionX,
|
||||
"y": mirrorResolutionY
|
||||
};
|
||||
|
||||
return resolution;
|
||||
};
|
||||
|
||||
// Sets up spectator camera to render the mirror, calls 'createMirrorLocalEntity' once to set up
|
||||
// mirror local entity, then connects 'updateMirrorDimensions' to update dimension changes
|
||||
_this.mirrorLocalEntityOn = function(onPreload) {
|
||||
if (!mirrorLocalEntityRunning) {
|
||||
if (!spectatorCameraConfig.attachedEntityId) {
|
||||
mirrorLocalEntityRunning = true;
|
||||
spectatorCameraConfig.mirrorProjection = true;
|
||||
spectatorCameraConfig.attachedEntityId = _this.entityID;
|
||||
previousFarClipDistance = spectatorCameraConfig.farClipPlaneDistance;
|
||||
spectatorCameraConfig.farClipPlaneDistance = FAR_CLIP_DISTANCE;
|
||||
var entityProperties = Entities.getEntityProperties(_this.entityID, ['dimensions']);
|
||||
var mirrorEntityDimensions = entityProperties.dimensions;
|
||||
var initialResolution = _this.calculateMirrorResolution(mirrorEntityDimensions);
|
||||
spectatorCameraConfig.resetSizeSpectatorCamera(initialResolution.x, initialResolution.y);
|
||||
spectatorCameraConfig.enableSecondaryCameraRenderConfigs(true);
|
||||
createMirrorLocalEntity();
|
||||
Script.update.connect(updateMirrorDimensions);
|
||||
} else {
|
||||
print("Cannot turn on mirror if spectator camera is already in use");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Resets spectator camera, deletes the mirror local entity, and disconnects 'updateMirrorDimensions'
|
||||
_this.mirrorLocalEntityOff = function() {
|
||||
if (mirrorLocalEntityRunning) {
|
||||
spectatorCameraConfig.enableSecondaryCameraRenderConfigs(false);
|
||||
spectatorCameraConfig.mirrorProjection = false;
|
||||
spectatorCameraConfig.attachedEntityId = null;
|
||||
spectatorCameraConfig.farClipPlaneDistance = previousFarClipDistance;
|
||||
if (mirrorLocalEntityID) {
|
||||
Entities.deleteEntity(mirrorLocalEntityID);
|
||||
mirrorLocalEntityID = false;
|
||||
}
|
||||
Script.update.disconnect(updateMirrorDimensions);
|
||||
mirrorLocalEntityRunning = false;
|
||||
}
|
||||
};
|
||||
|
||||
// ENTITY FUNCTIONS
|
||||
_this.preload = function(entityID) {
|
||||
_this.entityID = entityID;
|
||||
mirrorlocalEntityRunning = false;
|
||||
|
||||
// If avatar is already inside the mirror zone at the time preload is called then turn on the mirror
|
||||
var children = Entities.getChildrenIDs(_this.entityID);
|
||||
var childZero = Entities.getEntityProperties(children[0]);
|
||||
if (isPositionInsideBox(MyAvatar.position, {
|
||||
position: childZero.position,
|
||||
rotation: childZero.rotation,
|
||||
dimensions: childZero.dimensions
|
||||
})) {
|
||||
_this.mirrorLocalEntityOn(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Turn off mirror on unload
|
||||
_this.unload = function(entityID) {
|
||||
_this.mirrorLocalEntityOff();
|
||||
};
|
||||
});
|
32
interface/resources/serverless/Scripts/mirrorReflection.js
Normal file
32
interface/resources/serverless/Scripts/mirrorReflection.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// mirrorReflection.js
|
||||
//
|
||||
// Created by Rebecca Stankus on 8/30/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
// Attach `mirrorReflection.js` to a zone entity that is parented to
|
||||
// the box entity whose Script is `mirrorClient.js`.
|
||||
// When a user enters this zone, the mirror will turn on.
|
||||
// When a user leaves this zone, the mirror will turn off.
|
||||
|
||||
(function () {
|
||||
var mirrorID, reflectionAreaID;
|
||||
// get id of reflection area and mirror
|
||||
this.preload = function(entityID) {
|
||||
reflectionAreaID = entityID;
|
||||
mirrorID = Entities.getEntityProperties(reflectionAreaID, 'parentID').parentID;
|
||||
};
|
||||
|
||||
// when avatar enters reflection area, begin reflecting
|
||||
this.enterEntity = function(entityID){
|
||||
Entities.callEntityMethod(mirrorID, 'mirrorLocalEntityOn');
|
||||
};
|
||||
|
||||
// when avatar leaves reflection area, stop reflecting
|
||||
this.leaveEntity = function (entityID) {
|
||||
Entities.callEntityMethod(mirrorID, 'mirrorLocalEntityOff');
|
||||
};
|
||||
});
|
47
interface/resources/serverless/Scripts/portal.js
Normal file
47
interface/resources/serverless/Scripts/portal.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// portal.js
|
||||
// Created by Zach Fox on 2019-05-23
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
(function () {
|
||||
var Portal = function() {};
|
||||
|
||||
|
||||
Portal.prototype = {
|
||||
enterEntity: function (id) {
|
||||
var properties = Entities.getEntityProperties(id, ["userData"]);
|
||||
var userData;
|
||||
|
||||
try {
|
||||
userData = JSON.parse(properties.userData);
|
||||
} catch (e) {
|
||||
console.error("Error parsing userData: ", e);
|
||||
}
|
||||
|
||||
if (userData) {
|
||||
if (userData.destination) {
|
||||
var destination = userData.destination;
|
||||
|
||||
if (userData.destination.indexOf("bookmark:") > -1) {
|
||||
var bookmarkName = userData.destination.replace("bookmark:", "");
|
||||
destination = LocationBookmarks.getAddress(bookmarkName);
|
||||
}
|
||||
|
||||
Window.location = destination;
|
||||
} else {
|
||||
console.log("Please specify `destination` inside this entity's `userData`!");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
console.log("Please specify this entity's `userData`! See README.md for instructions.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return new Portal();
|
||||
});
|
202
interface/resources/serverless/Scripts/soundEmitter.js
Normal file
202
interface/resources/serverless/Scripts/soundEmitter.js
Normal file
|
@ -0,0 +1,202 @@
|
|||
/* eslint-disable no-magic-numbers */
|
||||
//
|
||||
// soundEmitter.js
|
||||
//
|
||||
// Created by Zach Fox on 2019-07-05
|
||||
// Copyright High Fidelity 2019
|
||||
//
|
||||
// Licensed under the Apache 2.0 License
|
||||
// See accompanying license file or http://apache.org/
|
||||
//
|
||||
|
||||
(function() {
|
||||
var that;
|
||||
var SOUND_EMITTER_UPDATE_INTERVAL_MS = 500;
|
||||
var DEFAULT_AUDIO_INJECTOR_OPTIONS = {
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"volume": 0.5,
|
||||
"loop": false,
|
||||
"localOnly": false
|
||||
};
|
||||
|
||||
|
||||
var SoundEmitter = function() {
|
||||
that = this;
|
||||
that.entityID = false;
|
||||
that.soundObjectURL = false;
|
||||
that.soundObject = false;
|
||||
that.audioInjector = false;
|
||||
that.audioInjectorOptions = DEFAULT_AUDIO_INJECTOR_OPTIONS;
|
||||
that.signalsConnected = {};
|
||||
that.soundEmitterUpdateInterval = false;
|
||||
};
|
||||
|
||||
|
||||
SoundEmitter.prototype = {
|
||||
preload: function(entityID) {
|
||||
that.entityID = entityID;
|
||||
|
||||
var properties = Entities.getEntityProperties(that.entityID, ["userData"]);
|
||||
|
||||
var userData;
|
||||
|
||||
try {
|
||||
userData = JSON.parse(properties.userData);
|
||||
} catch (e) {
|
||||
console.error("Error parsing userData: ", e);
|
||||
}
|
||||
|
||||
if (userData) {
|
||||
if (userData.soundURL && userData.soundURL.length > 0) {
|
||||
that.handleNewSoundURL(userData.soundURL);
|
||||
} else {
|
||||
console.log("Please specify this entity's `userData`! See README.md for instructions.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
console.log("Please specify this entity's `userData`! See README.md for instructions.");
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
clearCurrentSoundData: function() {
|
||||
that.soundObjectURL = false;
|
||||
|
||||
if (that.signalsConnected["soundObjectReady"]) {
|
||||
that.soundObject.ready.disconnect(that.updateSoundEmitter);
|
||||
that.signalsConnected["soundObjectReady"] = false;
|
||||
}
|
||||
|
||||
that.soundObject = false;
|
||||
|
||||
if (that.audioInjector) {
|
||||
if (that.audioInjector.playing) {
|
||||
that.audioInjector.stop();
|
||||
}
|
||||
|
||||
that.audioInjector = false;
|
||||
}
|
||||
|
||||
that.audioInjectorOptions = DEFAULT_AUDIO_INJECTOR_OPTIONS;
|
||||
|
||||
if (that.soundEmitterUpdateInterval) {
|
||||
Script.clearInterval(that.soundEmitterUpdateInterval);
|
||||
that.soundEmitterUpdateInterval = false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
unload: function() {
|
||||
that.clearCurrentSoundData();
|
||||
},
|
||||
|
||||
|
||||
handleNewSoundURL: function(newSoundURL) {
|
||||
that.clearCurrentSoundData();
|
||||
|
||||
that.soundObjectURL = newSoundURL;
|
||||
that.soundObject = SoundCache.getSound(that.soundObjectURL);
|
||||
|
||||
if (that.soundObject.downloaded) {
|
||||
that.updateSoundEmitter();
|
||||
} else {
|
||||
that.soundObject.ready.connect(that.updateSoundEmitter);
|
||||
that.signalsConnected["soundObjectReady"] = true;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
positionChanged: function(newPos) {
|
||||
return (newPos.x !== that.audioInjectorOptions.position.x ||
|
||||
newPos.y !== that.audioInjectorOptions.position.y ||
|
||||
newPos.z !== that.audioInjectorOptions.position.z);
|
||||
},
|
||||
|
||||
|
||||
updateSoundEmitter: function() {
|
||||
var properties = Entities.getEntityProperties(that.entityID, ["userData", "position", "script", "serverScripts"]);
|
||||
|
||||
var userData;
|
||||
|
||||
try {
|
||||
userData = JSON.parse(properties.userData);
|
||||
} catch (e) {
|
||||
console.error("Error parsing userData: ", e);
|
||||
}
|
||||
|
||||
var optionsChanged = false;
|
||||
var shouldRestartPlayback = false;
|
||||
var newPosition = properties.position;
|
||||
|
||||
if (userData) {
|
||||
if (userData.soundURL && userData.soundURL.length > 0 && userData.soundURL !== that.soundObjectURL) {
|
||||
console.log("Sound Emitter: User put a new sound URL into `userData`! Resetting...");
|
||||
that.handleNewSoundURL(userData.soundURL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof(userData.volume) !== "undefined" && !isNaN(userData.volume) && userData.volume !== that.audioInjectorOptions.volume) {
|
||||
optionsChanged = true;
|
||||
that.audioInjectorOptions.volume = userData.volume;
|
||||
}
|
||||
|
||||
if (typeof(userData.shouldLoop) !== "undefined" && userData.shouldLoop !== that.audioInjectorOptions.shouldLoop) {
|
||||
optionsChanged = true;
|
||||
|
||||
if (!that.audioInjectorOptions.loop && userData.shouldLoop && that.audioInjector && !that.audioInjector.playing) {
|
||||
shouldRestartPlayback = true;
|
||||
}
|
||||
|
||||
that.audioInjectorOptions.loop = userData.shouldLoop;
|
||||
}
|
||||
|
||||
if (typeof(userData.positionOverride) !== "undefined" && !isNaN(userData.positionOverride.x) &&
|
||||
!isNaN(userData.positionOverride.y) && !isNaN(userData.positionOverride.z)) {
|
||||
newPosition = userData.positionOverride;
|
||||
}
|
||||
} else {
|
||||
console.log("Please specify this entity's `userData`! See README.md for instructions.");
|
||||
that.clearCurrentSoundData();
|
||||
return;
|
||||
}
|
||||
|
||||
var localOnly = that.audioInjectorOptions.localOnly;
|
||||
// If this script is attached as a client entity script...
|
||||
if (properties.script.indexOf("soundEmitter.js") > -1) {
|
||||
// ... Make sure that the audio injector IS local only.
|
||||
localOnly = true;
|
||||
// Else if this script is attached as a client server script...
|
||||
} else if (properties.serverScripts.indexOf("soundEmitter.js") > -1) {
|
||||
// ... Make sure that the audio injector IS NOT local only.
|
||||
localOnly = false;
|
||||
}
|
||||
if (localOnly !== that.audioInjectorOptions.localOnly) {
|
||||
optionsChanged = true;
|
||||
that.audioInjectorOptions.localOnly = localOnly;
|
||||
}
|
||||
|
||||
if (that.positionChanged(newPosition)) {
|
||||
optionsChanged = true;
|
||||
that.audioInjectorOptions["position"] = newPosition;
|
||||
}
|
||||
|
||||
if (!that.audioInjector || shouldRestartPlayback) {
|
||||
that.audioInjector = Audio.playSound(that.soundObject, that.audioInjectorOptions);
|
||||
} else if (optionsChanged) {
|
||||
that.audioInjector.setOptions(that.audioInjectorOptions);
|
||||
}
|
||||
|
||||
if (!that.soundEmitterUpdateInterval) {
|
||||
that.soundEmitterUpdateInterval = Script.setInterval(that.updateSoundEmitter, SOUND_EMITTER_UPDATE_INTERVAL_MS);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return new SoundEmitter();
|
||||
});
|
77
interface/resources/serverless/Scripts/wizardLoader.js
Normal file
77
interface/resources/serverless/Scripts/wizardLoader.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
'use strict';
|
||||
|
||||
//
|
||||
// wizardLoader.js
|
||||
//
|
||||
// Created by Kalila L. on Feb 19 2021.
|
||||
// Copyright 2021 Vircadia contributors.
|
||||
//
|
||||
// This script is used to load the onboarding wizard at the location of the entity it's on.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() {
|
||||
var CONFIG_WIZARD_WEB_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Tutorial/Apps/configWizard/dist/index.html';
|
||||
|
||||
var loaderEntityID;
|
||||
var configWizardEntityID;
|
||||
|
||||
function onWebAppEventReceived(sendingEntityID, event) {
|
||||
if (sendingEntityID === configWizardEntityID) {
|
||||
var eventJSON = JSON.parse(event);
|
||||
|
||||
if (eventJSON.command === 'first-run-wizard-ready') {
|
||||
var objectToSend = {
|
||||
command: 'script-to-web-initialize',
|
||||
data: {
|
||||
performancePreset: Performance.getPerformancePreset(),
|
||||
refreshRateProfile: Performance.getRefreshRateProfile(),
|
||||
displayName: MyAvatar.displayName
|
||||
}
|
||||
};
|
||||
|
||||
Entities.emitScriptEvent(configWizardEntityID, JSON.stringify(objectToSend));
|
||||
}
|
||||
|
||||
if (eventJSON.command === 'complete-wizard') {
|
||||
Performance.setPerformancePreset(eventJSON.data.performancePreset);
|
||||
Performance.setRefreshRateProfile(eventJSON.data.refreshRateProfile);
|
||||
MyAvatar.displayName = eventJSON.data.displayName;
|
||||
|
||||
Entities.deleteEntity(configWizardEntityID);
|
||||
Entities.webEventReceived.disconnect(onWebAppEventReceived);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.preload = function (entityID) {
|
||||
loaderEntityID = entityID;
|
||||
var loaderEntityProps = Entities.getEntityProperties(loaderEntityID, ['position', 'rotation']);
|
||||
|
||||
configWizardEntityID = Entities.addEntity({
|
||||
type: 'Web',
|
||||
sourceUrl: CONFIG_WIZARD_WEB_URL,
|
||||
maxFPS: 60,
|
||||
dpi: 20,
|
||||
useBackground: false,
|
||||
grab: {
|
||||
grabbable: false
|
||||
},
|
||||
position: loaderEntityProps.position,
|
||||
rotation: loaderEntityProps.rotation,
|
||||
dimensions: { x: 1.4, y: 0.75, z: 0 }
|
||||
}, 'local');
|
||||
|
||||
Entities.webEventReceived.connect(onWebAppEventReceived);
|
||||
}
|
||||
|
||||
this.unload = function () {
|
||||
if (configWizardEntityID) {
|
||||
Entities.deleteEntity(configWizardEntityID);
|
||||
Entities.webEventReceived.disconnect(onWebAppEventReceived);
|
||||
}
|
||||
}
|
||||
|
||||
})
|
Binary file not shown.
BIN
interface/resources/serverless/Textures/default_particle.png
Normal file
BIN
interface/resources/serverless/Textures/default_particle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
BIN
interface/resources/serverless/Textures/galaxySkybox.JPG
Normal file
BIN
interface/resources/serverless/Textures/galaxySkybox.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 870 KiB |
BIN
interface/resources/serverless/Textures/galaxySkybox.png
Normal file
BIN
interface/resources/serverless/Textures/galaxySkybox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 MiB |
BIN
interface/resources/serverless/Textures/gradient1.jpg
Normal file
BIN
interface/resources/serverless/Textures/gradient1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
File diff suppressed because it is too large
Load diff
2204
interface/resources/serverless/tutorialqrc.json
Normal file
2204
interface/resources/serverless/tutorialqrc.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* The <code>About</code> API provides information about the version of Interface that is currently running. It also has the
|
||||
* functionality to open a web page in an Interface browser window.
|
||||
*
|
||||
|
@ -41,7 +41,7 @@
|
|||
* print("Qt version: " + About.qtVersion);
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* The <code>HifiAbout</code> API provides information about the version of Interface that is currently running. It also
|
||||
* has the functionality to open a web page in an Interface browser window.
|
||||
*
|
||||
|
@ -82,7 +82,7 @@ public:
|
|||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* Display a web page in an Interface browser window or the tablet.
|
||||
* @function About.openUrl
|
||||
* @param {string} url - The URL of the web page you want to view in Interface.
|
||||
|
|
|
@ -658,7 +658,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
/**jsdoc
|
||||
/*@jsdoc
|
||||
* <p>The <code>Controller.Hardware.Application</code> object has properties representing Interface's state. The property
|
||||
* values are integer IDs, uniquely identifying each output. <em>Read-only.</em></p>
|
||||
* <p>These states can be mapped to actions or functions or <code>Controller.Standard</code> items in a {@link RouteObject}
|
||||
|
@ -1012,7 +1012,7 @@ const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false;
|
|||
const bool DEFAULT_PREFER_STYLUS_OVER_LASER = false;
|
||||
const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false;
|
||||
const QString DEFAULT_CURSOR_NAME = "DEFAULT";
|
||||
const bool DEFAULT_MINI_TABLET_ENABLED = true;
|
||||
const bool DEFAULT_MINI_TABLET_ENABLED = false;
|
||||
const bool DEFAULT_AWAY_STATE_WHEN_FOCUS_LOST_IN_VR_ENABLED = true;
|
||||
|
||||
QSharedPointer<OffscreenUi> getOffscreenUI() {
|
||||
|
@ -1307,6 +1307,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
_entityServerConnectionTimer.setSingleShot(true);
|
||||
connect(&_entityServerConnectionTimer, &QTimer::timeout, this, &Application::setFailedToConnectToEntityServer);
|
||||
|
||||
connect(&domainHandler, &DomainHandler::confirmConnectWithoutAvatarEntities,
|
||||
this, &Application::confirmConnectWithoutAvatarEntities);
|
||||
|
||||
connect(&domainHandler, &DomainHandler::connectedToDomain, this, [this]() {
|
||||
if (!isServerlessMode()) {
|
||||
_entityServerConnectionTimer.setInterval(ENTITY_SERVER_ADDED_TIMEOUT);
|
||||
|
@ -1970,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
|
||||
|
@ -2520,7 +2523,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
return viewFrustum.getPosition();
|
||||
});
|
||||
|
||||
DependencyManager::get<UsersScriptingInterface>()->setKickConfirmationOperator([this] (const QUuid& nodeID) { userKickConfirmation(nodeID); });
|
||||
DependencyManager::get<UsersScriptingInterface>()->setKickConfirmationOperator([this] (const QUuid& nodeID, unsigned int banFlags) { userKickConfirmation(nodeID, banFlags); });
|
||||
|
||||
render::entities::WebEntityRenderer::setAcquireWebSurfaceOperator([=](const QString& url, bool htmlContent, QSharedPointer<OffscreenQmlSurface>& webSurface, bool& cachedWebSurface) {
|
||||
bool isTablet = url == TabletScriptingInterface::QML;
|
||||
|
@ -2648,7 +2651,7 @@ void Application::setCachebustRequire() {
|
|||
return;
|
||||
}
|
||||
bool enable = menu->isOptionChecked(MenuOption::CachebustRequire);
|
||||
|
||||
|
||||
Setting::Handle<bool>{ CACHEBUST_SCRIPT_REQUIRE_SETTING_NAME, false }.set(enable);
|
||||
}
|
||||
|
||||
|
@ -3016,6 +3019,8 @@ Application::~Application() {
|
|||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
// 26 Feb 2021 - Tried re-enabling this call but OSX still crashes on exit.
|
||||
//
|
||||
// 10/16/2019 - Disabling this call. This causes known crashes (A), and it is not
|
||||
// fully understood whether it might cause other unknown crashes (B).
|
||||
//
|
||||
|
@ -3268,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 {
|
||||
|
@ -3600,7 +3605,7 @@ void Application::onDesktopRootItemCreated(QQuickItem* rootItem) {
|
|||
_desktopRootItemCreated = true;
|
||||
}
|
||||
|
||||
void Application::userKickConfirmation(const QUuid& nodeID) {
|
||||
void Application::userKickConfirmation(const QUuid& nodeID, unsigned int banFlags) {
|
||||
auto avatarHashMap = DependencyManager::get<AvatarHashMap>();
|
||||
auto avatar = avatarHashMap->getAvatarBySessionID(nodeID);
|
||||
|
||||
|
@ -3625,7 +3630,7 @@ void Application::userKickConfirmation(const QUuid& nodeID) {
|
|||
// ask the NodeList to kick the user with the given session ID
|
||||
|
||||
if (yes) {
|
||||
DependencyManager::get<NodeList>()->kickNodeBySessionID(nodeID);
|
||||
DependencyManager::get<NodeList>()->kickNodeBySessionID(nodeID, banFlags);
|
||||
}
|
||||
|
||||
DependencyManager::get<UsersScriptingInterface>()->setWaitForKickResponse(false);
|
||||
|
@ -4040,11 +4045,11 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
|
|||
|
||||
// If this is a first run we short-circuit the address passed in
|
||||
if (_firstRun.get()) {
|
||||
if (!BuildInfo::INITIAL_STARTUP_LOCATION.isEmpty()) {
|
||||
if (!BuildInfo::PRELOADED_STARTUP_LOCATION.isEmpty()) {
|
||||
DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS);
|
||||
Menu::getInstance()->triggerOption(MenuOption::HomeLocation);
|
||||
}
|
||||
|
||||
|
||||
if (!_overrideEntry) {
|
||||
DependencyManager::get<AddressManager>()->goToEntry();
|
||||
sentTo = SENT_TO_ENTRY;
|
||||
|
@ -7220,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;
|
||||
}
|
||||
|
@ -7923,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);
|
||||
|
@ -9199,6 +9204,32 @@ void Application::setShowBulletConstraintLimits(bool value) {
|
|||
_physicsEngine->setShowBulletConstraintLimits(value);
|
||||
}
|
||||
|
||||
void Application::confirmConnectWithoutAvatarEntities() {
|
||||
|
||||
if (_confirmConnectWithoutAvatarEntitiesDialog) {
|
||||
// Dialog is already displayed.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getMyAvatar()->hasAvatarEntities()) {
|
||||
// No avatar entities so continue with login.
|
||||
DependencyManager::get<NodeList>()->getDomainHandler().setCanConnectWithoutAvatarEntities(true);
|
||||
return;
|
||||
}
|
||||
|
||||
QString continueMessage = "Your wearables will not display on this domain. Continue?";
|
||||
_confirmConnectWithoutAvatarEntitiesDialog = OffscreenUi::asyncQuestion("Continue Without Wearables", continueMessage,
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (_confirmConnectWithoutAvatarEntitiesDialog->getDialogItem()) {
|
||||
QObject::connect(_confirmConnectWithoutAvatarEntitiesDialog, &ModalDialogListener::response, this, [=](QVariant answer) {
|
||||
QObject::disconnect(_confirmConnectWithoutAvatarEntitiesDialog, &ModalDialogListener::response, this, nullptr);
|
||||
_confirmConnectWithoutAvatarEntitiesDialog = nullptr;
|
||||
bool shouldConnect = (static_cast<QMessageBox::StandardButton>(answer.toInt()) == QMessageBox::Yes);
|
||||
DependencyManager::get<NodeList>()->getDomainHandler().setCanConnectWithoutAvatarEntities(shouldConnect);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Application::createLoginDialog() {
|
||||
const glm::vec3 LOGIN_DIMENSIONS { 0.89f, 0.5f, 0.01f };
|
||||
const auto OFFSET = glm::vec2(0.7f, -0.1f);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue