Merge remote-tracking branch 'origin/master' into remove-hifiac

This commit is contained in:
ksuprynowicz 2022-01-18 21:29:33 +01:00
commit 4e399edaa7
926 changed files with 29581 additions and 15795 deletions

View file

@ -5,6 +5,7 @@ module.exports = {
"ecmaVersion": 5
},
"globals": {
"About": false,
"Account": false,
"Agent": false,
"AnimationCache": false,

11
.github/stale.yml vendored Normal file
View file

@ -0,0 +1,11 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 180
# Number of days of inactivity before a stale issue is closed
daysUntilClose: false
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
Hello! Is this still an issue?
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View file

@ -6,251 +6,217 @@ on:
- master
env:
#APP_NAME: gpu-frame-player
APP_NAME: interface
BUILD_TYPE: Release
BUCKET_NAME: hifi-gh-builds
BUILD_NUMBER: ${{ github.run_number }}
CI_BUILD: Github
CMAKE_BACKTRACE_URL: https://highfidelity.sp.backtrace.io:6098
CMAKE_BACKTRACE_TOKEN: ${{ secrets.backtrace_token }}
CMAKE_BACKTRACE_SYMBOLS_TOKEN: ${{ secrets.backtrace_symbols_token }}
GIT_COMMIT: ${{ github.sha }}
HIFI_VCPKG_BOOTSTRAP: true
LAUNCHER_HMAC_SECRET: ${{ secrets.launcher_hmac_secret }}
OCULUS_APP_ID: '${{ secrets.oculus_app_id }}'
# VCPKG did not build well on OSX disabling HIFI_VCPKG_BOOTSTRAP, which invokes a download to a working version of vcpkg
# HIFI_VCPKG_BOOTSTRAP: true
RELEASE_TYPE: PRODUCTION
RELEASE_DYNAMODB_V2: ReleaseManager2-ReleaseQueue-prod
RELEASE_NUMBER: ${{ github.run_number }}
STABLE_BUILD: 0
UPLOAD_BUCKET: athena-public
# OSX specific variables
# OSX-specific variables
DEVELOPER_DIR: /Applications/Xcode_11.2.app/Contents/Developer
MACOSX_DEPLOYMENT_TARGET: '10.11'
# WIN32 specific variables
# WIN-specific variables
PreferredToolArchitecture: X64
# Mac OS
#PLATFORM_CMAKE_GENERATOR=Xcode
#PLATFORM_BUILD_ARGUMENTS=--config Release --target package
#ARTIFACT_EXPRESSION=build/*.dmg,build/*.zip
# Windows
#PLATFORM_CMAKE_GENERATOR=Visual Studio 15 2017 Win64
#PLATFORM_BUILD_ARGUMENTS=--target package --config release
#ARTIFACT_EXPRESSION=build/*.exe,build/*.zip,*-symbols.zip
# Ubuntu
#PLATFORM_CMAKE_GENERATOR=Unix Makefiles
#PLATFORM_BUILD_ARGUMENTS=--target all -- -j4
#ARTIFACT_EXPRESSION=build/assignment-client/**,build/domain-server/**,build/ice-server/ice-server,build/tools/ice-client/ice-client,build/tools/ac-client/ac-client,build/tools/oven,build/ext/makefiles/nvtt/project/lib/**,build/ext/makefiles/quazip/project/lib/**
# Android
# branch: master
# GA_TRACKING_ID: ${{ secrets.ga_tracking_id }}
# ANDROID_OAUTH_CLIENT_SECRET=${MASKED_ANDROID_OAUTH_CLIENT_SECRET_NIGHTLY}
# ANDROID_OAUTH_CLIENT_ID=6c7d2349c0614640150db37457a1f75dce98a28ffe8f14d47f6cfae4de5b262a
# ANDROID_OAUTH_REDIRECT_URI=https://dev-android-interface.highfidelity.com/auth
# branch: !master
# GA_TRACKING_ID=UA-39558647-11
# ANDROID_OAUTH_CLIENT_SECRET=${MASKED_ANDROID_OAUTH_CLIENT_SECRET_RELEASE}
# ANDROID_OAUTH_CLIENT_ID= c1063ea5d0b0c405e0c9cd77351328e211a91496a3f25985a99e861f1661db1d
# ANDROID_OAUTH_REDIRECT_URI=https://android-interface.highfidelity.com/auth
# ARTIFACT_EXPRESSION=android/*.apk
# ANDROID_APK_NAME=HighFidelity-Beta-PR${RELEASE_NUMBER}-${GIT_COMMIT_SHORT}.apk
# ANDROID_BUILT_APK_NAME=interface-debug.apk
# ANDROID_APP=interface
# ANDROID_BUILD_DIR=debug
# ANDROID_BUILD_TARGET=assembleDebug
# STABLE_BUILD=0
jobs:
generate_build_number:
runs-on: ubuntu-latest
steps:
- name: Generate build number
id: buildnumber
uses: highfidelity/build-number@v3
with:
token: ${{secrets.github_token}}
- name: Upload build number
uses: actions/upload-artifact@v1
with:
name: BUILD_NUMBER
path: BUILD_NUMBER
build:
strategy:
matrix:
os: [windows-latest, macOS-latest]
build_type: [full, client]
#os: [windows-latest, macOS-latest, ubuntu-latest]
# exclude:
# - os: ubuntu-latest
# build_type: client
os: [windows-latest, macOS-latest, ubuntu-18.04]
# build_type: [full, client]
build_type: [full]
include:
- os: ubuntu-18.04
build_type: full
apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0 libsnappy1v5 libwebpdemux2 libwebpmux3
fail-fast: false
runs-on: ${{matrix.os}}
needs: generate_build_number
steps:
- name: Download build number
uses: actions/download-artifact@v1
with:
name: BUILD_NUMBER
- name: Restore build number
id: buildnumber
uses: highfidelity/build-number@v3
with:
output_name: RELEASE_NUMBER
- name: Configure Build Environment 1
- name: Report Build Number
shell: bash
run: |
echo "Build number: $BUILD_NUMBER"
- name: Configure build environment 1
shell: bash
id: buildenv1
run: |
echo ::set-env name=UPLOAD_PREFIX::master
echo ::set-env name=GIT_COMMIT_SHORT::`echo $GIT_COMMIT | cut -c1-7`
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-latest" ]; then
echo ::set-env name=INSTALLER_EXT::tgz
if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then
echo "PYTHON_EXEC=python3" >> $GITHUB_ENV
echo "INSTALLER_EXT=tgz" >> $GITHUB_ENV
echo "CMAKE_BUILD_EXTRA=-- -j3" >> $GITHUB_ENV
echo "CMAKE_EXTRA=-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" >> $GITHUB_ENV
fi
# Mac build variables
if [ "${{ matrix.os }}" = "macOS-latest" ]; then
echo ::set-env name=PYTHON_EXEC::python3
echo ::set-env name=ZIP_COMMAND::zip
echo ::set-env name=ZIP_ARGS::-r
echo ::set-env name=INSTALLER_EXT::dmg
echo ::set-env name=SYMBOL_REGEX::dSYM
echo "::set-output name=symbols_archive::${{ steps.buildnumber.outputs.build_number }}-${{ matrix.build_type }}-mac-symbols.zip"
echo "PYTHON_EXEC=python3" >> $GITHUB_ENV
echo "ZIP_COMMAND=zip" >> $GITHUB_ENV
echo "ZIP_ARGS=-r" >> $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
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
echo ::set-env name=PYTHON_EXEC::python
echo ::set-env name=ZIP_COMMAND::7z
echo ::set-env name=ZIP_ARGS::a
echo ::set-env name=INSTALLER_EXT::exe
echo "::set-env name=SYMBOL_REGEX::\(exe\|dll\|pdb\)"
echo "::set-output name=symbols_archive::${{ steps.buildnumber.outputs.build_number }}-${{ matrix.build_type }}-win-symbols.zip"
echo "PYTHON_EXEC=python" >> $GITHUB_ENV
echo "ZIP_COMMAND=7z" >> $GITHUB_ENV
echo "ZIP_ARGS=a" >> $GITHUB_ENV
echo "INSTALLER_EXT=exe" >> $GITHUB_ENV
echo "CMAKE_EXTRA=-A x64" >> $GITHUB_ENV
echo "SYMBOL_REGEX=\(exe\|dll\|pdb\)" >> $GITHUB_ENV
echo "symbols_archive=${BUILD_NUMBER}-${{ matrix.build_type }}-win-symbols.zip" >> $GITHUB_ENV
# echo "HF_PFX_PASSPHRASE=${{secrets.pfx_key}}" >> $GITHUB_ENV
# echo "HF_PFX_FILE=${{runner.workspace}}\build\codesign.pfx" >> $GITHUB_ENV
fi
# Configuration is broken into two steps because you can't set an env var and also reference it in the same step
- name: Configure Build Environment 2
- name: Configure build environment 2
shell: bash
run: |
echo "${{ steps.buildenv1.outputs.symbols_archive }}"
echo ::set-env name=ARTIFACT_PATTERN::HighFidelity-Beta-*.$INSTALLER_EXT
echo "ARTIFACT_PATTERN=Vircadia-*.$INSTALLER_EXT" >> $GITHUB_ENV
# Build type variables
echo "GIT_COMMIT_SHORT=${{ steps.buildenv1.outputs.github_sha_short }}" >> $GITHUB_ENV
if [ "${{ matrix.build_type }}" = "full" ]; then
echo ::set-env name=CLIENT_ONLY::FALSE
echo ::set-env name=INSTALLER::HighFidelity-Beta-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT
echo "CLIENT_ONLY=FALSE" >> $GITHUB_ENV
echo "INSTALLER=Vircadia-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV
else
echo ::set-env name=CLIENT_ONLY::TRUE
echo ::set-env name=INSTALLER::HighFidelity-Beta-Interface-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT
echo "CLIENT_ONLY=TRUE" >> $GITHUB_ENV
echo "INSTALLER=Vircadia-Interface-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT" >> $GITHUB_ENV
fi
# Linux build variables
if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then
echo ::set-env name=PYTHON_EXEC::python3
echo ::set-env name=CMAKE_EXTRA::""
fi
# Mac build variables
if [ "${{ matrix.os }}" = "macOS-latest" ]; then
echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode"
fi
# Windows build variables
if [ "${{ matrix.os }}" = "windows-latest" ]; then
echo ::set-env name=CMAKE_EXTRA::"-A x64"
echo ::set-env name=HF_PFX_PASSPHRASE::${{secrets.pfx_key}}
echo "::set-env name=HF_PFX_FILE::${{runner.workspace}}\build\codesign.pfx"
fi
- name: Clear Working Directory
if: matrix.os == 'windows-latest'
- name: Clear working directory
if: startsWith(matrix.os, 'windows')
shell: bash
working-directory: ${{runner.workspace}}
run: rm -rf ./*
- uses: actions/checkout@v1
with:
submodules: true
with:
submodules: false
fetch-depth: 1
- name: Create Build Directory
run: cmake -E make_directory ${{runner.workspace}}/build
- name: Decrypt Signing Key (Windows)
if: matrix.os == 'windows-latest'
working-directory: ${{runner.workspace}}/build
- name: Install dependencies
if: startsWith(matrix.os, 'ubuntu')
shell: bash
run: gpg --batch --yes -o codesign.pfx --passphrase "${{secrets.gpg_symmetric_key}}" --decrypt $GITHUB_WORKSPACE/tools/ci-scripts/codesign.pfx.gpg
- name: Import Signing Key (Windows)
if: matrix.os == 'windows-latest'
working-directory: ${{runner.workspace}}/build
shell: powershell
run: |
$mypwd=ConvertTo-SecureString -String ${{ secrets.pfx_key }} -Force -AsPlainText
Import-PfxCertificate -Password $mypwd -CertStoreLocation Cert:\CurrentUser\My -FilePath ${{runner.workspace}}\build\codesign.pfx
Import-PfxCertificate -Password $mypwd -CertStoreLocation Cert:\LocalMachine\My -FilePath ${{runner.workspace}}\build\codesign.pfx
run: |
echo "Installing Python Modules:"
pip3 install distro || exit 1
echo "Updating apt repository index"
sudo apt update || exit 1
echo "Installing apt packages"
sudo apt install -y ${{ matrix.apt-dependencies }} || exit 1
- name: Install Python modules
if: matrix.os != 'ubuntu-latest'
if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS')
shell: bash
run: $PYTHON_EXEC -m pip install boto3 PyGithub
- name: Create build environment
shell: bash
run: cmake -E make_directory "${{runner.workspace}}/build"
- name: Configure CMake
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCLIENT_ONLY:BOOLEAN=$CLIENT_ONLY $CMAKE_EXTRA
- name: Build Application
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DVCPKG_BUILD_TYPE=release -DCLIENT_ONLY:BOOLEAN=$CLIENT_ONLY -DBYPASS_SIGNING:BOOLEAN=TRUE $CMAKE_EXTRA
- name: Build application
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake --build . --config $BUILD_TYPE --target $APP_NAME
- name: Build Console
run: cmake --build . --config $BUILD_TYPE --target $APP_TARGET_NAME $CMAKE_BUILD_EXTRA
- name: Build domain server
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake --build . --config $BUILD_TYPE --target packaged-server-console
- name: Build Domain Server (FullBuild)
if: matrix.build_type == 'full'
shell: bash
working-directory: ${{runner.workspace}}/build
run: cmake --build . --config $BUILD_TYPE --target domain-server
- name: Build Assignment Client (FullBuild)
if: matrix.build_type == 'full'
shell: bash
working-directory: ${{runner.workspace}}/build
run: cmake --build . --config $BUILD_TYPE --target assignment-client
- name: Build Installer
run: cmake --build . --config $BUILD_TYPE --target domain-server $CMAKE_BUILD_EXTRA
- name: Build assignment client
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake --build . --config $BUILD_TYPE --target package
- name: Sign Installer (Windows)
if: matrix.os == 'windows-latest'
shell: powershell
working-directory: C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64
run: .\signtool.exe sign /fd sha256 /f ${{runner.workspace}}\build\codesign.pfx /p ${{secrets.pfx_key}} /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 ${{runner.workspace}}\build\${env:INSTALLER}
- name: Upload Artifact
if: matrix.os != 'ubuntu-latest'
run: cmake --build . --config $BUILD_TYPE --target assignment-client $CMAKE_BUILD_EXTRA
- name: Build console
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake --build . --config $BUILD_TYPE --target packaged-server-console $CMAKE_BUILD_EXTRA
- name: Build installer
working-directory: ${{runner.workspace}}/build
shell: bash
run: |
echo "Retry code from https://unix.stackexchange.com/a/137639"
function fail {
echo $1 >&2
exit 1
}
function retry {
local n=1
local max=5
local delay=15
while true; do
"$@" && break || {
if [[ $n -lt $max ]]; then
((n++))
echo "Command failed. Attempt $n/$max:"
sleep $delay;
else
fail "The command has failed after $n attempts."
fi
}
done
}
retry cmake --build . --config $BUILD_TYPE --target package $CMAKE_BUILD_EXTRA
#- name: Sign installer (Windows)
# if: startsWith(matrix.os, 'windows')
# shell: powershell
# working-directory: C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64
# run: .\signtool.exe sign /fd sha256 /f ${{runner.workspace}}\build\codesign.pfx /p ${{secrets.pfx_key}} /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 ${{runner.workspace}}\build\${env:INSTALLER}
- name: Output system stats
if: ${{ always() }}
working-directory: ${{runner.workspace}}/build
shell: bash
run: |
echo "Disk usage:"
df -h
- name: Output installer logs
if: failure() && startsWith(matrix.os, 'windows')
shell: bash
working-directory: ${{runner.workspace}}/build
run: cat ./_CPack_Packages/win64/NSIS/NSISOutput.log
- name: Upload artifact
if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS')
shell: bash
working-directory: ${{runner.workspace}}/build
env:
AWS_ACCESS_KEY_ID: ${{ secrets.aws_access_key_id }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.aws_secret_access_key }}
run: $PYTHON_EXEC $GITHUB_WORKSPACE/tools/ci-scripts/upload.py
- name: Archive Symbols
if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest')
working-directory: ${{runner.workspace}}
shell: bash
run: |
SYMBOLS_TEMP="symbols-temp"
mkdir $SYMBOLS_TEMP
find "./build" \( -path '*/tools/gpu-frame-player/*' -or -path '*/interface/*' -or -path '*/plugins/*' \) -regex ".*\.$SYMBOL_REGEX" -exec cp -r {} $SYMBOLS_TEMP \;
cd $SYMBOLS_TEMP
$ZIP_COMMAND $ZIP_ARGS ../${{ steps.buildenv1.outputs.symbols_archive }} .
- name: Upload Symbols
if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest')
working-directory: ${{runner.workspace}}
shell: bash
run: |
curl --data-binary @${{ steps.buildenv1.outputs.symbols_archive }} "$CMAKE_BACKTRACE_URL/post?format=symbols&token=$CMAKE_BACKTRACE_SYMBOLS_TOKEN&upload_file=${{steps.buildenv1.outputs.symbols_archive}}&tag=$RELEASE_NUMBER"
# - name: Debug List Symbols
# if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest')
# working-directory: ${{runner.workspace}}
# shell: bash
# run: |
# unzip -v "${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}"
# - name: Debug Upload Symbols Artifact
# if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest')
# uses: actions/upload-artifact@v1
# with:
# name: symbols
# path: ${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}
#- name: Archive symbols
# if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS')
# working-directory: ${{runner.workspace}}
# shell: bash
# run: |
# SYMBOLS_TEMP="symbols-temp"
# mkdir $SYMBOLS_TEMP
# find "./build" \( -path '*/tools/gpu-frame-player/*' -or -path '*/interface/*' -or -path '*/plugins/*' \) -regex ".*\.$SYMBOL_REGEX" -exec cp -r {} $SYMBOLS_TEMP \;
# cd $SYMBOLS_TEMP
# $ZIP_COMMAND $ZIP_ARGS ../${{ steps.buildenv1.outputs.symbols_archive }} .
#- name: Upload symbols
# if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS')
# working-directory: ${{runner.workspace}}
# shell: bash
# run: |
# curl --data-binary @${{ steps.buildenv1.outputs.symbols_archive }} "$CMAKE_BACKTRACE_URL/post?format=symbols&token=$CMAKE_BACKTRACE_SYMBOLS_TOKEN&upload_file=${{steps.buildenv1.outputs.symbols_archive}}&tag=$BUILD_NUMBER"
#- name: Debug list symbols
# if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS')
# working-directory: ${{runner.workspace}}
# shell: bash
# run: |
# unzip -v "${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}"
#- name: Upload debug list symbols
# if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS')
# uses: actions/upload-artifact@v1
# with:
# name: symbols
# path: ${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}

View file

@ -14,7 +14,9 @@ env:
RELEASE_TYPE: PR
RELEASE_NUMBER: ${{ github.event.number }}
VERSION_CODE: ${{ github.event.number }}
# Sentry Crash Reporting
CMAKE_BACKTRACE_URL: ${{ secrets.MINIDUMP_TOKEN }}
CMAKE_BACKTRACE_TOKEN: PR_${{ github.event.number }}_${{ github.sha }}
# OSX specific variables
DEVELOPER_DIR: /Applications/Xcode_11.2.app/Contents/Developer
@ -22,18 +24,27 @@ env:
# WIN32 specific variables
PreferredToolArchitecture: X64
GIT_COMMIT_SHORT: ${{ github.sha }}
# Ensure XZ always runs with muticore support
XZ_OPT: -T0
jobs:
build:
name: "build (${{matrix.os}}, ${{matrix.build_type}})"
strategy:
matrix:
os: [windows-latest, macOS-latest, ubuntu-18.04]
build_type: [full]
include:
- os: windows-latest
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 libsnappy1v5 libwebpdemux2 libwebpmux3
- os: ubuntu-18.04
build_type: android
apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0
fail-fast: false
runs-on: ${{matrix.os}}
@ -43,44 +54,74 @@ jobs:
shell: bash
id: buildenv1
run: |
echo ::set-env name=GIT_COMMIT_SHORT::`echo $GIT_COMMIT | cut -c1-7`
echo ::set-env name=JOB_NAME::"build (${{matrix.os}}, ${{matrix.build_type}})"
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 ::set-env name=PYTHON_EXEC::python3
echo ::set-env name=INSTALLER_EXT::*
echo ::set-env name=CMAKE_BUILD_EXTRA::"-- -j3"
echo ::set-env name=CMAKE_EXTRA::"-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)"
echo "PYTHON_EXEC=python3" >> $GITHUB_ENV
echo "INSTALLER_EXT=*" >> $GITHUB_ENV
echo "CMAKE_BUILD_EXTRA=-- -j3" >> $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 ::set-env name=PYTHON_EXEC::python3
echo ::set-env name=INSTALLER_EXT::dmg
echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode"
echo "PYTHON_EXEC=python3" >> $GITHUB_ENV
echo "INSTALLER_EXT=dmg" >> $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 ::set-env name=PYTHON_EXEC::python
echo ::set-env name=INSTALLER_EXT::exe
echo ::set-env name=CMAKE_EXTRA::"-A x64"
echo "PYTHON_EXEC=python" >> $GITHUB_ENV
echo "INSTALLER_EXT=exe" >> $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
HIFI_ANDROID_PRECOMPILED="${{runner.workspace}}/dependencies"
echo "HIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED" >> $GITHUB_ENV
mkdir $HIFI_ANDROID_PRECOMPILED
echo "INSTALLER_EXT=apk" >> $GITHUB_ENV
fi
# Configuration is broken into two steps because you can't set an env var and also reference it in the same step
- name: Configure Build Environment 2
shell: bash
run: |
echo "${{ steps.buildenv1.outputs.symbols_archive }}"
echo ::set-env name=ARTIFACT_PATTERN::Vircadia-Alpha-PR${{ github.event.number }}-*.$INSTALLER_EXT
# Build type variables
echo ::set-env name=INSTALLER::Vircadia-Alpha-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT
echo "GIT_COMMIT_SHORT=${{ steps.buildenv1.outputs.github_sha_short }}" >> $GITHUB_ENV
if [[ "${{ matrix.build_type }}" != "android" ]]; then
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
- name: Clear Working Directory
if: startsWith(matrix.os, 'windows')
shell: bash
working-directory: ${{runner.workspace}}
run: rm -rf ./*
- uses: actions/checkout@v1
with:
submodules: true
with:
submodules: false
fetch-depth: 1
- name: Install dependencies
shell: bash
@ -101,23 +142,46 @@ jobs:
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DVCPKG_BUILD_TYPE=release $CMAKE_EXTRA
- name: Compress cmake logs
if: always()
shell: bash
run: |
if [ "${{ matrix.os }}" == "macOS-latest" ]; then
TAR=gtar
else
TAR=tar
fi
find "$HOME/vircadia-files/vcpkg" -name '*log' -type f -print0 | $TAR --null --force-local -T - -c --xz -v -f "${{ runner.workspace }}/cmake-logs-${{ matrix.os }}-${{ github.event.number }}.tar.xz"
- name: Archive cmake logs
if: always()
uses: actions/upload-artifact@v2
with:
name: cmake-logs-${{ matrix.os }}-${{ github.event.number }}.tar.xz
path: ${{ runner.workspace }}/cmake-logs-${{ matrix.os }}-${{ github.event.number }}.tar.xz
if-no-files-found: error
- name: Build Application
if: matrix.build_type == 'full' || matrix.build_type == 'client'
working-directory: ${{runner.workspace}}/build
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
shell: bash
run: cmake --build . --config $BUILD_TYPE --target domain-server $CMAKE_BUILD_EXTRA
- name: Build Assignment Client
if: matrix.build_type == 'full'
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake --build . --config $BUILD_TYPE --target assignment-client $CMAKE_BUILD_EXTRA
- name: Build Console
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
- name: Build Installer
if: matrix.build_type != 'android'
working-directory: ${{runner.workspace}}/build
shell: bash
run: |
@ -144,6 +208,28 @@ 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
working-directory: ${{runner.workspace}}/vircadia
run: |
echo "Pre-cache the vcpkg managed dependencies"
$PYTHON_EXEC prebuild.py --build-root ${{runner.workspace}}/build --android interface
cd android
# Pre-cache the gradle dependencies
./gradlew -m tasks -PHIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED
# Build!
./build_android.sh
- name: Output system stats
if: ${{ always() }}
working-directory: ${{runner.workspace}}/build
@ -161,4 +247,8 @@ jobs:
working-directory: ${{runner.workspace}}/build
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: $PYTHON_EXEC "$GITHUB_WORKSPACE/tools/ci-scripts/upload_to_publish_server.py"
run: |
if [[ "${{ matrix.build_type }}" == "android" ]]; then
cd $GITHUB_WORKSPACE/android
fi
$PYTHON_EXEC "$GITHUB_WORKSPACE/tools/ci-scripts/upload_to_publish_server.py"

1
.gitignore vendored
View file

@ -111,3 +111,4 @@ tools/unity-avatar-exporter
server-console/package-lock.json
vcpkg/
/tools/nitpick/compiledResources
qt/

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "vircadia-web"]
path = vircadia-web
url = ../vircadia-web.git

43
.grenrc.js Normal file
View 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"
}

189
BUILD.md
View file

@ -1,114 +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.
Linux:
```bash
export 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.
Windows:
```bash
set HIFI_VCPKG_BASE=/path/to/directory
```
#### Generating Build Files
Where `/path/to/directory` is the path to a directory where you wish the build files to get stored.
##### Possible Environment Variables
### Generating Build Files
// The URL to post the dump to.
CMAKE_BACKTRACE_URL
// The identifying tag of the release.
CMAKE_BACKTRACE_TOKEN
// The release version.
RELEASE_NUMBER
// The build commit.
BUILD_NUMBER
#### Possible Environment Variables
// 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
```text
// 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
// 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:
@ -118,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).
@ -138,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
@ -151,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.

View file

@ -1,8 +1,8 @@
# Build Android
*Last Updated on December 21, 2019*
*Last Updated on December 15, 2020*
Please read the [general build guide](BUILD.md) for information on building other platforms. Only Android specific instructions are found in this file. **Note that these instructions apply to building for Oculus Quest.**
Please read the [general build guide](BUILD.md) for information on building other platforms. Only Android specific instructions are found in this file. **Note that these instructions apply to building for the Oculus Quest 1.**
## Dependencies
@ -14,7 +14,7 @@ Please install the dependencies for your OS using the [Windows](BUILD_WIN.md), [
### Android Studio
Download the [Android Studio](https://developer.android.com/studio/index.html) installer and run it. Once installed, at the welcome screen, click _Configure_ in the lower right corner and select _SDK Manager_.
Download the [Android Studio](https://developer.android.com/studio/index.html) installer and run it. Once installed, click _File_ then _Settings_, expand _Appearance & Behavior_ then expand _System Settings_ and select _Android SDK_.
From the _SDK Platforms_ tab, select API levels 26 and 28.
@ -27,24 +27,28 @@ From the _SDK Tools_ tab, select the following
* Android SDK Tools
* NDK (even if you have the NDK installed separately)
Still in the _SDK Tools_ tab, click _Show Package Details_. Select CMake 3.6.4. Do this even if you have a separate CMake installation.
Still in the _SDK Tools_ tab, check off _Show Package Details_ at the bottom. Select CMake 3.6.4. Do this even if you have a separate CMake installation. Also, make sure the NDK installed version is 18 (or higher).
Also, make sure the NDK installed version is 18 (or higher).
Now go back to _File_ then _Project Structure_ then under _Project_ set the Android Gradle Plugin Version to `3.2.1` and Gradle Version to `4.10.1`.
If Android Studio pops open the "Plugin Update Recommeded" dialog, do not click update, just click X on the top right to close. Later versions of the Gradle plugin have known issues with cz.malohlava.
## Environment
### Create a keystore in Android Studio
Follow the directions [here](https://developer.android.com/studio/publish/app-signing#generate-key) to create a keystore file. You can save it anywhere (preferably not in the `hifi` folder).
Follow the directions [here](https://developer.android.com/studio/publish/app-signing#generate-key) to create a keystore file. You can save it anywhere (preferably not in the `vircadia` folder).
### Set up machine specific Gradle properties
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.
@ -52,21 +56,30 @@ 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 above code to suppress modules is not necessary, but will speed up the build process.
#### 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`
```properties
SUPPRESS_FRAME_PLAYER
SUPPRESS_QUEST_FRAME_PLAYER
```
### Clone the repository
`git clone https://github.com/kasenvr/project-athena.git`
`git clone https://github.com/vircadia/vircadia.git`
## Building & Running
@ -74,12 +87,17 @@ The above code to suppress modules is not necessary, but will speed up the build
* Open Android Studio
* Choose _Open an existing Android Studio project_
* Navigate to the `hifi` repository and choose the `android` folder and select _OK_
* Navigate to the `vircadia` repository that had you cloned and choose the `android` folder and select _OK_
* Wait for Gradle to sync (this should take around 20 minutes the first time)
* From the _Build_ menu select _Make Project_
* If a dialog pops open saying "Plugin Update Recommeded" dialog, do not click update, just click X on the top right to close.
* In the _Project_ window click on the project you wish to build (i.e. "questInterface") then click _Build_ in the top menu and choose _Make Module 'questInterface'_
* By default this will build the "debug" apk, you can change this by opening the _Build Variants_ window along the left side and select other build types such as "release".
* Your newly build APK should reside in `vircadia\android\apps\questInterface\release` (if you chose release).
### Running a Module
You are free to use the "adb" command line or other development tools to install (sideload on Quest) your newly built APK, or you can follow the instructions below to load the APK via Android Studio.
* In the toolbar at the top of Android Studio, next to the green hammer icon, you should see a dropdown menu.
* You may already see a configuration for the module you are trying to build. If so, select it.
* Otherwise, select _Edit Configurations_.
@ -112,11 +130,19 @@ To view a more complete debug log,
* Click the icon with the two overlapping squares in the upper left corner of the tab where the sync is running (hover text says _Toggle view_)
* To change verbosity, click _File > Settings_. Under _Build, Execution, Deployment > Compiler_ you can add command-line flags, as per Gradle documentation
If you encounter CMake issues, try adding the following system environment variable:
With your start menu, search for 'Edit the System Environment Variables' and open it.
* Click on 'Advanced' tab, then 'Environment Variables'
* Select 'New' under System variables
* Set "Variable name" to QT_CMAKE_PREFIX_PATH
* Set "Variable value" to the directory that your android build placed the CMake 3.6.4 library CMake directory (i.e. android\qt\lib\cmake).
Some things you can try if you want to do a clean build
* Delete the `build` and `.externalNativeBuild` folders from the folder for each module you're building (for example, `hifi/android/apps/interface`)
* Delete the `build` and `.externalNativeBuild` folders from the folder for each module you're building (for example, `vircadia/android/apps/interface`)
* If you have set your `HIFI_VCPKG_ROOT` environment variable, delete the contents of that directory; otherwise, delete `AppData/Local/Temp/hifi`
* In Android Studio, click _File > Invalidate Caches / Restart_ and select _Invalidate and Restart_
If you see lots of "couldn't acquire lock" errors,
* Open Task Manager and close any running Clang / Gradle processes
* Open Task Manager and close any running Clang / Gradle processes

View file

@ -1,9 +1,11 @@
# Build Linux
*Last Updated on April 11, 2020*
*Last Updated on December 1, 2020*
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Linux specific instructions are found in this file.
You can use the [Vircadia Builder](https://github.com/vircadia/vircadia-builder) to build on Linux more easily. Alternatively, you can follow the manual steps below.
## Ubuntu 16.04/18.04 specific build guide
### Ubuntu 16.04 only
Add the following line to *.bash_profile*
@ -76,7 +78,7 @@ sudo apt-get install nodejs
Clone this repository:
```bash
git clone https://github.com/kasenvr/project-athena.git
git clone https://github.com/vircadia/vircadia.git
```
To compile a DEV version checkout the branch you need. To get a list of all tags:
@ -86,24 +88,27 @@ git fetch -a
Then checkout the main branch with:
```bash
git checkout kasen/core
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
Create the build directory:
```bash
cd project-athena
cd vircadia
mkdir build
cd build
```
@ -166,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`

View file

@ -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

View file

@ -1,86 +1,104 @@
# 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.
**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 dont 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++". On the right on the Summary toolbar, select the following components.
When selecting components, check "Desktop development with C++".
#### If you're installing Visual Studio 2017,
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.
* Windows 8.1 SDK and UCRT SDK
* VC++ 2015.3 v14.00 (v140) toolset for desktop
### Visual Studio 2019
#### 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)
If you do not already have a Python 3.x development environment installed, also check "Python Development" in this screen.
## Step 1a. Alternate Python
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.
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 1a. Alternate Python
## Step 2. Python Dependencies
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 you get version 3.6.6 or higher.
### Step 2. Python Dependencies
In a command-line that can access Python's pip you will need to run the following command:
In an administrator command-line that can access Python's pip you will need to run the following command:
`pip install distro`
### Step 3. Installing CMake
If you do not use an administrator command-line, you will get errors.
Download and install the latest version of CMake 3.15.
## Step 3. Installing CMake
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. Create VCPKG environment variable
## 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. (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 5. 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 6. Making a Build
## Step 8. Making a Build
Open `%VIRCADIA_DIR%\build\vircadia.sln` using Visual Studio.
@ -88,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 7. Testing Interface
## Step 9. Testing Interface
Create another environment variable (see Step #3)
* Set "Variable name": `_NO_DEBUG_HEAP`
@ -96,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 #6, first try this:
* Delete your locally cloned copy of the Vircadia repository
* Restart your computer
* Redownload the [repository](https://github.com/kasenvr/project-athena)
* Restart directions from Step #6
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.

View file

@ -41,10 +41,23 @@ 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}")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros/TargetPython.cmake")
target_python()
if (WIN32 AND NOT HIFI_ANDROID)
if (WIN32 AND NOT HIFI_ANDROID AND NOT (CMAKE_GENERATOR STREQUAL "Ninja"))
# Force x64 toolset
set(CMAKE_GENERATOR_TOOLSET "host=x64" CACHE STRING "64-bit toolset" FORCE)
endif()
@ -64,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 "")
@ -73,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)
@ -81,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()
@ -88,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)
@ -119,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")
@ -129,7 +159,6 @@ set(BUILD_TESTS_OPTION OFF)
set(BUILD_MANUAL_TESTS_OPTION ${BUILD_TESTS_OPTION})
set(BUILD_TOOLS_OPTION ON)
set(BUILD_INSTALLER_OPTION ON)
set(GLES_OPTION OFF)
set(DISABLE_QML_OPTION OFF)
set(DOWNLOAD_SERVERLESS_CONTENT_OPTION OFF)
@ -182,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()
@ -253,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 )
@ -299,6 +337,13 @@ if (BUILD_GPU_FRAME_PLAYER_ONLY)
add_subdirectory(tools/gpu-frame-player)
else()
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)
# add subdirectories for all targets
if (BUILD_SERVER)
add_subdirectory(assignment-client)
@ -311,8 +356,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()
@ -322,9 +370,6 @@ if (BUILD_CLIENT OR BUILD_SERVER)
add_subdirectory(server-console)
endif()
# BUILD_TOOLS option will be handled inside the tools's CMakeLists.txt because 'scribe' tool is required for build anyway
add_subdirectory(tools)
endif()
if (BUILD_TESTS)

View file

@ -1,3 +1,4 @@
The project embraces distributed development and if you'd like to help, it would be greatly appreciated. Just open a pull request with the revisions.
Contributing
@ -6,7 +7,7 @@ Contributing
2. Clone your fork of the repository locally
```
git clone git://github.com/USERNAME/project-athena.git
git clone git://github.com/USERNAME/vircadia.git
```
3. Create a new branch
@ -20,7 +21,7 @@ Contributing
6. Update your branch
```
git remote add upstream https://github.com/kasenvr/project-athena
git remote add upstream https://github.com/vircadia/vircadia
git pull upstream master
```
@ -35,13 +36,22 @@ Contributing
*You can follow [GitHub's guide](https://help.github.com/articles/creating-a-pull-request) to find out how to create a pull request.*
Tips for Pull Requests
===
To make the QA process go as smoothly as possible.
1. Have a basic description in your pull request.
2. Write a basic test plan if you are altering or adding features.
3. If a new API is added, try to make sure that some level of basic documentation on how you can utilize it is included.
4. If an added API or feature requires an external service, try to document or link to instructions on how to create a basic working setup.
Reporting Bugs
===
1. Always update to the latest code on master, we make many merges every day and it is possible the bug has already been fixed!
2. Search [issues](https://github.com/kasenvr/project-athena/issues) to make sure that somebody has not already reported the same bug.
3. [Add](https://github.com/kasenvr/project-athena/issues/new) your report to the issues list!
2. Search [issues](https://github.com/vircadia/vircadia/issues) to make sure that somebody has not already reported the same bug.
3. [Add](https://github.com/vircadia/vircadia/issues/new) your report to the issues list!
Requesting a Feature
===
1. Search [issues](https://github.com/kasenvr/project-athena/issues) to make sure that somebody has not already requested the same feature.
2. [Add](https://github.com/kasenvr/project-athena/issues/new) your request to the issues list!
1. Search [issues](https://github.com/vircadia/vircadia/issues) to make sure that somebody has not already requested the same feature.
2. [Add](https://github.com/vircadia/vircadia/issues/new) your request to the issues list!

View file

@ -1,98 +0,0 @@
# Creating an Installer
*Last Updated on August 24, 2020*
Follow the [build guide](BUILD.md) to figure out how to build Vircadia for your platform.
During generation, CMake should produce an `install` target and a `package` target.
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
To produce an installer, run the `package` target. However you will want to follow the steps specific to your platform below.
#### Windows
##### Prerequisites
To produce an executable installer on Windows, the following are required:
1. [7-zip](<https://www.7-zip.org/download.html>)
1. [Nullsoft Scriptable Install System](http://nsis.sourceforge.net/Download) - 3.04
Install using defaults (will install to `C:\Program Files (x86)\NSIS`)
1. [UAC Plug-in for Nullsoft](http://nsis.sourceforge.net/UAC_plug-in) - 0.2.4c
1. Extract Zip
1. Copy `UAC.nsh` to `C:\Program Files (x86)\NSIS\Include\`
1. Copy `Plugins\x86-ansi\UAC.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `Plugins\x86-unicode\UAC.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [nsProcess Plug-in for Nullsoft](http://nsis.sourceforge.net/NsProcess_plugin) - 1.6 (use the link marked **nsProcess_1_6.7z**)
1. Extract Zip
1. Copy `Include\nsProcess.nsh` to `C:\Program Files (x86)\NSIS\Include\`
1. Copy `Plugins\nsProcess.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `Plugins\nsProcessW.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [InetC Plug-in for Nullsoft](http://nsis.sourceforge.net/Inetc_plug-in) - 1.0
1. Extract Zip
1. Copy `Plugin\x86-ansi\InetC.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `Plugin\x86-unicode\InetC.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [NSISpcre Plug-in for Nullsoft](http://nsis.sourceforge.net/NSISpcre_plug-in) - 1.0
1. Extract Zip
1. Copy `NSISpre.nsh` to `C:\Program Files (x86)\NSIS\Include\`
1. Copy `NSISpre.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. [nsisSlideshow Plug-in for Nullsoft](<http://wiz0u.free.fr/prog/nsisSlideshow/>) - 1.7
1. Extract Zip
1. Copy `bin\nsisSlideshow.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `bin\nsisSlideshowW.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [Nsisunz plug-in for Nullsoft](http://nsis.sourceforge.net/Nsisunz_plug-in)
1. Download both Zips and unzip
1. Copy `nsisunz\Release\nsisunz.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `NSISunzU\Plugin unicode\nsisunz.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [ApplicationID plug-in for Nullsoft]() - 1.0
1. Download [`Pre-built DLLs`](<https://github.com/connectiblutz/NSIS-ApplicationID/releases/download/1.1/NSIS-ApplicationID.zip>)
1. Extract Zip
1. Copy `Release\ApplicationID.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `ReleaseUnicode\ApplicationID.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [Node.JS and NPM](<https://www.npmjs.com/get-npm>)
1. Install version 10.15.0 LTS
##### 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
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.
1. Build the solution.
1. Build `packaged-server-console-npm-install` (found under **hidden/Server Console**)
1. Build `packaged-server-console` (found under **Server Console**)
This will add 2 folders to `build\server-console\` -
`server-console-win32-x64` and `x64`
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
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.

273
INSTALLER.md Normal file
View file

@ -0,0 +1,273 @@
# Creating an Installer
*Last Updated on June 16, 2021*
Follow the [build guide](BUILD.md) to figure out how to build Vircadia for your platform.
During generation, CMake should produce an `install` target and a `package` target.
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
To produce an installer, run the `package` target. However you will want to follow the steps specific to your platform below.
### Windows
#### Prerequisites
To produce an executable installer on Windows, the following are required:
1. [7-zip](<https://www.7-zip.org/download.html>)
1. [Nullsoft Scriptable Install System](http://nsis.sourceforge.net/Download) - 3.04
Install using defaults (will install to `C:\Program Files (x86)\NSIS`)
1. [UAC Plug-in for Nullsoft](http://nsis.sourceforge.net/UAC_plug-in) - 0.2.4c
1. Extract Zip
1. Copy `UAC.nsh` to `C:\Program Files (x86)\NSIS\Include\`
1. Copy `Plugins\x86-ansi\UAC.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `Plugins\x86-unicode\UAC.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [nsProcess Plug-in for Nullsoft](http://nsis.sourceforge.net/NsProcess_plugin) - 1.6 (use the link marked **nsProcess_1_6.7z**)
1. Extract Zip
1. Copy `Include\nsProcess.nsh` to `C:\Program Files (x86)\NSIS\Include\`
1. Copy `Plugins\nsProcess.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `Plugins\nsProcessW.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [InetC Plug-in for Nullsoft](http://nsis.sourceforge.net/Inetc_plug-in) - 1.0
1. Extract Zip
1. Copy `Plugin\x86-ansi\InetC.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `Plugin\x86-unicode\InetC.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [NSISpcre Plug-in for Nullsoft](http://nsis.sourceforge.net/NSISpcre_plug-in) - 1.0
1. Extract Zip
1. Copy `NSISpre.nsh` to `C:\Program Files (x86)\NSIS\Include\`
1. Copy `NSISpre.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. [nsisSlideshow Plug-in for Nullsoft](<http://wiz0u.free.fr/prog/nsisSlideshow/>) - 1.7
1. Extract Zip
1. Copy `bin\nsisSlideshow.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `bin\nsisSlideshowW.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [Nsisunz plug-in for Nullsoft](http://nsis.sourceforge.net/Nsisunz_plug-in)
1. Download both Zips and unzip
1. Copy `nsisunz\Release\nsisunz.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `NSISunzU\Plugin unicode\nsisunz.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [ApplicationID plug-in for Nullsoft]() - 1.0
1. Download [`Pre-built DLLs`](<https://github.com/connectiblutz/NSIS-ApplicationID/releases/download/1.1/NSIS-ApplicationID.zip>)
1. Extract Zip
1. Copy `Release\ApplicationID.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi\`
1. Copy `ReleaseUnicode\ApplicationID.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-unicode\`
1. [Node.JS and NPM](<https://nodejs.org/en/download/>)
1. Install version 10.15.0 LTS (or greater)
#### 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
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.
1. Build the solution.
1. Build `packaged-server-console-npm-install` (found under **hidden/Server Console**)
1. Build `packaged-server-console` (found under **Server Console**)
This will add 2 folders to `build\server-console\` -
`server-console-win32-x64` and `x64`
1. Build CMakeTargets->PACKAGE
The installer is now available in `build\_CPack_Packages\win64\NSIS`
#### 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.

View file

@ -1,5 +1,5 @@
Copyright (c) 2013-2019, High Fidelity, Inc.
Copyright (c) 2019-2020, Vircadia contributors.
Copyright (c) 2019-2021, Vircadia contributors.
All rights reserved.
https://vircadia.com

View file

@ -1,61 +1,80 @@
# Vircadia
<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.
### [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/kasenvr/project-athena/releases/)
### How to build the Interface
[For Windows](https://github.com/kasenvr/project-athena/blob/master/BUILD_WIN.md)
[For Mac](https://github.com/kasenvr/project-athena/blob/master/BUILD_OSX.md)
[For Linux](https://github.com/kasenvr/project-athena/blob/master/BUILD_LINUX.md)
[For Linux - Vircadia Builder](https://github.com/kasenvr/vircadia-builder)
[View Releases here](https://github.com/vircadia/vircadia/releases/)
### How to deploy a Server
[For Windows and Linux](https://vircadia.com/deploy-a-server/)
- [For Windows and Linux](https://vircadia.com/deploy-a-server/)
### How to build a Server
### Building
[For Linux - Vircadia Builder](https://github.com/kasenvr/vircadia-builder)
#### How to build the Interface
### How to generate an Installer
- [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)
[For Windows](https://github.com/kasenvr/project-athena/blob/master/INSTALL.md)
#### How to build a Server
[For Linux - AppImage - Vircadia Builder](https://github.com/kasenvr/vircadia-builder/blob/master/README.md#building-appimages)
- [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)
### Boot to Metaverse: The Goal
#### How to generate an Installer
- [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/)
Having a place to experience adventure, a place to relax with calm breath, that's a world to live in. An engine to support infinite combinations and possibilities of worlds without censorship and interruption, that's a metaverse. Finding a way to make infinite realities our reality is the dream.
### Boot to Metaverse: The Technicals
Many developers have had personal combinations of High Fidelity from C++ modifications to different default scripts, all of which are lost to time as their fullest potential is never truly shared and propagated through the system.
Vircadia consists of many projects and codebases with its unifying structure's goal being a decentralized metaverse.
The goal of this project is to achieve the metaverse dream through shared contribution and building. Setting goals that are achievable yet meaningful is key to making proper forward progress on the technical front whilst maintaining morale.
- The Interface (Codename Athena) - You are here!
- The Server (Codename Athena) - You are also here!
- [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.
### Why High Fidelity's Virtual Reality Platform?
Because of all the options, it is the only starting point that is open-source, cross-platform, fully VR integrated + fully desktop integrated with an aim for quality visuals and performance. It also provides a foundation to build from including components like entity management, full body IK, etc.
WebXR offers the open-source and decentralized aspect but does not have any of the full featured starting points such as avatars, IK, etc. which means that a lot of ground work will have to be laid to make something functional. Far more work will need to be done to create a truly seamless and extensive experience as well.
Platforms like NeosVR or VRChat are not viable from go due to their fundamental closed-source and centralized nature. A metaverse to live in cannot have the keys handed over to any singular entity, if any at all.
We need to do the best we can with what we've got and our best bet as open source developers is to not redesign the wheel if we can help it!
#### Child Projects
- [Vircadia Builder for Linux](https://github.com/vircadia/vircadia-builder/)
- [User Documentation](https://github.com/vircadia/vircadia-docs-sphinx/)
- [Developer Documentation](https://github.com/vircadia/vircadia-dev-docs/)
### Contribution
A special thanks to the contributors of Vircadia.
There are many contributors to Vircadia. Code writers, reviewers, testers, documentation writers, modelers, and general supporters of the project are all integral to its development and success towards its goals. Find out how you can [contribute](CONTRIBUTING.md)!
[Contribution](CONTRIBUTING.md)
### [Supporters](https://github.com/sponsors/digisomni/)
| [Karol Suprynowicz - 74hc595](https://github.com/ksuprynowicz) |
| --- |
| <p align="center">[![ksuprynowicz](https://avatars.githubusercontent.com/u/11568651?s=64&v=4)](https://github.com/ksuprynowicz)</p>

View file

@ -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()

View file

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

View file

@ -9,7 +9,7 @@ import java.net.URISyntaxException;
public class HifiUtils {
public static final String METAVERSE_BASE_URL = "https://metaverse.highfidelity.com";
public static final String METAVERSE_BASE_URL = "https://metaverse.vircadia.com/live";
private static HifiUtils instance;

View file

@ -41,7 +41,7 @@ public class LoginFragment extends Fragment
private final String OAUTH_CLIENT_ID = BuildConfig.OAUTH_CLIENT_ID;
private final String OAUTH_REDIRECT_URI = BuildConfig.OAUTH_REDIRECT_URI;
private final String OAUTH_AUTHORIZE_BASE_URL = "https://highfidelity.com/oauth/authorize";
private final String OAUTH_AUTHORIZE_BASE_URL = "https://metaverse.vircadia.com/live/oauth/authorize";
private static final int OAUTH_AUTHORIZE_REQUEST = 1;
private EditText mUsername;
@ -222,7 +222,7 @@ public class LoginFragment extends Fragment
}
private void onForgotPasswordClicked() {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://highfidelity.com/users/password/new"));
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://metaverse.vircadia.com/live/users/password/new"));
startActivity(intent);
}

View file

@ -28,7 +28,7 @@ import retrofit2.http.Query;
public class EndpointUsersProvider implements UsersProvider {
public static final String BASE_URL = "https://metaverse.highfidelity.com/";
public static final String BASE_URL = "https://metaverse.vircadia.com/live/";
private final Retrofit mRetrofit;
private final EndpointUsersProviderService mEndpointUsersProviderService;

View file

@ -22,7 +22,7 @@ import retrofit2.http.Query;
public class UserStoryDomainProvider implements DomainProvider {
public static final String BASE_URL = "https://metaverse.highfidelity.com/";
public static final String BASE_URL = "https://metaverse.vircadia.com/live/";
private static final String INCLUDE_ACTIONS_FOR_PLACES = "concurrency";
private static final String INCLUDE_ACTIONS_FOR_FULL_SEARCH = "concurrency,announcements,snapshot";

View file

@ -15,8 +15,8 @@ import io.highfidelity.hifiinterface.HifiUtils;
* available in an API
*/
public class DownloadProfileImageTask extends AsyncTask<String, Void, String> {
private static final String BASE_PROFILE_URL = "https://highfidelity.com";
// Note: This should now be available in the API, correct?
private static final String BASE_PROFILE_URL = "https://metaverse.vircadia.com/live";
private static final String TAG = "Interface";
private final DownloadProfileImageResultProcessor mResultProcessor;

View file

@ -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}
)

View file

@ -5,11 +5,11 @@ ANDROID_BUILD_TYPE=release
ANDROID_BUILD_TARGET=assembleRelease
if [[ "$RELEASE_TYPE" == "PR" ]]; then
ANDROID_APK_SUFFIX=PR${RELEASE_NUMBER}-${SHA7}.apk ;
ANDROID_APK_SUFFIX=PR${RELEASE_NUMBER}-${GIT_COMMIT_SHORT}.apk ;
elif [[ "${STABLE_BUILD}" == "1" ]]; then
ANDROID_APK_SUFFIX=${RELEASE_NUMBER}.apk ;
else
ANDROID_APK_SUFFIX=${RELEASE_NUMBER}-${SHA7}.apk ;
ANDROID_APK_SUFFIX=${RELEASE_NUMBER}-${GIT_COMMIT_SHORT}.apk ;
fi
@ -17,7 +17,7 @@ fi
ANDROID_APP=interface
ANDROID_OUTPUT_DIR=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_TYPE}
ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}.apk
ANDROID_APK_NAME=HighFidelity-Beta-${ANDROID_APK_SUFFIX}
ANDROID_APK_NAME=Vircadia-${ANDROID_APK_SUFFIX}
./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET}
cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME}
@ -25,9 +25,9 @@ cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME}
ANDROID_APP=questInterface
ANDROID_OUTPUT_DIR=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_TYPE}
ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}.apk
ANDROID_APK_NAME=HighFidelity-Quest-Beta-${ANDROID_APK_SUFFIX}
ANDROID_APK_NAME=Vircadia-Quest-Alpha-${ANDROID_APK_SUFFIX}
./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET} || true
cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} || true
cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME}

View file

@ -1,9 +1,9 @@
#!/usr/bin/env bash
set -xeuo pipefail
DOCKER_IMAGE_NAME="hifi_androidbuild"
DOCKER_IMAGE_NAME="vircadia_androidbuild"
docker build --build-arg BUILD_UID=`id -u` -t "${DOCKER_IMAGE_NAME}" -f docker/Dockerfile docker
docker build --build-arg BUILD_UID=`id -u` -t "${DOCKER_IMAGE_NAME}" -f ./android/docker/Dockerfile ./android/docker
# The Jenkins PR builds use VERSION_CODE, but the release builds use VERSION
# So make sure we use VERSION_CODE consistently
@ -17,7 +17,7 @@ test -z "$STABLE_BUILD" && export STABLE_BUILD=0
docker run \
--rm \
--security-opt seccomp:unconfined \
-v "${WORKSPACE}":/home/jenkins/hifi \
-v "${WORKSPACE}":/home/gha/vircadia \
-e RELEASE_NUMBER \
-e RELEASE_TYPE \
-e ANDROID_APP \
@ -33,7 +33,7 @@ docker run \
-e OAUTH_CLIENT_SECRET \
-e OAUTH_CLIENT_ID \
-e OAUTH_REDIRECT_URI \
-e SHA7 \
-e GIT_COMMIT_SHORT \
-e STABLE_BUILD \
-e VERSION_CODE \
"${DOCKER_IMAGE_NAME}" \

View file

@ -57,13 +57,13 @@ RUN apt-get -y install \
# --- Gradle
ARG BUILD_UID=1001
RUN useradd -ms /bin/bash -u $BUILD_UID jenkins
RUN echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
USER jenkins
WORKDIR /home/jenkins
RUN useradd -ms /bin/bash -u $BUILD_UID gha
RUN echo "gha ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
USER gha
WORKDIR /home/gha
# Hifi dependencies
ENV HIFI_BASE="/home/jenkins/hifi_android"
# Vircadia dependencies
ENV HIFI_BASE="/home/gha/vircadia_android"
ENV HIFI_ANDROID_PRECOMPILED="$HIFI_BASE/dependencies"
ENV HIFI_VCPKG_BASE="$HIFI_BASE/vcpkg"
@ -71,24 +71,18 @@ RUN mkdir "$HIFI_BASE" && \
mkdir "$HIFI_VCPKG_BASE" && \
mkdir "$HIFI_ANDROID_PRECOMPILED"
# Checkout a relatively recent commit from the main repository and use it to cache the
# gradle and vcpkg dependencies
# This commit ID should be updated whenever someone changes the dependency list
# in cmake/ports
RUN git clone https://github.com/highfidelity/hifi.git && \
cd ~/hifi && \
git checkout 796bfb5d6715ff14c2e60f3ee8fac1465b7578c6
# Download the repo
RUN git clone https://github.com/vircadia/vircadia.git
WORKDIR /home/jenkins/hifi
WORKDIR /home/gha/vircadia
RUN mkdir build
# Pre-cache the vcpkg managed dependencies
WORKDIR /home/jenkins/hifi/build
WORKDIR /home/gha/vircadia/build
RUN python3 ../prebuild.py --build-root `pwd` --android interface
# Pre-cache the gradle dependencies
WORKDIR /home/jenkins/hifi/android
WORKDIR /home/gha/vircadia/android
RUN ./gradlew -m tasks -PHIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED
#RUN ./gradlew extractDependencies -PHIFI_ANDROID_PRECOMPILED=$HIFI_ANDROID_PRECOMPILED

View file

@ -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

View file

@ -112,11 +112,12 @@ Agent::Agent(ReceivedMessage& message) :
packetReceiver.registerListenerForTypes(
{ PacketType::MixedAudio, PacketType::SilentAudioFrame },
this, "handleAudioPacket");
PacketReceiver::makeUnsourcedListenerReference<Agent>(this, &Agent::handleAudioPacket));
packetReceiver.registerListenerForTypes(
{ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
this, "handleOctreePacket");
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
PacketReceiver::makeSourcedListenerReference<Agent>(this, &Agent::handleOctreePacket));
packetReceiver.registerListener(PacketType::SelectedAudioFormat,
PacketReceiver::makeUnsourcedListenerReference<Agent>(this, &Agent::handleSelectedAudioFormat));
// 100Hz timer for audio
const int TARGET_INTERVAL_MSEC = 10; // 10ms

View file

@ -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

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 11/25/2013.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -33,6 +34,7 @@
#include <Trace.h>
#include <StatTracker.h>
#include <ThreadHelpers.h>
#include "AssignmentClientLogging.h"
#include "AssignmentFactory.h"
@ -81,7 +83,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
_assignmentServerHostname = assignmentServerHostname;
}
_assignmentServerSocket = HifiSockAddr(_assignmentServerHostname, assignmentServerPort, true);
_assignmentServerSocket = SockAddr(_assignmentServerHostname, assignmentServerPort, true);
if (_assignmentServerSocket.isNull()) {
qCCritical(assignment_client) << "PAGE: Couldn't resolve domain server address" << _assignmentServerHostname;
}
@ -109,7 +111,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
// did we get an assignment-client monitor port?
if (assignmentMonitorPort > 0) {
_assignmentClientMonitorSocket = HifiSockAddr(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME, assignmentMonitorPort);
_assignmentClientMonitorSocket = SockAddr(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME, assignmentMonitorPort);
_assignmentClientMonitorSocket.setObjectName("AssignmentClientMonitor");
qCDebug(assignment_client) << "Assignment-client monitor socket is" << _assignmentClientMonitorSocket;
@ -118,8 +120,10 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
setUpStatusToMonitor();
}
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket");
packetReceiver.registerListener(PacketType::StopNode, this, "handleStopNodePacket");
packetReceiver.registerListener(PacketType::CreateAssignment,
PacketReceiver::makeUnsourcedListenerReference<AssignmentClient>(this, &AssignmentClient::handleCreateAssignmentPacket));
packetReceiver.registerListener(PacketType::StopNode,
PacketReceiver::makeUnsourcedListenerReference<AssignmentClient>(this, &AssignmentClient::handleStopNodePacket));
}
void AssignmentClient::stopAssignmentClient() {
@ -233,10 +237,13 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer<ReceivedMessa
qCDebug(assignment_client) << "Destination IP for assignment is" << nodeList->getDomainHandler().getIP().toString();
// start the deployed assignment
QThread* workerThread = new QThread;
QThread* workerThread = new QThread();
workerThread->setObjectName("ThreadedAssignment Worker");
connect(workerThread, &QThread::started, _currentAssignment.data(), &ThreadedAssignment::run);
connect(workerThread, &QThread::started, _currentAssignment.data(), [this] {
setThreadName("ThreadedAssignment Worker");
_currentAssignment->run();
});
// Once the ThreadedAssignment says it is finished - we ask it to deleteLater
// This is a queued connection so that it is put into the event loop to be processed by the worker
@ -263,7 +270,7 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer<ReceivedMessa
}
void AssignmentClient::handleStopNodePacket(QSharedPointer<ReceivedMessage> message) {
const HifiSockAddr& senderSockAddr = message->getSenderSockAddr();
const SockAddr& senderSockAddr = message->getSenderSockAddr();
if (senderSockAddr.getAddress() == QHostAddress::LocalHost ||
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {

View file

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

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 1/10/2014.
// Copyright 2014 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -72,7 +73,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
auto nodeList = DependencyManager::set<LimitedNodeList>(listenPort);
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::AssignmentClientStatus, this, "handleChildStatusPacket");
packetReceiver.registerListener(PacketType::AssignmentClientStatus,
PacketReceiver::makeUnsourcedListenerReference<AssignmentClientMonitor>(this, &AssignmentClientMonitor::handleChildStatusPacket));
adjustOSResources(std::max(_numAssignmentClientForks, _maxAssignmentClientForks));
// use QProcess to fork off a process for each of the child assignment clients
@ -330,7 +332,7 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer<ReceivedMes
auto nodeList = DependencyManager::get<NodeList>();
SharedNodePointer matchingNode = nodeList->nodeWithUUID(senderID);
const HifiSockAddr& senderSockAddr = message->getSenderSockAddr();
const SockAddr& senderSockAddr = message->getSenderSockAddr();
AssignmentClientChildData* childData = nullptr;

View file

@ -308,7 +308,8 @@ AssetServer::AssetServer(ReceivedMessage& message) :
// Queue all requests until the Asset Server is fully setup
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation }, this, "queueRequests");
packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation },
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::queueRequests));
#ifdef Q_OS_WIN
updateConsumedCores();
@ -464,10 +465,14 @@ void AssetServer::completeSetup() {
qCDebug(asset_server) << "Overriding temporary queuing packet handler.";
// We're fully setup, override the request queueing handler and replay all requests
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet");
packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo");
packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload");
packetReceiver.registerListener(PacketType::AssetMappingOperation, this, "handleAssetMappingOperation");
packetReceiver.registerListener(PacketType::AssetGet,
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::handleAssetGet));
packetReceiver.registerListener(PacketType::AssetGetInfo,
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::handleAssetGetInfo));
packetReceiver.registerListener(PacketType::AssetUpload,
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::handleAssetUpload));
packetReceiver.registerListener(PacketType::AssetMappingOperation,
PacketReceiver::makeSourcedListenerReference<AssetServer>(this, &AssetServer::handleAssetMappingOperation));
replayRequests();
}

View file

@ -101,20 +101,23 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
PacketType::InjectorGainSet,
PacketType::AudioSoloRequest,
PacketType::StopInjector },
this, "queueAudioPacket");
PacketReceiver::makeSourcedListenerReference<AudioMixer>(this, &AudioMixer::queueAudioPacket)
);
// packets whose consequences are global should be processed on the main thread
packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket");
packetReceiver.registerListener(PacketType::NodeMuteRequest, this, "handleNodeMuteRequestPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket");
packetReceiver.registerListener(PacketType::MuteEnvironment,
PacketReceiver::makeSourcedListenerReference<AudioMixer>(this, &AudioMixer::handleMuteEnvironmentPacket));
packetReceiver.registerListener(PacketType::NodeMuteRequest,
PacketReceiver::makeSourcedListenerReference<AudioMixer>(this, &AudioMixer::handleNodeMuteRequestPacket));
packetReceiver.registerListener(PacketType::KillAvatar,
PacketReceiver::makeSourcedListenerReference<AudioMixer>(this, &AudioMixer::handleKillAvatarPacket));
packetReceiver.registerListenerForTypes({
PacketType::ReplicatedMicrophoneAudioNoEcho,
PacketType::ReplicatedMicrophoneAudioWithEcho,
PacketType::ReplicatedInjectAudio,
PacketType::ReplicatedSilentAudioFrame
},
this, "queueReplicatedAudioPacket"
PacketType::ReplicatedSilentAudioFrame },
PacketReceiver::makeUnsourcedListenerReference<AudioMixer>(this, &AudioMixer::queueReplicatedAudioPacket)
);
connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled);

View file

@ -11,9 +11,13 @@
#include "AudioMixerSlavePool.h"
#include <QObject>
#include <assert.h>
#include <algorithm>
#include <ThreadHelpers.h>
void AudioMixerSlaveThread::run() {
while (true) {
wait();
@ -157,6 +161,7 @@ void AudioMixerSlavePool::resize(int numThreads) {
// start new slaves
for (int i = 0; i < numThreads - _numThreads; ++i) {
auto slave = new AudioMixerSlaveThread(*this, _workerSharedData);
QObject::connect(slave, &QThread::started, [] { setThreadName("AudioMixerSlaveThread"); });
slave->start();
_slaves.emplace_back(slave);
}

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 9/5/13.
// Copyright 2013 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -71,26 +72,38 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) :
connect(DependencyManager::get<NodeList>().data(), &NodeList::nodeKilled, this, &AvatarMixer::handleAvatarKilled);
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::AvatarData, this, "queueIncomingPacket");
packetReceiver.registerListener(PacketType::AdjustAvatarSorting, this, "handleAdjustAvatarSorting");
packetReceiver.registerListener(PacketType::AvatarQuery, this, "handleAvatarQueryPacket");
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket");
packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket");
packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket");
packetReceiver.registerListener(PacketType::RequestsDomainListData, this, "handleRequestsDomainListDataPacket");
packetReceiver.registerListener(PacketType::SetAvatarTraits, this, "queueIncomingPacket");
packetReceiver.registerListener(PacketType::BulkAvatarTraitsAck, this, "queueIncomingPacket");
packetReceiver.registerListener(PacketType::AvatarData,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::queueIncomingPacket));
packetReceiver.registerListener(PacketType::AdjustAvatarSorting,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleAdjustAvatarSorting));
packetReceiver.registerListener(PacketType::AvatarQuery,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleAvatarQueryPacket));
packetReceiver.registerListener(PacketType::AvatarIdentity,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleAvatarIdentityPacket));
packetReceiver.registerListener(PacketType::KillAvatar,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleKillAvatarPacket));
packetReceiver.registerListener(PacketType::NodeIgnoreRequest,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleNodeIgnoreRequestPacket));
packetReceiver.registerListener(PacketType::RadiusIgnoreRequest,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleRadiusIgnoreRequestPacket));
packetReceiver.registerListener(PacketType::RequestsDomainListData,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleRequestsDomainListDataPacket));
packetReceiver.registerListener(PacketType::SetAvatarTraits,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::queueIncomingPacket));
packetReceiver.registerListener(PacketType::BulkAvatarTraitsAck,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::queueIncomingPacket));
packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
this, "handleOctreePacket");
packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "queueIncomingPacket");
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleOctreePacket));
packetReceiver.registerListener(PacketType::ChallengeOwnership,
PacketReceiver::makeSourcedListenerReference<AvatarMixer>(this, &AvatarMixer::queueIncomingPacket));
packetReceiver.registerListenerForTypes({
PacketType::ReplicatedAvatarIdentity,
PacketType::ReplicatedKillAvatar
}, this, "handleReplicatedPacket");
}, PacketReceiver::makeUnsourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleReplicatedPacket));
packetReceiver.registerListener(PacketType::ReplicatedBulkAvatarData, this, "handleReplicatedBulkAvatarPacket");
packetReceiver.registerListener(PacketType::ReplicatedBulkAvatarData,
PacketReceiver::makeUnsourcedListenerReference<AvatarMixer>(this, &AvatarMixer::handleReplicatedBulkAvatarPacket));
auto nodeList = DependencyManager::get<NodeList>();
connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &AvatarMixer::handlePacketVersionMismatch);
@ -101,7 +114,7 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) :
});
}
SharedNodePointer addOrUpdateReplicatedNode(const QUuid& nodeID, const HifiSockAddr& senderSockAddr) {
SharedNodePointer addOrUpdateReplicatedNode(const QUuid& nodeID, const SockAddr& senderSockAddr) {
auto replicatedNode = DependencyManager::get<NodeList>()->addOrUpdateNode(nodeID, NodeType::Agent,
senderSockAddr,
senderSockAddr,
@ -964,7 +977,7 @@ void AvatarMixer::domainSettingsRequestComplete() {
start();
}
void AvatarMixer::handlePacketVersionMismatch(PacketType type, const HifiSockAddr& senderSockAddr, const QUuid& senderUUID) {
void AvatarMixer::handlePacketVersionMismatch(PacketType type, const SockAddr& senderSockAddr, const QUuid& senderUUID) {
// if this client is using packet versions we don't expect.
if ((type == PacketTypeEnum::Value::AvatarIdentity || type == PacketTypeEnum::Value::AvatarData) && !senderUUID.isNull()) {
// Echo an empty AvatarData packet back to that client.

View file

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

View file

@ -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.

View file

@ -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);

View file

@ -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();

View file

@ -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;
}

View file

@ -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.
*/

View file

@ -59,8 +59,7 @@ EntityServer::EntityServer(ReceivedMessage& message) :
PacketType::ChallengeOwnership,
PacketType::ChallengeOwnershipRequest,
PacketType::ChallengeOwnershipReply },
this,
"handleEntityPacket");
PacketReceiver::makeSourcedListenerReference<EntityServer>(this, &EntityServer::handleEntityPacket));
connect(&_dynamicDomainVerificationTimer, &QTimer::timeout, this, &EntityServer::startDynamicDomainVerification);
_dynamicDomainVerificationTimer.setSingleShot(true);

View file

@ -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.
*

View file

@ -20,14 +20,18 @@
#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)
{
connect(DependencyManager::get<NodeList>().data(), &NodeList::nodeKilled, this, &MessagesMixer::nodeKilled);
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::MessagesData, this, "handleMessages");
packetReceiver.registerListener(PacketType::MessagesSubscribe, this, "handleMessagesSubscribe");
packetReceiver.registerListener(PacketType::MessagesUnsubscribe, this, "handleMessagesUnsubscribe");
packetReceiver.registerListener(PacketType::MessagesData,
PacketReceiver::makeSourcedListenerReference<MessagesMixer>(this, &MessagesMixer::handleMessages));
packetReceiver.registerListener(PacketType::MessagesSubscribe,
PacketReceiver::makeSourcedListenerReference<MessagesMixer>(this, &MessagesMixer::handleMessagesSubscribe));
packetReceiver.registerListener(PacketType::MessagesUnsubscribe,
PacketReceiver::makeSourcedListenerReference<MessagesMixer>(this, &MessagesMixer::handleMessagesUnsubscribe));
}
void MessagesMixer::nodeKilled(SharedNodePointer killedNode) {
@ -41,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());
@ -57,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);
}
}
@ -85,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;
}

View file

@ -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

View file

@ -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.

View file

@ -34,6 +34,7 @@
#include <QtCore/QDir>
#include <OctreeDataUtils.h>
#include <ThreadHelpers.h>
Q_LOGGING_CATEGORY(octree_server, "hifi.octree-server")
@ -1122,8 +1123,10 @@ void OctreeServer::run() {
void OctreeServer::domainSettingsRequestComplete() {
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket");
packetReceiver.registerListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket");
packetReceiver.registerListener(PacketType::OctreeDataNack,
PacketReceiver::makeSourcedListenerReference<OctreeServer>(this, &OctreeServer::handleOctreeDataNackPacket));
packetReceiver.registerListener(getMyQueryMessageType(),
PacketReceiver::makeSourcedListenerReference<OctreeServer>(this, &OctreeServer::handleOctreeQueryPacket));
qDebug(octree_server) << "Received domain settings";
@ -1190,7 +1193,10 @@ void OctreeServer::domainSettingsRequestComplete() {
_persistAsFileType);
_persistManager->moveToThread(&_persistThread);
connect(&_persistThread, &QThread::finished, _persistManager, &QObject::deleteLater);
connect(&_persistThread, &QThread::started, _persistManager, &OctreePersistThread::start);
connect(&_persistThread, &QThread::started, _persistManager, [this] {
setThreadName("OctreePersistThread");
_persistManager->start();
});
connect(_persistManager, &OctreePersistThread::loadCompleted, this, [this]() {
beginRunning();
});

View file

@ -83,13 +83,18 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
this, "handleOctreePacket");
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleOctreePacket));
packetReceiver.registerListener(PacketType::SelectedAudioFormat,
PacketReceiver::makeUnsourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleSelectedAudioFormat));
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
packetReceiver.registerListener(PacketType::ReloadEntityServerScript,
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleReloadEntityServerScriptPacket));
packetReceiver.registerListener(PacketType::EntityScriptGetStatus,
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleEntityScriptGetStatusPacket));
packetReceiver.registerListener(PacketType::EntityServerScriptLog,
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleEntityServerScriptLogPacket));
packetReceiver.registerListener(PacketType::EntityScriptCallMethod,
PacketReceiver::makeSourcedListenerReference<EntityScriptServer>(this, &EntityScriptServer::handleEntityScriptCallMethodPacket));
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
auto timer = new QTimer(this);
@ -465,7 +470,9 @@ void EntityScriptServer::resetEntitiesScriptEngine() {
scriptEngines->runScriptInitializers(newEngine);
newEngine->runInThread();
auto newEngineSP = qSharedPointerCast<EntitiesScriptEngineProvider>(newEngine);
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(newEngineSP);
// On the entity script server, these are the same
DependencyManager::get<EntityScriptingInterface>()->setPersistentEntitiesScriptEngine(newEngineSP);
DependencyManager::get<EntityScriptingInterface>()->setNonPersistentEntitiesScriptEngine(newEngineSP);
if (_entitiesScriptEngine) {
disconnect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated,

View file

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

View file

@ -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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View file

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

View file

@ -4,6 +4,7 @@
#
# Created by Leonardo Murillo on 12/16/2015.
# Copyright 2015 High Fidelity, Inc.
# Copyright 2021 Vircadia contributors.
#
# Distributed under the Apache License, Version 2.0.
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -20,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")
@ -31,7 +32,7 @@ macro(GENERATE_INSTALLERS)
set(CPACK_PACKAGE_NAME ${_DISPLAY_NAME})
set(CPACK_PACKAGE_VENDOR "Vircadia")
set(CPACK_PACKAGE_VERSION ${BUILD_VERSION})
set(CPACK_PACKAGE_FILE_NAME "Vircadia-Alpha${_PACKAGE_NAME_EXTRA}-${BUILD_VERSION}")
set(CPACK_PACKAGE_FILE_NAME "Vircadia${_PACKAGE_NAME_EXTRA}-${BUILD_VERSION}-${RELEASE_NAME}")
set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME})
set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME})
if (PR_BUILD)
@ -95,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
@ -122,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)

View file

@ -26,5 +26,6 @@ function(LINK_HIFI_LIBRARIES)
endforeach()
setup_memory_debugger()
setup_thread_debugger()
endfunction()

View file

@ -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}
)

View file

@ -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)

View file

@ -10,7 +10,7 @@
#
macro(optional_win_executable_signing)
if (WIN32 AND PRODUCTION_BUILD)
if (WIN32 AND PRODUCTION_BUILD AND NOT BYPASS_SIGNING)
if (DEFINED ENV{HF_PFX_FILE})
if (DEFINED ENV{HF_PFX_PASSPHRASE})
message(STATUS "Executable for ${TARGET_NAME} will be signed with SignTool.")

View file

@ -4,6 +4,7 @@
#
# Created by Leonardo Murillo on 07/14/2015.
# Copyright 2015 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
@ -22,8 +23,13 @@ macro(SET_PACKAGING_PARAMETERS)
set_from_env(RELEASE_TYPE RELEASE_TYPE "DEV")
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}")
@ -32,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)
@ -39,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
@ -62,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
@ -71,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
@ -79,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")
@ -119,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")
@ -141,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 ()
@ -174,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(APP_USER_MODEL_ID "com.highfidelity.console")
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}")

View file

@ -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)

View file

@ -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})

View file

@ -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")

View file

@ -5,6 +5,9 @@
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
# For understanding the execution flow followed by the Qt setup,
# please look at the comment on top of hifi_qt.py
function(get_sub_directories result curdir)
file(GLOB children RELATIVE ${curdir} ${curdir}/*)
set(dirlist "")
@ -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()

View file

@ -1,6 +1,6 @@
macro(target_oculus_mobile)
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/oculus_1.22/VrApi)
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/ovr_sdk_mobile_1.37.0/VrApi)
# Mobile SDK
set(OVR_MOBILE_INCLUDE_DIRS ${INSTALL_DIR}/Include)
@ -12,7 +12,7 @@ macro(target_oculus_mobile)
target_link_libraries(${TARGET_NAME} ${OVR_MOBILE_LIBRARIES})
# Platform SDK
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/oculusPlatform)
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/ovr_platform_sdk_23.0.0)
set(OVR_PLATFORM_INCLUDE_DIRS ${INSTALL_DIR}/Include)
target_include_directories(${TARGET_NAME} PRIVATE ${OVR_PLATFORM_INCLUDE_DIRS})
set(OVR_PLATFORM_LIBRARIES ${INSTALL_DIR}/Android/libs/arm64-v8a/libovrplatformloader.so)

View 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)

View file

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

View file

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

View file

@ -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
)

View file

@ -19,7 +19,7 @@ include(vcpkg_common_functions)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO kasenvr/etc2comp
REPO vircadia/etc2comp
REF 7f1843bf07825c21cab711360c1ddbad04641036
SHA512 d747076acda8537d39585858c793a35c3dcc9ef283d723619a47f8c81ec1454c95b3340ad35f0655a939eae5b8271c801c48a9a7568311a01903a344c44af25b
HEAD_REF master

View file

@ -2,13 +2,22 @@ include(vcpkg_common_functions)
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
file(READ "${VCPKG_ROOT_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" EXTERNAL_BUILD_ASSETS)
file(READ "${VCPKG_ROOT_DIR}/_env/USE_GLES.txt" USE_GLES)
# GitHub Actions Android builds fail with `FILENAME` set while desktop builds with GLES fail without a set `FILENAME`.
if (ANDROID)
vcpkg_download_distfile(
SOURCE_ARCHIVE
URLS ${EXTERNAL_BUILD_ASSETS}/dependencies/glad/glad32es.zip
SHA512 2e02ac633eed8f2ba2adbf96ea85d08998f48dd2e9ec9a88ec3c25f48eaf1405371d258066327c783772fcb3793bdb82bd7375fdabb2ba5e2ce0835468b17f65
)
elseif (USE_GLES)
vcpkg_download_distfile(
SOURCE_ARCHIVE
URLS ${EXTERNAL_BUILD_ASSETS}/dependencies/glad/glad32es.zip
SHA512 2e02ac633eed8f2ba2adbf96ea85d08998f48dd2e9ec9a88ec3c25f48eaf1405371d258066327c783772fcb3793bdb82bd7375fdabb2ba5e2ce0835468b17f65
FILENAME glad32es.zip
)
else()
# else Linux desktop
vcpkg_download_distfile(

View file

@ -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

View file

@ -3,7 +3,7 @@ include(vcpkg_common_functions)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO kasenvr/scribe
REPO vircadia/scribe
REF 1bd638a36ca771e5a68d01985b6389b71835cbd2
SHA512 dbe241d86df3912e544f6b9839873f9875df54efc93822b145e7b13243eaf2e3d690bc8a28b1e52d05bdcd7e68fca6b0b2f5c43ffd0f56a9b7a50d54dcf9e31e
HEAD_REF master

View file

@ -9,9 +9,9 @@ include(vcpkg_common_functions)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO kasenvr/nvidia-texture-tools
REF 330c4d56274a0f602a5c70596e2eb670a4ed56c2
SHA512 4c0bc2f369120d696cc27710b6d33086b27eef55f537ec66b9a5c8b1839bc2426c0413670b0f65be52c5d353468f0126dfe024be1f0690611d4d7e33ac530127
REPO vircadia/nvidia-texture-tools
REF d8b7a98aeb177b5eddb76571183bbd2f95d54e6c
SHA512 ea15ffd19eb1e14c8ebd62f8d7de3df1ecf6c18a339025f4a0e13419717d510903fc126ec6d1bdfbb5a2f4525a922412b72318bc8dd55dd000481a3924fbfcd4
HEAD_REF master
)

View file

@ -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.

View file

@ -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=(.*)$/)
{

View file

@ -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';

View file

@ -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

View file

@ -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})

View file

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

View file

@ -3,8 +3,8 @@ include(vcpkg_common_functions)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO oneapi-src/oneTBB
REF 4bdba61bafc6ba2d636f31564f1de5702d365cf7
SHA512 f2a8d7e0476f846039390f4a79af3fe13770e23b01bf4741e738136f7ddb401357a0e50f35212e8d0fa5fc4cf1563418337309227d7243fc3676edd406ae652d
REF eca91f16d7490a8abfdee652dadf457ec820cc37
SHA512 7144e1dc68304b5358e6ea330431b6f0c61fadb147efa353a5b242777d6fabf7b8cf99b79cffb51b49b911dd17a9f1879619d6eebdf319f23ec3235c89cffc25
HEAD_REF tbb_2019
PATCHES fix-static-build.patch
)

View file

@ -4,6 +4,7 @@
//
// Created by Stephen Birarda on 1/14/16.
// Copyright 2015 High Fidelity, Inc.
// Copyright 2021 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -24,10 +25,12 @@ namespace BuildInfo {
const QString MODIFIED_ORGANIZATION = "@BUILD_ORGANIZATION@";
const QString ORGANIZATION_DOMAIN = "vircadia.com";
const QString VERSION = "@BUILD_VERSION@";
const QString RELEASE_NAME = "@RELEASE_NAME@";
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,

View file

@ -2,18 +2,19 @@
# CPackProperties.cmake.in
# cmake/templates
#
# Copyright 2016 High Fidelity, Inc.
# Created by Stephen Birarda on January 11, 2016
# Copyright 2016 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
#
set(INTERFACE_DISPLAY_NAME "Interface")
set(INTERFACE_DISPLAY_NAME "Vircadia")
set(INTERFACE_SHORTCUT_NAME "@INTERFACE_SHORTCUT_NAME@")
set(INTERFACE_HF_SHORTCUT_NAME "@INTERFACE_HF_SHORTCUT_NAME@")
set(INTERFACE_WIN_EXEC_NAME "@INTERFACE_EXEC_PREFIX@.exe")
set(CONSOLE_DISPLAY_NAME "Console")
set(CONSOLE_DISPLAY_NAME "Vircadia Server Console")
set(CONSOLE_INSTALL_SUBDIR "@CONSOLE_INSTALL_DIR@")
set(CONSOLE_SHORTCUT_NAME "@CONSOLE_SHORTCUT_NAME@")
set(CONSOLE_HF_SHORTCUT_NAME "@CONSOLE_HF_SHORTCUT_NAME@")
@ -22,9 +23,9 @@ set(SANDBOX_HF_SHORTCUT_NAME "@SANDBOX_HF_SHORTCUT_NAME@")
set(CONSOLE_WIN_EXEC_NAME "@CONSOLE_EXEC_NAME@")
set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "@PRE_SANDBOX_INTERFACE_SHORTCUT_NAME@")
set(PRE_SANDBOX_CONSOLE_SHORTCUT_NAME "@PRE_SANDBOX_CONSOLE_SHORTCUT_NAME@")
set(DS_DISPLAY_NAME "Domain Server")
set(DS_DISPLAY_NAME "Vircadia Domain Server")
set(DS_EXEC_NAME "@DS_EXEC_NAME@")
set(AC_DISPLAY_NAME "Assignment Client")
set(AC_DISPLAY_NAME "Vircadia Assignment Client")
set(AC_EXEC_NAME "@AC_EXEC_NAME@")
set(HIGH_FIDELITY_PROTOCOL "@HIGH_FIDELITY_PROTOCOL@")
set(HIGH_FIDELITY_APP_PROTOCOL "@HIGH_FIDELITY_APP_PROTOCOL@")

View file

@ -202,9 +202,9 @@
; The Inner invocation has written an uninstaller binary for us.
; We need to sign it if it's a production or PR build.
!if @PRODUCTION_BUILD@ == 1
!if @BYPASS_SIGNING@ == 1
!if @BYPASS_SIGNING@ == TRUE
!warning "BYPASS_SIGNING set - installer will not be signed"
!else
!else
!system '"@SIGNTOOL_EXECUTABLE@" sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://timestamp.comodoca.com?td=sha256 /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0
!endif
!endif
@ -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
@ -636,6 +636,7 @@ Var Express
; figure out where to download installer slideshow images from
StrCpy $0 "http://cdn.highfidelity.com/installer/slideshow"
; Is this in use anymore?
${If} $CampaignName == ""
StrCpy $0 "$0/default"
@ -717,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
@ -836,16 +837,24 @@ Function PostInstallOptionsPage
!insertmacro SetInstallOption $DesktopClientCheckbox @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ ${BST_CHECKED}
${EndIf}
; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs.
;${If} @SERVER_COMPONENT_CONDITIONAL@
; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @SANDBOX_HF_SHORTCUT_NAME@"
;${Else}
; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@"
;${EndIf}
;Pop $DesktopConsoleCheckbox
;IntOp $CurrentOffset $CurrentOffset + 15
;
;; set the checkbox state depending on what is present in the registry
;!insertmacro SetInstallOption $DesktopConsoleCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED}
${If} @SERVER_COMPONENT_CONDITIONAL@
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @SANDBOX_HF_SHORTCUT_NAME@"
${Else}
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@"
Pop $DesktopConsoleCheckbox
IntOp $CurrentOffset $CurrentOffset + 15
; set the checkbox state depending on what is present in the registry
!insertmacro SetInstallOption $DesktopConsoleCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED}
${EndIf}
Pop $DesktopConsoleCheckbox
IntOp $CurrentOffset $CurrentOffset + 15
; set the checkbox state depending on what is present in the registry
!insertmacro SetInstallOption $DesktopConsoleCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED}
${If} @CLIENT_COMPONENT_CONDITIONAL@
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @INTERFACE_HF_SHORTCUT_NAME@ after install"
@ -860,31 +869,54 @@ Function PostInstallOptionsPage
${EndIf}
${EndIf}
; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs.
;${If} @SERVER_COMPONENT_CONDITIONAL@
; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ after install"
;${Else}
; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install"
;${EndIf}
;Pop $LaunchConsoleNowCheckbox
;
;; set the checkbox state depending on what is present in the registry
;!insertmacro SetInstallOption $LaunchConsoleNowCheckbox @SERVER_LAUNCH_NOW_REG_KEY@ ${BST_UNCHECKED}
;${StrContains} $substringResult "/forceNoLaunchServer" $CMDLINE
;${IfNot} $substringResult == ""
; ${NSD_SetState} $LaunchConsoleNowCheckbox ${BST_UNCHECKED}
;${EndIf}
;IntOp $CurrentOffset $CurrentOffset + 15
${If} @SERVER_COMPONENT_CONDITIONAL@
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ after install"
${Else}
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install"
${EndIf}
Pop $LaunchConsoleNowCheckbox
; set the checkbox state depending on what is present in the registry
!insertmacro SetInstallOption $LaunchConsoleNowCheckbox @SERVER_LAUNCH_NOW_REG_KEY@ ${BST_UNCHECKED}
${StrContains} $substringResult "/forceNoLaunchServer" $CMDLINE
${IfNot} $substringResult == ""
Pop $LaunchConsoleNowCheckbox
; set the checkbox state depending on what is present in the registry
!insertmacro SetInstallOption $LaunchConsoleNowCheckbox @SERVER_LAUNCH_NOW_REG_KEY@ ${BST_UNCHECKED}
${StrContains} $substringResult "/forceNoLaunchServer" $CMDLINE
${IfNot} $substringResult == ""
${NSD_SetState} $LaunchConsoleNowCheckbox ${BST_UNCHECKED}
${EndIf}
IntOp $CurrentOffset $CurrentOffset + 15
${EndIf}
IntOp $CurrentOffset $CurrentOffset + 30
${If} @SERVER_COMPONENT_CONDITIONAL@
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ on startup"
${Else}
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup"
${EndIf}
Pop $ConsoleStartupCheckbox
IntOp $CurrentOffset $CurrentOffset + 15
; set the checkbox state depending on what is present in the registry
!insertmacro SetInstallOption $ConsoleStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_UNCHECKED}
; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs.
;${If} @SERVER_COMPONENT_CONDITIONAL@
; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ on startup"
;${Else}
; ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup"
;${EndIf}
;Pop $ConsoleStartupCheckbox
;IntOp $CurrentOffset $CurrentOffset + 15
;
;; set the checkbox state depending on what is present in the registry
;!insertmacro SetInstallOption $ConsoleStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_UNCHECKED}
${If} @SERVER_COMPONENT_CONDITIONAL@
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @SANDBOX_HF_SHORTCUT_NAME@ on startup"
Pop $ConsoleStartupCheckbox
IntOp $CurrentOffset $CurrentOffset + 15
; set the checkbox state depending on what is present in the registry
!insertmacro SetInstallOption $ConsoleStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_UNCHECKED}
${EndIf}
${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Perform a clean install (Delete older settings and content)"
Pop $CleanInstallCheckbox
@ -956,13 +988,29 @@ FunctionEnd
Function ReadPostInstallOptions
; check if the user asked for a desktop shortcut to console
${NSD_GetState} $DesktopConsoleCheckbox $DesktopConsoleState
${LogText} "Option: Start Desktop Console: $DesktopConsoleState"
; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs.
;; check if the user asked for a desktop shortcut to console
;${NSD_GetState} $DesktopConsoleCheckbox $DesktopConsoleState
;${LogText} "Option: Start Desktop Console: $DesktopConsoleState"
${If} @SERVER_COMPONENT_CONDITIONAL@
; check if the user asked for a desktop shortcut to console
${NSD_GetState} $DesktopConsoleCheckbox $DesktopConsoleState
${LogText} "Option: Start Desktop Console: $DesktopConsoleState"
${Else}
StrCpy $DesktopConsoleState ${BST_UNCHECKED}
${EndIf}
; check if the user asked to have console launched every startup
${NSD_GetState} $ConsoleStartupCheckbox $ConsoleStartupState
${LogText} "Option: Start Desktop Console On Startup: $ConsoleStartupState"
; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs.
;; check if the user asked to have console launched every startup
;${NSD_GetState} $ConsoleStartupCheckbox $ConsoleStartupState
;${LogText} "Option: Start Desktop Console On Startup: $ConsoleStartupState"
${If} @SERVER_COMPONENT_CONDITIONAL@
; check if the user asked to have console launched every startup
${NSD_GetState} $ConsoleStartupCheckbox $ConsoleStartupState
${LogText} "Option: Start Desktop Console On Startup: $ConsoleStartupState"
${Else}
StrCpy $ConsoleStartupState ${BST_UNCHECKED}
${EndIf}
${If} @SERVER_COMPONENT_CONDITIONAL@
${LogText} "Option: Install Server"
@ -1298,19 +1346,23 @@ 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_SHORTCUT_NAME@.lnk" \
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_HF_SHORTCUT_NAME@.lnk" \
"$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
; Set appUserModelId
ApplicationID::Set "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@"
ApplicationID::Set "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_HF_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@"
${Else}
; handling for interface only console shortcut
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_SHORTCUT_NAME@.lnk"
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \
"$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
; Set appUserModelId
ApplicationID::Set "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@"
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\@SANDBOX_HF_SHORTCUT_NAME@.lnk"
; FIXME: Re-enable or permanently remove system tray "Console" for Interface-only installs.
;CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \
; "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
;; Set appUserModelId
;ApplicationID::Set "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" "@APP_USER_MODEL_ID@"
${EndIf}
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\@UNINSTALLER_NAME@"
@ -1517,7 +1569,7 @@ Section "Uninstall"
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@SANDBOX_SHORTCUT_NAME@.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@SANDBOX_HF_SHORTCUT_NAME@.lnk"
Delete "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk"
Delete "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk"
Delete "$DESKTOP\@SANDBOX_HF_SHORTCUT_NAME@.lnk"
@ -1558,7 +1610,7 @@ Section "Uninstall"
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@INTERFACE_SHORTCUT_NAME@.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@CONSOLE_SHORTCUT_NAME@.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@SANDBOX_SHORTCUT_NAME@.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\@SANDBOX_HF_SHORTCUT_NAME@.lnk"
@CPACK_NSIS_DELETE_ICONS_EXTRA@
;Delete empty start menu parent diretories

2
debian/rules vendored
View file

@ -6,7 +6,7 @@
override_dh_auto_configure:
mkdir obj-$(DEB_TARGET_MULTIARCH)
(cd obj-$(DEB_TARGET_MULTIARCH) && cmake .. -DCMAKE_INSTALL_PREFIX=/opt/hifi -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON "-GUnix Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCLIENT_ONLY=ON -DDOWNLOAD_SERVERLESS_CONTENT=ON -DCMAKE_CXX_COMPILER=/usr/lib/llvm-7/bin/clang\+\+ -DOpenGL_GL_PREFERENCE=GLVND)
(cd obj-$(DEB_TARGET_MULTIARCH) && cmake .. -DCMAKE_INSTALL_PREFIX=/opt/hifi -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON "-GUnix Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCLIENT_ONLY=ON -DDOWNLOAD_SERVERLESS_CONTENT=ON -DCMAKE_CXX_COMPILER=/usr/lib/llvm-7/bin/clang\+\+ -DOpenGL_GL_PREFERENCE=LEGACY)
override_dh_auto_build:
(cd obj-$(DEB_TARGET_MULTIARCH) && make -j4)

View file

@ -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

View file

@ -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 &ldquo;locked&rdquo; 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&rsquo;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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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 &ldquo;locked&rdquo; 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&rsquo;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",
@ -1888,7 +1959,7 @@
"name": "provider",
"label": "Provider",
"help": "OAuth provider URL.",
"default": "https://metaverse.highfidelity.com",
"default": "https://metaverse.vircadia.com/live",
"advanced": true,
"backup": false
},
@ -2013,6 +2084,23 @@
}
]
},
{
"name": "domain_server",
"label": "Setup Domain Server",
"restart": false,
"hidden": true,
"settings": [
{
"name": "network_address",
"default": ""
},
{
"name": "network_port",
"type": "int",
"default": 0
}
]
},
{
"name": "installed_content",
"label": "Installed Content",

View file

@ -2,7 +2,7 @@
//
// index.html
//
// Created by kasenvr@gmail.com on 21 Jul 2020
// Created by somnilibertas@gmail.com on 21 Jul 2020
// Copyright 2020 Vircadia and contributors.
//
// Distributed under the Apache License, Version 2.0.

View file

@ -1,3 +1,3 @@
// Here you can put a script that will be run by an assignment-client (AC)
// For examples, please go to https://github.com/kasenvr/project-athena/tree/master/script-archive/acScripts
// For examples, please go to https://github.com/vircadia/vircadia/tree/master/script-archive/acScripts
// The directory named acScripts contains assignment-client specific scripts you can try.

View file

@ -129,9 +129,10 @@ function getCurrentDomainIDType() {
return DOMAIN_ID_TYPE_UNKNOWN;
}
if (DomainInfo !== null) {
if (DomainInfo.name !== undefined) {
return DOMAIN_ID_TYPE_TEMP;
}
// Disabled because detecting as temp domain... and we're not even using temp domains right now.
// if (DomainInfo.name !== undefined) {
// return DOMAIN_ID_TYPE_TEMP;
// }
return DOMAIN_ID_TYPE_FULL;
}
return DOMAIN_ID_TYPE_UNKNOWN;
@ -500,6 +501,31 @@ function prepareAccessTokenPrompt(callback) {
});
}
function createDomainIDPrompt(callback) {
swal({
title: 'Finish Registering Domain',
type: 'input',
text: 'Enter a label for this Domain Server.</br></br>This will help you identify which domain ID belongs to which server.</br></br>This is a required step for registration.</br></br>Acceptable characters are [A-Z][a-z0-9]+-_.</br',
showCancelButton: true,
confirmButtonText: "Create",
closeOnConfirm: false,
html: true
}, function (inputValue) {
if (inputValue === false) {
return false;
}
if (inputValue === "") {
swal.showInputError("Please enter a valid label for your machine.");
return false;
}
if (callback) {
callback(inputValue);
}
});
}
function getMetaverseUrl(callback) {
$.ajax('/api/metaverse_info', {
success: function(data) {

View file

@ -40,6 +40,8 @@ $(document).ready(function(){
// call our method to setup the place names table
setupPlacesTable();
// hide the places table for now because we do not want that interacted with from the domain-server
$('#' + Settings.PLACES_TABLE_ID).hide();
setupDomainNetworkingSettings();
// setupDomainLabelSetting();
@ -363,7 +365,7 @@ $(document).ready(function(){
confirmButtonText: "Create",
closeOnConfirm: false,
html: true
}, function(inputValue){
}, function (inputValue) {
if (inputValue === false) {
swal.close();
@ -373,7 +375,7 @@ $(document).ready(function(){
}
} else {
// we're going to change the alert to a new one with a spinner while we create this domain
showSpinnerAlert('Creating domain ID');
// showSpinnerAlert('Creating domain ID');
createNewDomainID(inputValue, justConnected);
}
});
@ -385,7 +387,12 @@ $(document).ready(function(){
"label": label
}
$.post("/api/domains", domainJSON, function(data){
$.post("/api/domains", domainJSON, function(data) {
if (data.status === "failure") {
failedToCreateDomainID(data, justConnected);
return;
}
// we successfully created a domain ID, set it on that field
var domainID = data.domain.domainId;
console.log("Setting domain id to ", data, domainID);
@ -406,40 +413,50 @@ $(document).ready(function(){
text: successText,
html: true,
confirmButtonText: 'Save'
}, function(){
}, function () {
saveSettings();
});
}, 'json').fail(function(){
}, 'json').fail(function (data) {
failedToCreateDomainID(data, justConnected);
});
}
function failedToCreateDomainID(data, justConnected) {
var errorText = "There was a problem creating your new domain ID. Do you want to try again or";
var errorText = "There was a problem creating your new domain ID. Do you want to try again or";
if (data && data.status === "failure") {
errorText = "Error: " + data.error + "</br>Do you want to try again or";
console.log("Error: " + data.error);
} else {
console.log("Error: Failed to post to metaverse.");
}
if (justConnected) {
errorText += " just save your new access token?</br></br>You can always create a new domain ID later.";
if (justConnected) {
errorText += " just save your new access token?</br></br>You can always create a new domain ID later.";
} else {
errorText += " cancel?"
}
// we failed to create the new domain ID, show a sweet-alert that lets them try again or cancel
swal({
title: '',
type: 'error',
text: errorText,
html: true,
confirmButtonText: 'Try again',
showCancelButton: true,
closeOnConfirm: false
}, function (isConfirm) {
if (isConfirm) {
// they want to try creating a domain ID again
showDomainCreationAlert(justConnected);
} else {
errorText += " cancel?"
}
// we failed to create the new domain ID, show a sweet-alert that lets them try again or cancel
swal({
title: '',
type: 'error',
text: errorText,
html: true,
confirmButtonText: 'Try again',
showCancelButton: true,
closeOnConfirm: false
}, function(isConfirm){
if (isConfirm) {
// they want to try creating a domain ID again
showDomainCreationAlert(justConnected);
} else {
// they want to cancel
if (justConnected) {
// since they just connected we need to save the access token here
saveSettings();
}
// they want to cancel
if (justConnected) {
// since they just connected we need to save the access token here
saveSettings();
}
});
}
});
}
@ -711,8 +728,8 @@ $(document).ready(function(){
name: 'places',
label: 'Places',
html_id: Settings.PLACES_TABLE_ID,
help: "The following places currently point to this domain.</br>To point places to this domain, "
+ " go to the <a href='" + METAVERSE_URL + "/user/places'>My Places</a> "
help: "To point places to this domain, "
+ " go to the <a href='" + METAVERSE_URL + "/user/places'>Places</a> "
+ "page in your Metaverse account.",
read_only: true,
can_add_new_rows: false,
@ -745,9 +762,10 @@ $(document).ready(function(){
var errorEl = createDomainLoadingError("There was an error retrieving your places.");
$("#" + Settings.PLACES_TABLE_ID).after(errorEl);
var temporaryPlaceButton = dynamicButton(Settings.GET_TEMPORARY_NAME_BTN_ID, 'Get a temporary place name');
temporaryPlaceButton.hide();
$('#' + Settings.PLACES_TABLE_ID).after(temporaryPlaceButton);
// DISABLE TEMP PLACE NAME BUTTON...
// var temporaryPlaceButton = dynamicButton(Settings.GET_TEMPORARY_NAME_BTN_ID, 'Get a temporary place name');
// temporaryPlaceButton.hide();
// $('#' + Settings.PLACES_TABLE_ID).after(temporaryPlaceButton);
if (accessTokenIsSet()) {
appendAddButtonToPlacesTable();
}

View file

@ -19,12 +19,12 @@
</dl>
</div>
<div class="wizard-step col-md-8 col-centered" style="display: none;">
<!-- <div class="wizard-step col-md-8 col-centered" style="display: none;">
<h4 class="step-title"></h4>
<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>
@ -51,12 +51,12 @@
<button type="button" class="btn btn-md btn-block btn-primary next-button">Next</button>
</dd>
</dl>
</div>
</div> -->
<div class="wizard-step col-md-9 col-centered" style="display: none;">
<h4 class="step-title"></h4>
<div class="row">
<p id="permissions-description" class="col-md-12 step-info"><b>Localhost</b> has been granted administrator privileges to this domain. (Localhost is any</br>user on the same machine as the Vircadia Server)</p>
<p id="permissions-description" class="col-md-12 step-info"><b>Localhost</b> has been granted administrator privileges to this domain. (Localhost is any</br>user on the same machine as the Vircadia server)</p>
</div>
<div id="admin-row" class="row">
<p class="col-md-6">
@ -186,7 +186,37 @@
<button type="button" class="btn btn-md btn-block btn-default back-button">Back</button>
</dd>
<dd class="col-md-3 col-md-offset-6">
<button id="save-username-password" type="button" class="btn btn-md btn-block btn-primary">Finish</button>
<button id="save-username-password" type="button" class="btn btn-md btn-block btn-primary next-button">Next</button>
</dd>
</dl>
</div>
<div class="wizard-step col-md-8 col-centered" style="display: none;">
<h4 class="step-title"></h4>
<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.
If you are running this server on a powerful system and intend to have a large audience, then turn this setting on.
</span>
</div>
</div>
<br />
<div id="automatic-threading-options-row" class="row">
<p class="col-md-12">
<label>
<input id="enable-automatic-threading" name="threading-checkbox" type="checkbox" value="true"> Enable Automatic Threading
</label>
</p>
</div>
<dl class="row">
<dd class="col-md-3">
<button type="button" class="btn btn-md btn-block btn-default back-button">Back</button>
</dd>
<dd class="col-md-3 col-md-offset-6">
<button id="save-threading-settings" type="button" class="btn btn-md btn-block btn-primary">Finish</button>
</dd>
</dl>
</div>
@ -201,7 +231,7 @@
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<p id="main-description" class="step-info">You have successfully setup and configured your cloud hosted domain.</p>
<p id="main-description" class="step-info">You have successfully setup and configured your Vircadia domain.</p>
</div>
</div>

View file

@ -50,12 +50,17 @@ $(document).ready(function(){
prepareAccessTokenPrompt(function(accessToken) {
Metaverse.accessToken = accessToken;
saveAccessToken();
promptToCreateDomainID();
});
});
$('body').on('click', '#save-permissions', function() {
savePermissions();
});
$('body').on('click', '#save-permissions', function() {
savePermissions();
});
$('body').on('click', '#save-threading-settings', function() {
saveThreadingSettings();
});
function triggerSaveUsernamePassword(event) {
if (event.keyCode === 13) {
@ -151,7 +156,7 @@ function setupWizardSteps() {
$('#admin-description').html('Add more Metaverse usernames');
} else {
$('.cloud-only').remove();
$('#save-permissions').text("Finish");
$('#save-threading-settings').text("Finish");
steps = $('.wizard-step');
$(steps).each(function(i) {
@ -167,6 +172,49 @@ function setupWizardSteps() {
$(currentStep).show();
}
function promptToCreateDomainID() {
setTimeout(function () {
createDomainIDPrompt(function (label) {
var domainJSON = {
"label": label
};
$.post("/api/domains", domainJSON, function (data) {
if (data.status === "failure") {
swal.showInputError("Error: " + data.error);
return;
}
swal.close();
// we successfully created a domain ID, set it on that field
var domainID = data.domain.domainId;
console.log("Setting domain ID to ", data, domainID);
var formJSON = {
"metaverse": {
"automatic_networking": "full",
"id": domainID
},
"descriptors": {
"world_name": label
}
};
// POST the form JSON to the domain-server settings.json endpoint so the settings are saved
postSettings(formJSON, goToNextStep);
}, 'json').fail(function (data) {
if (data && data.status === "failure") {
swal.showInputError("Error: " + data.error);
} else {
swal.showInputError("Error: Failed to post to metaverse.");
}
console.log("Failed to create domain ID...");
});
});
}, 500); // Apparently swal needs time before opening another prompt.
}
function updatePlaceNameLink(address) {
if (address) {
var url = URLs.PLACE_URL + '/' + address;
@ -260,10 +308,6 @@ function goToNextStep() {
var currentStep = $('body').find('.wizard-step:visible');
var nextStep = currentStep.next('.wizard-step');
var formJSON = {
"wizard": {}
}
if (nextStep.length > 0) {
currentStep.hide();
nextStep.show();
@ -341,7 +385,7 @@ function saveAccessToken() {
$(this).blur();
// POST the form JSON to the domain-server settings.json endpoint so the settings are saved
postSettings(formJSON, goToNextStep);
postSettings(formJSON);
}
function getSettingDescriptionForKey(groupKey, settingKey) {
@ -421,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,
@ -429,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,
@ -437,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,
@ -446,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,
@ -521,7 +569,29 @@ function saveUsernamePassword() {
$(this).blur();
// POST the form JSON to the domain-server settings.json endpoint so the settings are saved
postSettings(formJSON, function() {
location.reload();
});
postSettings(formJSON, goToNextStep);
}
function saveThreadingSettings() {
var enable_automatic_threading = $("#enable-automatic-threading").prop("checked");
currentStepNumber += 1;
var formJSON = {
"audio_threading": {
"auto_threads": enable_automatic_threading
},
"avatar_mixer": {
"auto_threads": enable_automatic_threading
},
"wizard": {
"steps_completed": currentStepNumber.toString()
}
}
// remove focus from the button
$(this).blur();
// POST the form JSON to the domain-server settings.json endpoint so the settings are saved
postSettings(formJSON, goToNextStep);
}

View file

@ -17,7 +17,8 @@
#include <openssl/x509.h>
#include <random>
#include <QDataStream>
#include <QtCore/QDataStream>
#include <QtCore/QMetaMethod>
#include <AccountManager.h>
#include <Assignment.h>
@ -352,10 +353,11 @@ 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
HifiSockAddr connectingAddr = node->getActiveSocket() ? *node->getActiveSocket() : node->getPublicSocket();
SockAddr connectingAddr = node->getActiveSocket() ? *node->getActiveSocket() : node->getPublicSocket();
QString hardwareAddress;
QUuid machineFingerprint;
@ -447,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;
}
@ -648,7 +651,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
}
SharedNodePointer DomainGatekeeper::addVerifiedNodeFromConnectRequest(const NodeConnectionData& nodeConnection) {
HifiSockAddr discoveredSocket = nodeConnection.senderSockAddr;
SockAddr discoveredSocket = nodeConnection.senderSockAddr;
SharedNetworkPeer connectedPeer = _icePeers.value(nodeConnection.connectUUID);
if (connectedPeer && connectedPeer->getActiveSocket()) {
@ -687,7 +690,7 @@ void DomainGatekeeper::cleanupICEPeerForNode(const QUuid& nodeID) {
bool DomainGatekeeper::verifyUserSignature(const QString& username,
const QByteArray& usernameSignature,
const HifiSockAddr& senderSockAddr) {
const SockAddr& senderSockAddr) {
// it's possible this user can be allowed to connect, but we need to check their username signature
auto lowerUsername = username.toLower();
KeyFlagPair publicKeyPair = _userPublicKeys.value(lowerUsername);
@ -770,7 +773,7 @@ bool DomainGatekeeper::needToVerifyDomainUserIdentity(const QString& username, c
}
bool DomainGatekeeper::verifyDomainUserIdentity(const QString& username, const QString& accessToken,
const QString& refreshToken, const HifiSockAddr& senderSockAddr) {
const QString& refreshToken, const SockAddr& senderSockAddr) {
if (_verifiedDomainUserIdentities.contains(username)
&& _verifiedDomainUserIdentities.value(username) == QPair<QString, QString>(accessToken, refreshToken)) {
return true;
@ -868,7 +871,7 @@ void DomainGatekeeper::publicKeyJSONErrorCallback(QNetworkReply* requestReply) {
_inFlightPublicKeyRequests.remove(username);
}
void DomainGatekeeper::sendProtocolMismatchConnectionDenial(const HifiSockAddr& senderSockAddr) {
void DomainGatekeeper::sendProtocolMismatchConnectionDenial(const SockAddr& senderSockAddr) {
QString protocolVersionError = "Protocol version mismatch - Domain version: " + QCoreApplication::applicationVersion();
qDebug() << "Protocol Version mismatch - denying connection.";
@ -877,7 +880,7 @@ void DomainGatekeeper::sendProtocolMismatchConnectionDenial(const HifiSockAddr&
DomainHandler::ConnectionRefusedReason::ProtocolMismatch);
}
void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr,
void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const SockAddr& senderSockAddr,
DomainHandler::ConnectionRefusedReason reasonCode,
QString extraInfo) {
// this is an agent and we've decided we won't let them connect - send them a packet to deny connection
@ -907,7 +910,7 @@ void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const H
DependencyManager::get<LimitedNodeList>()->sendPacket(std::move(connectionDeniedPacket), senderSockAddr);
}
void DomainGatekeeper::sendConnectionTokenPacket(const QString& username, const HifiSockAddr& senderSockAddr) {
void DomainGatekeeper::sendConnectionTokenPacket(const QString& username, const SockAddr& senderSockAddr) {
// get the existing connection token or create a new one
QUuid& connectionToken = _connectionTokenHash[username.toLower()];
@ -1237,7 +1240,7 @@ void DomainGatekeeper::requestDomainUser(const QString& username, const QString&
// Get data pertaining to "me", the user who generated the access token.
const QString WORDPRESS_USER_ROUTE = "wp/v2/users/me";
const QString WORDPRESS_USER_QUERY = "_fields=username,roles";
const QString WORDPRESS_USER_QUERY = "_fields=username,email,roles";
QUrl domainUserURL = apiBase + WORDPRESS_USER_ROUTE + (apiBase.contains("?") ? "&" : "?") + WORDPRESS_USER_QUERY;
QNetworkRequest request;
@ -1269,8 +1272,13 @@ void DomainGatekeeper::requestDomainUserFinished() {
if (200 <= httpStatus && httpStatus < 300) {
QString username = rootObject.value("username").toString().toLower();
if (_inFlightDomainUserIdentityRequests.contains(username)) {
QString email = rootObject.value("email").toString().toLower();
if (_inFlightDomainUserIdentityRequests.contains(username) || _inFlightDomainUserIdentityRequests.contains(email)) {
// Success! Verified user.
if (!_inFlightDomainUserIdentityRequests.contains(username)) {
username = email;
}
_verifiedDomainUserIdentities.insert(username, _inFlightDomainUserIdentityRequests.value(username));
_inFlightDomainUserIdentityRequests.remove(username);

View file

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

View file

@ -4,6 +4,7 @@
//
// Created by Zach Pomerantz on 5/25/2016.
// Copyright 2016 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

View file

@ -60,14 +60,19 @@
#include <Gzip.h>
#include <OctreeDataUtils.h>
#include <ThreadHelpers.h>
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";
const QString PUBLIC_SOCKET_ADDRESS_KEY = "network_address";
const QString PUBLIC_SOCKET_PORT_KEY = "network_port";
const QString DOMAIN_UPDATE_AUTOMATIC_NETWORKING_KEY = "automatic_networking";
const int MIN_PORT = 1;
const int MAX_PORT = 65535;
@ -340,7 +345,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
void DomainServer::parseCommandLine(int argc, char* argv[]) {
QCommandLineParser parser;
parser.setApplicationDescription("High Fidelity Domain Server");
parser.setApplicationDescription("Vircadia Domain Server");
const QCommandLineOption versionOption = parser.addVersionOption();
const QCommandLineOption helpOption = parser.addHelpOption();
@ -656,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());
}
@ -772,45 +777,68 @@ void DomainServer::setupNodeListAndAssignments() {
connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded);
connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled);
connect(nodeList.data(), &LimitedNodeList::localSockAddrChanged, this,
[this](const HifiSockAddr& localSockAddr) {
[this](const SockAddr& localSockAddr) {
DependencyManager::get<LimitedNodeList>()->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, localSockAddr.getPort());
});
// register as the packet receiver for the types we want
PacketReceiver& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::RequestAssignment, this, "processRequestAssignmentPacket");
packetReceiver.registerListener(PacketType::DomainListRequest, this, "processListRequestPacket");
packetReceiver.registerListener(PacketType::DomainServerPathQuery, this, "processPathQueryPacket");
packetReceiver.registerListener(PacketType::NodeJsonStats, this, "processNodeJSONStatsPacket");
packetReceiver.registerListener(PacketType::DomainDisconnectRequest, this, "processNodeDisconnectRequestPacket");
packetReceiver.registerListener(PacketType::AvatarZonePresence, this, "processAvatarZonePresencePacket");
packetReceiver.registerListener(PacketType::RequestAssignment,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processRequestAssignmentPacket));
packetReceiver.registerListener(PacketType::DomainListRequest,
PacketReceiver::makeSourcedListenerReference<DomainServer>(this, &DomainServer::processListRequestPacket));
packetReceiver.registerListener(PacketType::DomainServerPathQuery,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processPathQueryPacket));
packetReceiver.registerListener(PacketType::NodeJsonStats,
PacketReceiver::makeSourcedListenerReference<DomainServer>(this, &DomainServer::processNodeJSONStatsPacket));
packetReceiver.registerListener(PacketType::DomainDisconnectRequest,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processNodeDisconnectRequestPacket));
packetReceiver.registerListener(PacketType::AvatarZonePresence,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processAvatarZonePresencePacket));
// NodeList won't be available to the settings manager when it is created, so call registerListener here
packetReceiver.registerListener(PacketType::DomainSettingsRequest, &_settingsManager, "processSettingsRequestPacket");
packetReceiver.registerListener(PacketType::NodeKickRequest, &_settingsManager, "processNodeKickRequestPacket");
packetReceiver.registerListener(PacketType::UsernameFromIDRequest, &_settingsManager, "processUsernameFromIDRequestPacket");
packetReceiver.registerListener(PacketType::DomainSettingsRequest,
PacketReceiver::makeUnsourcedListenerReference<DomainServerSettingsManager>(&_settingsManager, &DomainServerSettingsManager::processSettingsRequestPacket));
packetReceiver.registerListener(PacketType::NodeKickRequest,
PacketReceiver::makeSourcedListenerReference<DomainServerSettingsManager>(&_settingsManager, &DomainServerSettingsManager::processNodeKickRequestPacket));
packetReceiver.registerListener(PacketType::UsernameFromIDRequest,
PacketReceiver::makeSourcedListenerReference<DomainServerSettingsManager>(&_settingsManager, &DomainServerSettingsManager::processUsernameFromIDRequestPacket));
// register the gatekeeper for the packets it needs to receive
packetReceiver.registerListener(PacketType::DomainConnectRequest, &_gatekeeper, "processConnectRequestPacket");
packetReceiver.registerListener(PacketType::ICEPing, &_gatekeeper, "processICEPingPacket");
packetReceiver.registerListener(PacketType::ICEPingReply, &_gatekeeper, "processICEPingReplyPacket");
packetReceiver.registerListener(PacketType::ICEServerPeerInformation, &_gatekeeper, "processICEPeerInformationPacket");
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,
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processICEPingReplyPacket));
packetReceiver.registerListener(PacketType::ICEServerPeerInformation,
PacketReceiver::makeUnsourcedListenerReference<DomainGatekeeper>(&_gatekeeper, &DomainGatekeeper::processICEPeerInformationPacket));
packetReceiver.registerListener(PacketType::ICEServerHeartbeatDenied, this, "processICEServerHeartbeatDenialPacket");
packetReceiver.registerListener(PacketType::ICEServerHeartbeatACK, this, "processICEServerHeartbeatACK");
packetReceiver.registerListener(PacketType::ICEServerHeartbeatDenied,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processICEServerHeartbeatDenialPacket));
packetReceiver.registerListener(PacketType::ICEServerHeartbeatACK,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processICEServerHeartbeatACK));
packetReceiver.registerListener(PacketType::OctreeDataFileRequest, this, "processOctreeDataRequestMessage");
packetReceiver.registerListener(PacketType::OctreeDataPersist, this, "processOctreeDataPersistMessage");
packetReceiver.registerListener(PacketType::OctreeDataFileRequest,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processOctreeDataRequestMessage));
packetReceiver.registerListener(PacketType::OctreeDataPersist,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::processOctreeDataPersistMessage));
packetReceiver.registerListener(PacketType::OctreeFileReplacement, this, "handleOctreeFileReplacementRequest");
packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl, this, "handleDomainContentReplacementFromURLRequest");
packetReceiver.registerListener(PacketType::OctreeFileReplacement,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::handleOctreeFileReplacementRequest));
packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl,
PacketReceiver::makeUnsourcedListenerReference<DomainServer>(this, &DomainServer::handleDomainContentReplacementFromURLRequest));
// set a custom packetVersionMatch as the verify packet operator for the udt::Socket
nodeList->setPacketFilterOperator(&DomainServer::isPacketVerified);
_assetClientThread.setObjectName("AssetClient Thread");
QString name = "AssetClient Thread";
_assetClientThread.setObjectName(name);
auto assetClient = DependencyManager::set<AssetClient>();
assetClient->moveToThread(&_assetClientThread);
connect(&_assetClientThread, &QThread::started, [name] { setThreadName(name.toStdString()); });
_assetClientThread.start();
// add whatever static assignments that have been parsed to the queue
addStaticAssignmentsToQueue();
@ -882,14 +910,13 @@ void DomainServer::setupAutomaticNetworking() {
qDebug() << "domain-server" << _automaticNetworkingSetting << "automatic networking enabled for ID"
<< uuidStringWithoutCurlyBraces(domainID) << "via" << _oauthProviderURL.toString();
auto nodeList = DependencyManager::get<LimitedNodeList>();
// send any public socket changes to the data server so nodes can find us at our new IP
connect(nodeList.data(), &LimitedNodeList::publicSockAddrChanged, this,
&DomainServer::performIPAddressPortUpdate);
if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE) {
auto nodeList = DependencyManager::get<LimitedNodeList>();
// send any public socket changes to the data server so nodes can find us at our new IP
connect(nodeList.data(), &LimitedNodeList::publicSockAddrChanged,
this, &DomainServer::performIPAddressUpdate);
// have the LNL enable public socket updating via STUN
nodeList->startSTUNPublicSocketUpdate();
}
@ -1198,7 +1225,7 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode, quint64 reques
broadcastNewNode(newNode);
}
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr &senderSockAddr, bool newConnection) {
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const SockAddr &senderSockAddr, bool newConnection) {
const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID +
NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + 4;
@ -1474,7 +1501,7 @@ void DomainServer::transactionJSONCallback(const QJsonObject& data) {
}
}
QJsonObject jsonForDomainSocketUpdate(const HifiSockAddr& socket) {
QJsonObject jsonForDomainSocketUpdate(const SockAddr& socket) {
const QString SOCKET_NETWORK_ADDRESS_KEY = "network_address";
const QString SOCKET_PORT_KEY = "port";
@ -1485,13 +1512,23 @@ QJsonObject jsonForDomainSocketUpdate(const HifiSockAddr& socket) {
return socketObject;
}
const QString DOMAIN_UPDATE_AUTOMATIC_NETWORKING_KEY = "automatic_networking";
void DomainServer::performIPAddressPortUpdate(const SockAddr& newPublicSockAddr) {
const QString& DOMAIN_SERVER_SETTINGS_KEY = "domain_server";
const QString& publicSocketAddress = newPublicSockAddr.getAddress().toString();
const int publicSocketPort = newPublicSockAddr.getPort();
void DomainServer::performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr) {
sendHeartbeatToMetaverse(newPublicSockAddr.getAddress().toString());
sendHeartbeatToMetaverse(publicSocketAddress, publicSocketPort);
QJsonObject rootObject;
QJsonObject domainServerObject;
domainServerObject.insert(PUBLIC_SOCKET_ADDRESS_KEY, publicSocketAddress);
domainServerObject.insert(PUBLIC_SOCKET_PORT_KEY, publicSocketPort);
rootObject.insert(DOMAIN_SERVER_SETTINGS_KEY, domainServerObject);
QJsonDocument doc(rootObject);
_settingsManager.recurseJSONObjectAndOverwriteSettings(rootObject, DomainSettings);
}
void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) {
void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress, const int port) {
// Setup the domain object to send to the data server
QJsonObject domainObject;
@ -1501,10 +1538,20 @@ void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) {
static const QString PROTOCOL_VERSION_KEY = "protocol";
domainObject[PROTOCOL_VERSION_KEY] = protocolVersionsSignatureBase64();
// add networking
static const QString NETWORK_ADDRESS_SETTINGS_KEY = "domain_server." + PUBLIC_SOCKET_ADDRESS_KEY;
const QString networkAddressFromSettings = _settingsManager.valueForKeyPath(NETWORK_ADDRESS_SETTINGS_KEY).toString();
if (!networkAddress.isEmpty()) {
static const QString PUBLIC_NETWORK_ADDRESS_KEY = "network_address";
domainObject[PUBLIC_NETWORK_ADDRESS_KEY] = networkAddress;
domainObject[PUBLIC_SOCKET_ADDRESS_KEY] = networkAddress;
} else if (!networkAddressFromSettings.isEmpty()) {
domainObject[PUBLIC_SOCKET_ADDRESS_KEY] = networkAddressFromSettings;
}
static const QString PORT_SETTINGS_KEY = "domain_server." + PUBLIC_SOCKET_PORT_KEY;
const int portFromSettings = _settingsManager.valueForKeyPath(PORT_SETTINGS_KEY).toInt();
if (port != 0) {
domainObject[PUBLIC_SOCKET_PORT_KEY] = port;
} else if (portFromSettings != 0) {
domainObject[PUBLIC_SOCKET_PORT_KEY] = portFromSettings;
}
static const QString AUTOMATIC_NETWORKING_KEY = "automatic_networking";
@ -1723,7 +1770,7 @@ void DomainServer::sendHeartbeatToIceServer() {
QDataStream heartbeatStream(_iceServerHeartbeatPacket.get());
QUuid senderUUID;
HifiSockAddr publicSocket, localSocket;
SockAddr publicSocket, localSocket;
heartbeatStream >> senderUUID >> publicSocket >> localSocket;
if (senderUUID != limitedNodeList->getSessionUUID()
@ -1881,7 +1928,7 @@ void DomainServer::processNodeJSONStatsPacket(QSharedPointer<ReceivedMessage> pa
}
}
QJsonObject DomainServer::jsonForSocket(const HifiSockAddr& socket) {
QJsonObject DomainServer::jsonForSocket(const SockAddr& socket) {
QJsonObject socketJSON;
socketJSON["ip"] = socket.getAddress().toString();
@ -2727,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";
@ -2740,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);
@ -2773,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
@ -2789,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
@ -2805,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);
}
@ -2839,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();
}
}
}
@ -2860,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() };
}
}
@ -2937,7 +3017,7 @@ static const QString BROADCASTING_SETTINGS_KEY = "broadcasting";
struct ReplicationServerInfo {
NodeType_t nodeType;
HifiSockAddr sockAddr;
SockAddr sockAddr;
};
ReplicationServerInfo serverInformationFromSettings(QVariantMap serverMap, ReplicationServerDirection direction) {
@ -2958,7 +3038,7 @@ ReplicationServerInfo serverInformationFromSettings(QVariantMap serverMap, Repli
serverInfo.nodeType = NodeType::downstreamType(nodeType);
}
// read the address and port and construct a HifiSockAddr from them
// read the address and port and construct a SockAddr from them
serverInfo.sockAddr = {
serverMap[REPLICATION_SERVER_ADDRESS].toString(),
(quint16) serverMap[REPLICATION_SERVER_PORT].toString().toInt()
@ -2967,7 +3047,7 @@ ReplicationServerInfo serverInformationFromSettings(QVariantMap serverMap, Repli
return serverInfo;
}
return { NodeType::Unassigned, HifiSockAddr() };
return { NodeType::Unassigned, SockAddr() };
}
void DomainServer::updateReplicationNodes(ReplicationServerDirection direction) {
@ -2976,7 +3056,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
if (broadcastSettingsVariant.isValid()) {
auto nodeList = DependencyManager::get<LimitedNodeList>();
std::vector<HifiSockAddr> replicationNodesInSettings;
std::vector<SockAddr> replicationNodesInSettings;
auto replicationSettings = broadcastSettingsVariant.toMap();
@ -2986,7 +3066,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
if (replicationSettings.contains(serversKey)) {
auto serversSettings = replicationSettings.value(serversKey).toList();
std::vector<HifiSockAddr> knownReplicationNodes;
std::vector<SockAddr> knownReplicationNodes;
nodeList->eachNode([direction, &knownReplicationNodes](const SharedNodePointer& otherNode) {
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
@ -3540,7 +3620,7 @@ void DomainServer::randomizeICEServerAddress(bool shouldTriggerHostLookup) {
indexToTry = distribution(generator);
}
_iceServerSocket = HifiSockAddr { candidateICEAddresses[indexToTry], ICE_SERVER_DEFAULT_PORT };
_iceServerSocket = SockAddr { candidateICEAddresses[indexToTry], ICE_SERVER_DEFAULT_PORT };
qCInfo(domain_server_ice) << "Set candidate ice-server socket to" << _iceServerSocket;
// clear our number of hearbeat denials, this should be re-set on ice-server change

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