# UniVirtual Viewer
###### tags: `viewer`
This project does most of the heavy lifting of handling the UniVirtual Viewer's UI and interacting with the third-party systems we rely on. There is more detail on the Third-Party assets further on within this document, but a basic outline is:
:::info
GitHub: https://github.com/cndgdev/dev-univirtual_viewer
:::
### Third-Party Modules
* Photon - the networking stack we use to create a multi-user environment
* Vivox - provides voice chat services
* Backtrace - Handles bug aggregation so we can more effectively diagnose and correct application issues
* UMA & o3n - provides an avatar customization system
* ZFBrowser - provides an integrated browser for displaying text-based content
* NWH - a vehicle physics system
* Ink - a narrative scripting language, for our NPC dialogues
## Build & Distribution
Both the Windows and MacOS environment are supported and builds for both environments are created from the same shared codebase. There are currently only very minor differences between the environments that must be handled, mostly related to where user settings and course assets are stored.
### Viewer Build Walkthrough
1. Create a new feature branch off develop on the viewer project git repository
2. Once your feature is complete, merge back to develop
#### Windows (via Jenkins)
3. In [Jenkins](https://ci.univirtual.com/), run the Univirtual_Viewer_(Win)_-_develop project
1. Once the build is complete, run the Publish Windows Viewer project
1. After that completes, open the univirtual AWS bucket
1. Navigate to the patch/Builds/ folder and note the most recent build_X.Y.Z.json file
1. Edit the builds_index.json file to set “AvailableBuilds” to the X.Y.Z value
1. The viewer build is now live through the patcher
#### macOS (manualy)
3. Build on macOS
1. Run shell script on macOS terminal to sign the app (see below)
1. **TODO:: Jason should upload the patch project**
1. Add the new app in the folder...
1. Make a new patch from GUI instructions
1. This will produce a folder and a json file
1. Upload those to AWS `Amazon S3 > Buckets > univirtual > patch/ > OSX/ > Builds/`
1. Edit `builds_index.json` to direct to the current version.
`builds_index.json` example:
```json
{
"AvailableBuilds": [
"0.2.4"
]
}
```
This is the shell script:
`cndg-univirtual-app-sign.sh`
```shell=
#!/bin/sh
BINARY="UniVirtual.app"
ZIP="UniVirtual.unsigned.zip"
ENTITLEMENTS="univirtual.entitlements"
SIGNCERT="Developer ID Application: Chant Newall Development Group LLC (ZJYBZ7K2S7)"
BUNDLE="info.cndg.univirtual.viewer"
USER="USERNAME"
PASSWORD="PASSWORD"
VENDOR="ZJYBZ7K2S7"
find "./$BINARY" -name "*.meta" -type f -exec rm {} \;
chmod +x ./$BINARY/Contents/MacOS/UniVirtual
chmod +x ./$BINARY/Contents/Frameworks/ZFGameBrowser.app/Contents/MacOS/ZFGameBrowser
rm ./$BINARY/ThirdPartyNotices.txt
libfile=`find ./$BINARY -path "./$BINARY/Contents/Resources" -prune -false -o -name '*.dylib'`
while read -r libname; do
echo "Sign:" $libname
codesign --deep --force --verify -vvvv --timestamp --options runtime --entitlements $ENTITLEMENTS --sign "$SIGNCERT" "$libname"
done <<< "$libfile"
bundlefile=`find ./$BINARY -path "./$BINARY/Contents/Resources" -prune -false -o -name '*.bundle'`
while read -r bundlename; do
echo "Sign:" $bundlename
codesign --deep --force --verify -vvvv --timestamp --options runtime --entitlements $ENTITLEMENTS --sign "$SIGNCERT" "$bundlename"
done <<< "$bundlefile"
frameworkfile=`find ./$BINARY -path "./$BINARY/Contents/Resources" -prune -false -o -name '*.framework'`
while read -r frameworkname; do
echo "Sign:" $frameworkname
codesign --deep --force --verify -vvvv --timestamp --options runtime --entitlements $ENTITLEMENTS --sign "$SIGNCERT" "$frameworkname"
done <<< "$frameworkfile"
binaryfile=`find ./$BINARY/Contents/MacOS -type f`
while read -r binaryname; do
echo "Sign:" $binaryname
codesign --deep --force --verify -vvvv --timestamp --options runtime --entitlements $ENTITLEMENTS --sign "$SIGNCERT" "$binaryname"
done <<< "$binaryfile"
ditto -c -k --sequesterRsrc --keepParent "$BINARY" "$ZIP"
#xcrun altool --notarize-app --username $USER --password $PASSWORD --asc-provider $VENDOR --primary-bundle-id $BUNDLE --file $ZIP
# functions
requeststatus() { # $1: requestUUID
requestUUID=${1?:"need a request UUID"}
req_status=$(xcrun altool --notarization-info "$requestUUID" \
--username "$USER" \
--password "$PASSWORD" 2>&1 \
| awk -F ': ' '/Status:/ { print $2; }' )
echo "$req_status"
}
# upload file
echo "## uploading $ZIP for notarization"
requestUUID=$(xcrun altool --notarize-app \
--primary-bundle-id "$BUNDLE" \
--username "$USER" \
--password "$PASSWORD" \
--asc-provider "$VENDOR" \
--file "$ZIP" 2>&1 \
| awk '/RequestUUID/ { print $NF; }')
echo "Notarization RequestUUID: $requestUUID"
if [[ $requestUUID == "" ]]; then
echo "could not upload for notarization"
exit 1
fi
# wait for status to be not "in progress" any more
request_status="in progress"
while [[ "$request_status" == "in progress" ]]; do
echo "waiting... "
sleep 10
request_status=$(requeststatus "$requestUUID")
echo "$request_status"
done
# print status information
xcrun altool --notarization-info "$requestUUID" \
--username "$USER" \
--password "$PASSWORD"
echo
if [[ $request_status != "success" ]]; then
echo "## could not notarize $BINARY"
exit 1
fi
# staple result
echo "## Stapling $BINARY"
xcrun stapler staple "$BINARY"
echo '## Done!'
exit 0
```