mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-07 17:04:10 +02:00
Merge branch 'master' into linux-actions-builds-pr-builds
This commit is contained in:
commit
9a87fe0473
15 changed files with 367 additions and 69 deletions
1
.github/workflows/master_build.yml
vendored
1
.github/workflows/master_build.yml
vendored
|
@ -91,7 +91,6 @@ jobs:
|
|||
# - os: ubuntu-latest
|
||||
# build_type: client
|
||||
runs-on: ${{matrix.os}}
|
||||
if: github.event.action != 'labeled' || github.event.label.name == 'rebuild-mac' || github.event.label.name == 'rebuild'
|
||||
needs: generate_build_number
|
||||
steps:
|
||||
- name: Download build number
|
||||
|
|
4
.github/workflows/pr_build.yml
vendored
4
.github/workflows/pr_build.yml
vendored
|
@ -9,18 +9,20 @@ env:
|
|||
BUILD_TYPE: Release
|
||||
CI_BUILD: Github
|
||||
GIT_COMMIT: ${{ github.sha }}
|
||||
GIT_COMMIT_SHORT: ${{ github.sha }}
|
||||
HIFI_VCPKG_BOOTSTRAP: true
|
||||
RELEASE_TYPE: PR
|
||||
RELEASE_NUMBER: ${{ github.event.number }}
|
||||
VERSION_CODE: ${{ github.event.number }}
|
||||
|
||||
|
||||
# OSX specific variables
|
||||
DEVELOPER_DIR: /Applications/Xcode_11.2.app/Contents/Developer
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.11'
|
||||
|
||||
# WIN32 specific variables
|
||||
PreferredToolArchitecture: X64
|
||||
GIT_COMMIT_SHORT: ${{ github.sha }}
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
|
@ -3616,28 +3616,18 @@ void DomainServer::handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMes
|
|||
}
|
||||
|
||||
void DomainServer::processAvatarZonePresencePacket(QSharedPointer<ReceivedMessage> message) {
|
||||
QUuid avatar = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
||||
QUuid zone = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
||||
QUuid avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
||||
QUuid zoneID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
if (avatar.isNull()) {
|
||||
if (avatarID.isNull()) {
|
||||
qCWarning(domain_server) << "Ignoring null avatar presence";
|
||||
return;
|
||||
}
|
||||
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||
auto matchingNode = limitedNodeList->nodeWithUUID(avatar);
|
||||
if (!matchingNode) {
|
||||
qCWarning(domain_server) << "Ignoring avatar presence for unknown avatar" << avatar;
|
||||
return;
|
||||
}
|
||||
QString verifiedUsername = matchingNode->getPermissions().getVerifiedUserName();
|
||||
if (verifiedUsername.isEmpty()) { // Silently bail for users who are not logged in.
|
||||
return;
|
||||
}
|
||||
static const int SCREENSHARE_EXPIRATION_SECONDS = 24 * 60 * 60;
|
||||
screensharePresence(zone.isNull() ? "" : zone.toString(), verifiedUsername, SCREENSHARE_EXPIRATION_SECONDS);
|
||||
screensharePresence(zoneID.isNull() ? "" : zoneID.toString(), avatarID, SCREENSHARE_EXPIRATION_SECONDS);
|
||||
}
|
||||
|
||||
void DomainServer::screensharePresence(QString roomname, QString username, int expirationSeconds) {
|
||||
void DomainServer::screensharePresence(QString roomname, QUuid avatarID, int expirationSeconds) {
|
||||
if (!DependencyManager::get<AccountManager>()->hasValidAccessToken()) {
|
||||
static std::once_flag presenceAuthorityWarning;
|
||||
std::call_once(presenceAuthorityWarning, [] {
|
||||
|
@ -3645,14 +3635,33 @@ void DomainServer::screensharePresence(QString roomname, QString username, int e
|
|||
});
|
||||
return;
|
||||
}
|
||||
|
||||
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||
auto matchingNode = limitedNodeList->nodeWithUUID(avatarID);
|
||||
if (!matchingNode) {
|
||||
qCWarning(domain_server) << "Ignoring avatar presence for unknown avatar ID" << avatarID;
|
||||
return;
|
||||
}
|
||||
QString verifiedUsername = matchingNode->getPermissions().getVerifiedUserName();
|
||||
if (verifiedUsername.isEmpty()) { // Silently bail for users who are not logged in.
|
||||
return;
|
||||
}
|
||||
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.callbackReceiver = this;
|
||||
callbackParams.jsonCallbackMethod = "handleSuccessfulScreensharePresence";
|
||||
callbackParams.errorCallbackMethod = "handleFailedScreensharePresence";
|
||||
// Construct `callbackData`, which is data that will be available to the callback functions.
|
||||
// In this case, the "success" callback needs access to the "roomname" (the zone ID) and the
|
||||
// relevant avatar's UUID.
|
||||
QJsonObject callbackData;
|
||||
callbackData.insert("roomname", roomname);
|
||||
callbackData.insert("avatarID", avatarID.toString());
|
||||
callbackParams.callbackData = callbackData;
|
||||
const QString PATH = "api/v1/domains/%1/screenshare";
|
||||
QString domain_id = uuidStringWithoutCurlyBraces(getID());
|
||||
QJsonObject json, screenshare;
|
||||
screenshare["username"] = username;
|
||||
screenshare["username"] = verifiedUsername;
|
||||
screenshare["roomname"] = roomname;
|
||||
if (expirationSeconds > 0) {
|
||||
screenshare["expiration"] = expirationSeconds;
|
||||
|
@ -3666,11 +3675,18 @@ void DomainServer::screensharePresence(QString roomname, QString username, int e
|
|||
);
|
||||
}
|
||||
|
||||
void DomainServer::handleSuccessfulScreensharePresence(QNetworkReply* requestReply) {
|
||||
void DomainServer::handleSuccessfulScreensharePresence(QNetworkReply* requestReply, QJsonObject callbackData) {
|
||||
QJsonObject jsonObject = QJsonDocument::fromJson(requestReply->readAll()).object();
|
||||
if (jsonObject["status"].toString() != "success") {
|
||||
qCWarning(domain_server) << "screensharePresence api call failed:" << QJsonDocument(jsonObject).toJson(QJsonDocument::Compact);
|
||||
return;
|
||||
}
|
||||
|
||||
// Tell the client that we just authorized to screenshare which zone ID in which they are authorized to screenshare.
|
||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||
auto packet = NLPacket::create(PacketType::AvatarZonePresence, NUM_BYTES_RFC4122_UUID, true);
|
||||
packet->write(QUuid(callbackData["roomname"].toString()).toRfc4122());
|
||||
nodeList->sendPacket(std::move(packet), *(nodeList->nodeWithUUID(QUuid(callbackData["avatarID"].toString()))));
|
||||
}
|
||||
|
||||
void DomainServer::handleFailedScreensharePresence(QNetworkReply* requestReply) {
|
||||
|
|
|
@ -78,7 +78,7 @@ public:
|
|||
|
||||
bool isAssetServerEnabled();
|
||||
|
||||
void screensharePresence(QString roomname, QString username, int expiration_seconds = 0);
|
||||
void screensharePresence(QString roomname, QUuid avatarID, int expiration_seconds = 0);
|
||||
|
||||
public slots:
|
||||
/// Called by NodeList to inform us a node has been added
|
||||
|
@ -132,7 +132,7 @@ private slots:
|
|||
void handleSuccessfulICEServerAddressUpdate(QNetworkReply* requestReply);
|
||||
void handleFailedICEServerAddressUpdate(QNetworkReply* requestReply);
|
||||
|
||||
void handleSuccessfulScreensharePresence(QNetworkReply* requestReply);
|
||||
void handleSuccessfulScreensharePresence(QNetworkReply* requestReply, QJsonObject callbackData);
|
||||
void handleFailedScreensharePresence(QNetworkReply* requestReply);
|
||||
|
||||
void updateReplicatedNodes();
|
||||
|
|
|
@ -436,38 +436,72 @@ class MyAvatar : public Avatar {
|
|||
const bool DEFAULT_STRAFE_ENABLED = true;
|
||||
public:
|
||||
|
||||
/**jsdoc
|
||||
* The <code>DriveKeys</code> API provides constant numeric values that represent different logical keys that drive your
|
||||
* avatar and camera.
|
||||
*
|
||||
* @namespace DriveKeys
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} TRANSLATE_X - Move the user's avatar in the direction of its x-axis, if the camera isn't in
|
||||
* independent or mirror modes.
|
||||
* @property {number} TRANSLATE_Y - Move the user's avatar in the direction of its y-axis, if the camera isn't in
|
||||
* independent or mirror modes.
|
||||
* @property {number} TRANSLATE_Z - Move the user's avatar in the direction of its z-axis, if the camera isn't in
|
||||
* independent or mirror modes.
|
||||
* @property {number} YAW - Rotate the user's avatar about its y-axis at a rate proportional to the control value, if the
|
||||
* camera isn't in independent or mirror modes.
|
||||
* @property {number} STEP_TRANSLATE_X - No action.
|
||||
* @property {number} STEP_TRANSLATE_Y - No action.
|
||||
* @property {number} STEP_TRANSLATE_Z - No action.
|
||||
* @property {number} STEP_YAW - Rotate the user's avatar about its y-axis in a step increment, if the camera isn't in
|
||||
* independent or mirror modes.
|
||||
* @property {number} PITCH - Rotate the user's avatar head and attached camera about its negative x-axis (i.e., positive
|
||||
* values pitch down) at a rate proportional to the control value, if the camera isn't in HMD, independent, or mirror
|
||||
* modes.
|
||||
* @property {number} ZOOM - Zoom the camera in or out.
|
||||
* @property {number} DELTA_YAW - Rotate the user's avatar about its y-axis by an amount proportional to the control value,
|
||||
* if the camera isn't in independent or mirror modes.
|
||||
* @property {number} DELTA_PITCH - Rotate the user's avatar head and attached camera about its negative x-axis (i.e.,
|
||||
* positive values pitch down) by an amount proportional to the control value, if the camera isn't in HMD, independent,
|
||||
* or mirror modes.
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* <p>Logical keys that drive your avatar and camera.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>TRANSLATE_X</td><td>Move the user's avatar in the direction of its x-axis, if the
|
||||
* camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>1</code></td><td>TRANSLATE_Y</td><td>Move the user's avatar in the direction of its y-axis, if the
|
||||
* camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>TRANSLATE_Z</td><td>Move the user's avatar in the direction of its z-axis, if the
|
||||
* camera isn't in independent or mirror modes</td></tr>
|
||||
* <tr><td><code>3</code></td><td>YAW</td><td>Rotate the user's avatar about its y-axis at a rate proportional to the
|
||||
* control value, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>4</code></td><td>STEP_TRANSLATE_X</td><td>No action.</td></tr>
|
||||
* <tr><td><code>5</code></td><td>STEP_TRANSLATE_Y</td><td>No action.</td></tr>
|
||||
* <tr><td><code>6</code></td><td>STEP_TRANSLATE_Z</td><td>No action.</td></tr>
|
||||
* <tr><td><code>7</code></td><td>STEP_YAW</td><td>Rotate the user's avatar about its y-axis in a step increment, if
|
||||
* the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>8</code></td><td>PITCH</td><td>Rotate the user's avatar head and attached camera about its negative
|
||||
* x-axis (i.e., positive values pitch down) at a rate proportional to the control value, if the camera isn't in HMD,
|
||||
* independent, or mirror modes.</td></tr>
|
||||
* <tr><td><code>9</code></td><td>ZOOM</td><td>Zoom the camera in or out.</td></tr>
|
||||
* <tr><td><code>10</code></td><td>DELTA_YAW</td><td>Rotate the user's avatar about its y-axis by an amount proportional
|
||||
* to the control value, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>11</code></td><td>DELTA_PITCH</td><td>Rotate the user's avatar head and attached camera about its
|
||||
* negative x-axis (i.e., positive values pitch down) by an amount proportional to the control value, if the camera
|
||||
* isn't in HMD, independent, or mirror modes.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.TRANSLATE_X}</code></td><td>Move the user's avatar in the direction of its
|
||||
* x-axis, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.TRANSLATE_Y}</code></td><td>Move the user's avatar in the direction of its
|
||||
* -axis, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.TRANSLATE_Z}</code></td><td>Move the user's avatar in the direction of its
|
||||
* z-axis, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.YAW}</code></td><td>Rotate the user's avatar about its y-axis at a rate
|
||||
* proportional to the control value, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.STEP_TRANSLATE_X}</code></td><td>No action.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.STEP_TRANSLATE_Y}</code></td><td>No action.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.STEP_TRANSLATE_Z}</code></td><td>No action.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.STEP_YAW}</code></td><td>Rotate the user's avatar about its y-axis in a
|
||||
* step increment, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.PITCH}</code></td><td>Rotate the user's avatar head and attached camera
|
||||
* about its negative x-axis (i.e., positive values pitch down) at a rate proportional to the control value, if the
|
||||
* camera isn't in HMD, independent, or mirror modes.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.ZOOM}</code></td><td>Zoom the camera in or out.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.DELTA_YAW}</code></td><td>Rotate the user's avatar about its y-axis by an
|
||||
* amount proportional to the control value, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>{@link DriveKeys|DriveKeys.DELTA_PITCH}</code></td><td>Rotate the user's avatar head and attached
|
||||
* camera about its negative x-axis (i.e., positive values pitch down) by an amount proportional to the control
|
||||
* value, if the camera isn't in HMD, independent, or mirror modes.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {number} MyAvatar.DriveKeys
|
||||
* @typedef {number} DriveKey
|
||||
*/
|
||||
enum DriveKeys {
|
||||
TRANSLATE_X = 0,
|
||||
|
@ -1019,7 +1053,7 @@ public:
|
|||
/**jsdoc
|
||||
* Gets the value of a drive key, regardless of whether it is disabled.
|
||||
* @function MyAvatar.getRawDriveKey
|
||||
* @param {MyAvatar.DriveKeys} key - The drive key.
|
||||
* @param {DriveKey} key - The drive key.
|
||||
* @returns {number} The value of the drive key.
|
||||
*/
|
||||
Q_INVOKABLE float getRawDriveKey(DriveKeys key) const;
|
||||
|
@ -1029,11 +1063,10 @@ public:
|
|||
/**jsdoc
|
||||
* Disables the action associated with a drive key.
|
||||
* @function MyAvatar.disableDriveKey
|
||||
* @param {MyAvatar.DriveKeys} key - The drive key to disable.
|
||||
* @param {DriveKey} key - The drive key to disable.
|
||||
* @example <caption>Disable rotating your avatar using the keyboard for a couple of seconds.</caption>
|
||||
* var YAW = 3;
|
||||
* print("Disable");
|
||||
* MyAvatar.disableDriveKey(YAW);
|
||||
* MyAvatar.disableDriveKey(DriveKeys.YAW);
|
||||
* Script.setTimeout(function () {
|
||||
* print("Enable");
|
||||
* MyAvatar.enableDriveKey(YAW);
|
||||
|
@ -1045,14 +1078,14 @@ public:
|
|||
* Enables the action associated with a drive key. The action may have been disabled with
|
||||
* {@link MyAvatar.disableDriveKey|disableDriveKey}.
|
||||
* @function MyAvatar.enableDriveKey
|
||||
* @param {MyAvatar.DriveKeys} key - The drive key to enable.
|
||||
* @param {DriveKey} key - The drive key to enable.
|
||||
*/
|
||||
Q_INVOKABLE void enableDriveKey(DriveKeys key);
|
||||
|
||||
/**jsdoc
|
||||
* Checks whether a drive key is disabled.
|
||||
* @function MyAvatar.isDriveKeyDisabled
|
||||
* @param {DriveKeys} key - The drive key to check.
|
||||
* @param {DriveKey} key - The drive key to check.
|
||||
* @returns {boolean} <code>true</code> if the drive key is disabled, <code>false</code> if it isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool isDriveKeyDisabled(DriveKeys key) const;
|
||||
|
|
|
@ -46,6 +46,7 @@ class AccountServicesScriptingInterface : public QObject {
|
|||
* @hifi-avatar
|
||||
*
|
||||
* @namespace AccountServices
|
||||
*
|
||||
* @property {string} username - The user name of the user logged in. If there is no user logged in, it is
|
||||
* <code>"Unknown user"</code>. <em>Read-only.</em>
|
||||
* @property {boolean} loggedIn - <code>true</code> if the user is logged in, otherwise <code>false</code>.
|
||||
|
@ -61,6 +62,86 @@ class AccountServicesScriptingInterface : public QObject {
|
|||
* — typically <code>"https://metaverse.highfidelity.com"</code>. <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* The <code>Account</code> API provides functions that give information on user connectivity, visibility, and asset
|
||||
* download progress.
|
||||
*
|
||||
* @deprecated This API is the same as the {@link AccountServices} API and will be removed.
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @namespace Account
|
||||
*
|
||||
* @property {string} username - The user name of the user logged in. If there is no user logged in, it is
|
||||
* <code>"Unknown user"</code>. <em>Read-only.</em>
|
||||
* @property {boolean} loggedIn - <code>true</code> if the user is logged in, otherwise <code>false</code>.
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} findableBy - The user's visibility to other users:
|
||||
* <ul>
|
||||
* <li><code>"none"</code> — user appears offline.</li>
|
||||
* <li><code>"friends"</code> — user is visible only to friends.</li>
|
||||
* <li><code>"connections"</code> — user is visible to friends and connections.</li>
|
||||
* <li><code>"all"</code> — user is visible to everyone.</li>
|
||||
* </ul>
|
||||
* @property {string} metaverseServerURL - The metaverse server that the user is authenticated against when logged in
|
||||
* — typically <code>"https://metaverse.highfidelity.com"</code>. <em>Read-only.</em>
|
||||
*
|
||||
* @borrows AccountServices.getDownloadInfo as getDownloadInfo
|
||||
* @borrows AccountServices.updateDownloadInfo as updateDownloadInfo
|
||||
* @borrows AccountServices.isLoggedIn as isLoggedIn
|
||||
* @borrows AccountServices.checkAndSignalForAccessToken as checkAndSignalForAccessToken
|
||||
* @borrows AccountServices.logOut as logOut
|
||||
*
|
||||
* @borrows AccountServices.connected as connected
|
||||
* @borrows AccountServices.disconnected as disconnected
|
||||
* @borrows AccountServices.myUsernameChanged as myUsernameChanged
|
||||
* @borrows AccountServices.downloadInfoChanged as downloadInfoChanged
|
||||
* @borrows AccountServices.findableByChanged as findableByChanged
|
||||
* @borrows AccountServices.loggedInChanged as loggedInChanged
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* The <code>GlobalServices</code> API provides functions that give information on user connectivity, visibility, and asset
|
||||
* download progress.
|
||||
*
|
||||
* @deprecated This API is the same as the {@link AccountServices} API and will be removed.
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @namespace GlobalServices
|
||||
*
|
||||
* @property {string} username - The user name of the user logged in. If there is no user logged in, it is
|
||||
* <code>"Unknown user"</code>. <em>Read-only.</em>
|
||||
* @property {boolean} loggedIn - <code>true</code> if the user is logged in, otherwise <code>false</code>.
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} findableBy - The user's visibility to other users:
|
||||
* <ul>
|
||||
* <li><code>"none"</code> — user appears offline.</li>
|
||||
* <li><code>"friends"</code> — user is visible only to friends.</li>
|
||||
* <li><code>"connections"</code> — user is visible to friends and connections.</li>
|
||||
* <li><code>"all"</code> — user is visible to everyone.</li>
|
||||
* </ul>
|
||||
* @property {string} metaverseServerURL - The metaverse server that the user is authenticated against when logged in
|
||||
* — typically <code>"https://metaverse.highfidelity.com"</code>. <em>Read-only.</em>
|
||||
*
|
||||
* @borrows AccountServices.getDownloadInfo as getDownloadInfo
|
||||
* @borrows AccountServices.updateDownloadInfo as updateDownloadInfo
|
||||
* @borrows AccountServices.isLoggedIn as isLoggedIn
|
||||
* @borrows AccountServices.checkAndSignalForAccessToken as checkAndSignalForAccessToken
|
||||
* @borrows AccountServices.logOut as logOut
|
||||
*
|
||||
* @borrows AccountServices.connected as connected
|
||||
* @borrows AccountServices.disconnected as disconnected
|
||||
* @borrows AccountServices.myUsernameChanged as myUsernameChanged
|
||||
* @borrows AccountServices.downloadInfoChanged as downloadInfoChanged
|
||||
* @borrows AccountServices.findableByChanged as findableByChanged
|
||||
* @borrows AccountServices.loggedInChanged as loggedInChanged
|
||||
*/
|
||||
|
||||
Q_PROPERTY(QString username READ getUsername NOTIFY myUsernameChanged)
|
||||
Q_PROPERTY(bool loggedIn READ loggedIn NOTIFY loggedInChanged)
|
||||
Q_PROPERTY(QString findableBy READ getFindableBy WRITE setFindableBy NOTIFY findableByChanged)
|
||||
|
|
|
@ -14,19 +14,56 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
/**jsdoc
|
||||
* The <code>DialogsMamnager</code> API provides facilities to work with some key dialogs.
|
||||
*
|
||||
* @namespace DialogsManager
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class DialogsManagerScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DialogsManagerScriptingInterface();
|
||||
static DialogsManagerScriptingInterface* getInstance();
|
||||
|
||||
/**jsdoc
|
||||
* <em>Currently performs no action.</em>
|
||||
* @function DialogsManager.showFeed
|
||||
*/
|
||||
Q_INVOKABLE void showFeed();
|
||||
|
||||
public slots:
|
||||
/**jsdoc
|
||||
* Shows the "Goto" dialog.
|
||||
* @function DialogsManager.showAddressBar
|
||||
*/
|
||||
void showAddressBar();
|
||||
|
||||
/**jsdoc
|
||||
* Hides the "Goto" dialog.
|
||||
* @function DialogsManager.hideAddressBar
|
||||
*/
|
||||
void hideAddressBar();
|
||||
|
||||
/**jsdoc
|
||||
* Shows the login dialog.
|
||||
* @function DialogsManager.showLoginDialog
|
||||
*/
|
||||
void showLoginDialog();
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Triggered when the "Goto" dialog is opened or closed.
|
||||
* <p><strong>Warning:</strong> Currently isn't always triggered.</p>
|
||||
* @function DialogsManager.addressBarShown
|
||||
* @param {boolean} visible - <code>true</code> if the Goto dialog has been opened, <code>false</code> if it has been
|
||||
* closed.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void addressBarShown(bool visible);
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <AccountManager.h>
|
||||
#include <AddressManager.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <NodeList.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "EntityScriptingInterface.h"
|
||||
|
@ -37,14 +38,48 @@ ScreenshareScriptingInterface::ScreenshareScriptingInterface() {
|
|||
_requestScreenshareInfoRetryTimer->setSingleShot(true);
|
||||
_requestScreenshareInfoRetryTimer->setInterval(SCREENSHARE_INFO_REQUEST_RETRY_TIMEOUT_MS);
|
||||
connect(_requestScreenshareInfoRetryTimer, &QTimer::timeout, this, &ScreenshareScriptingInterface::requestScreenshareInfo);
|
||||
|
||||
// This packet listener handles the packet containing information about the latest zone ID in which we are allowed to share.
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
PacketReceiver& packetReceiver = nodeList->getPacketReceiver();
|
||||
packetReceiver.registerListener(PacketType::AvatarZonePresence, this, "processAvatarZonePresencePacketOnClient");
|
||||
};
|
||||
|
||||
ScreenshareScriptingInterface::~ScreenshareScriptingInterface() {
|
||||
stopScreenshare();
|
||||
}
|
||||
|
||||
void ScreenshareScriptingInterface::processAvatarZonePresencePacketOnClient(QSharedPointer<ReceivedMessage> message) {
|
||||
QUuid zone = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
if (zone.isNull()) {
|
||||
qWarning() << "Ignoring avatar zone presence packet that doesn't specify a zone.";
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the last known authorized screenshare zone ID to the zone that the Domain Server just told us about.
|
||||
_lastAuthorizedZoneID = zone;
|
||||
|
||||
// If we had previously started the screenshare process but knew that we weren't going to be authorized to screenshare,
|
||||
// let's continue the screenshare process here.
|
||||
if (_waitingForAuthorization) {
|
||||
requestScreenshareInfo();
|
||||
}
|
||||
}
|
||||
|
||||
static const int MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES = 5;
|
||||
void ScreenshareScriptingInterface::requestScreenshareInfo() {
|
||||
// If the screenshare zone that we're currently in (i.e. `startScreenshare()` was called) is different from
|
||||
// the zone in which we are authorized to screenshare...
|
||||
// ...return early here and wait for the DS to send us a packet containing this zone's ID.
|
||||
if (_screenshareZoneID != _lastAuthorizedZoneID) {
|
||||
qDebug() << "Client not yet authorized to screenshare. Waiting for authorization message from domain server...";
|
||||
_waitingForAuthorization = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_waitingForAuthorization = false;
|
||||
|
||||
_requestScreenshareInfoRetries++;
|
||||
|
||||
if (_requestScreenshareInfoRetries >= MAX_NUM_SCREENSHARE_INFO_REQUEST_RETRIES) {
|
||||
|
@ -174,6 +209,7 @@ void ScreenshareScriptingInterface::stopScreenshare() {
|
|||
_projectAPIKey = "";
|
||||
_sessionID = "";
|
||||
_isPresenter = false;
|
||||
_waitingForAuthorization = false;
|
||||
}
|
||||
|
||||
// Called when the Metaverse returns the information necessary to start/view a screen share.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QNetworkReply>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <ReceivedMessage.h>
|
||||
|
||||
class ScreenshareScriptingInterface : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
|
@ -36,6 +37,7 @@ signals:
|
|||
void localWebEntityZOffsetChanged(const float& newZOffset);
|
||||
|
||||
private slots:
|
||||
void processAvatarZonePresencePacketOnClient(QSharedPointer<ReceivedMessage> message);
|
||||
void onWebEventReceived(const QUuid& entityID, const QVariant& message);
|
||||
void handleSuccessfulScreenshareInfoGet(QNetworkReply* reply);
|
||||
void handleFailedScreenshareInfoGet(QNetworkReply* reply);
|
||||
|
@ -82,6 +84,9 @@ private:
|
|||
QUuid _screenshareZoneID;
|
||||
QUuid _smartboardEntityID;
|
||||
bool _isPresenter{ false };
|
||||
|
||||
QUuid _lastAuthorizedZoneID;
|
||||
bool _waitingForAuthorization{ false };
|
||||
};
|
||||
|
||||
#endif // hifi_ScreenshareScriptingInterface_h
|
||||
|
|
|
@ -52,11 +52,13 @@ const int PULL_SETTINGS_RETRY_INTERVAL = 2 * MSECS_PER_SECOND;
|
|||
const int MAX_PULL_RETRIES = 10;
|
||||
|
||||
JSONCallbackParameters::JSONCallbackParameters(QObject* callbackReceiver,
|
||||
const QString& jsonCallbackMethod,
|
||||
const QString& errorCallbackMethod) :
|
||||
const QString& jsonCallbackMethod,
|
||||
const QString& errorCallbackMethod,
|
||||
const QJsonObject& callbackData) :
|
||||
callbackReceiver(callbackReceiver),
|
||||
jsonCallbackMethod(jsonCallbackMethod),
|
||||
errorCallbackMethod(errorCallbackMethod)
|
||||
errorCallbackMethod(errorCallbackMethod),
|
||||
callbackData(callbackData)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -348,9 +350,17 @@ void AccountManager::sendRequest(const QString& path,
|
|||
[callbackParams, networkReply] {
|
||||
if (networkReply->error() == QNetworkReply::NoError) {
|
||||
if (!callbackParams.jsonCallbackMethod.isEmpty()) {
|
||||
bool invoked = QMetaObject::invokeMethod(callbackParams.callbackReceiver,
|
||||
qPrintable(callbackParams.jsonCallbackMethod),
|
||||
Q_ARG(QNetworkReply*, networkReply));
|
||||
bool invoked = false;
|
||||
if (callbackParams.callbackData.isEmpty()) {
|
||||
invoked = QMetaObject::invokeMethod(callbackParams.callbackReceiver,
|
||||
qPrintable(callbackParams.jsonCallbackMethod),
|
||||
Q_ARG(QNetworkReply*, networkReply));
|
||||
} else {
|
||||
invoked = QMetaObject::invokeMethod(callbackParams.callbackReceiver,
|
||||
qPrintable(callbackParams.jsonCallbackMethod),
|
||||
Q_ARG(QNetworkReply*, networkReply),
|
||||
Q_ARG(QJsonObject, callbackParams.callbackData));
|
||||
}
|
||||
|
||||
if (!invoked) {
|
||||
QString error = "Could not invoke " + callbackParams.jsonCallbackMethod + " with QNetworkReply* "
|
||||
|
@ -366,9 +376,18 @@ void AccountManager::sendRequest(const QString& path,
|
|||
}
|
||||
} else {
|
||||
if (!callbackParams.errorCallbackMethod.isEmpty()) {
|
||||
bool invoked = QMetaObject::invokeMethod(callbackParams.callbackReceiver,
|
||||
qPrintable(callbackParams.errorCallbackMethod),
|
||||
Q_ARG(QNetworkReply*, networkReply));
|
||||
bool invoked = false;
|
||||
if (callbackParams.callbackData.isEmpty()) {
|
||||
invoked = QMetaObject::invokeMethod(callbackParams.callbackReceiver,
|
||||
qPrintable(callbackParams.errorCallbackMethod),
|
||||
Q_ARG(QNetworkReply*, networkReply));
|
||||
}
|
||||
else {
|
||||
invoked = QMetaObject::invokeMethod(callbackParams.callbackReceiver,
|
||||
qPrintable(callbackParams.errorCallbackMethod),
|
||||
Q_ARG(QNetworkReply*, networkReply),
|
||||
Q_ARG(QJsonObject, callbackParams.callbackData));
|
||||
}
|
||||
|
||||
if (!invoked) {
|
||||
QString error = "Could not invoke " + callbackParams.errorCallbackMethod + " with QNetworkReply* "
|
||||
|
|
|
@ -30,14 +30,16 @@
|
|||
class JSONCallbackParameters {
|
||||
public:
|
||||
JSONCallbackParameters(QObject* callbackReceiver = nullptr,
|
||||
const QString& jsonCallbackMethod = QString(),
|
||||
const QString& errorCallbackMethod = QString());
|
||||
const QString& jsonCallbackMethod = QString(),
|
||||
const QString& errorCallbackMethod = QString(),
|
||||
const QJsonObject& callbackData = QJsonObject());
|
||||
|
||||
bool isEmpty() const { return !callbackReceiver; }
|
||||
|
||||
QObject* callbackReceiver;
|
||||
QString jsonCallbackMethod;
|
||||
QString errorCallbackMethod;
|
||||
QJsonObject callbackData;
|
||||
};
|
||||
|
||||
namespace AccountManagerAuth {
|
||||
|
|
|
@ -68,6 +68,66 @@ const QString GET_PLACE = "/api/v1/places/%1";
|
|||
* <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* The <code>AddressManager</code> API provides facilities related to your current location in the metaverse.
|
||||
*
|
||||
* @namespace AddressManager
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @deprecated This API is deprecated and will be removed. Use the {@link location} or {@link Window|Window.location} APIs
|
||||
* instead.
|
||||
*
|
||||
* @property {Uuid} domainID - A UUID uniquely identifying the domain you're visiting. Is {@link Uuid(0)|Uuid.NULL} if you're not
|
||||
* connected to the domain or are in a serverless domain.
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} hostname - The name of the domain for your current metaverse address (e.g., <code>"DomainName"</code>,
|
||||
* <code>localhost</code>, or an IP address). Is blank if you're in a serverless domain.
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} href - Your current metaverse address (e.g., <code>"hifi://domainname/15,-10,26/0,0,0,1"</code>)
|
||||
* regardless of whether or not you're connected to the domain. Starts with <code>"file:///"</code> if you're in a
|
||||
* serverless domain.
|
||||
* <em>Read-only.</em>
|
||||
* @property {boolean} isConnected - <code>true</code> if you're connected to the domain in your current <code>href</code>
|
||||
* metaverse address, otherwise <code>false</code>.
|
||||
* @property {string} pathname - The location and orientation in your current <code>href</code> metaverse address
|
||||
* (e.g., <code>"/15,-10,26/0,0,0,1"</code>).
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} placename - The place name in your current <code>href</code> metaverse address
|
||||
* (e.g., <code>"DomainName"</code>). Is blank if your <code>hostname</code> is an IP address.
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} protocol - The protocol of your current <code>href</code> metaverse address (e.g., <code>"hifi"</code>).
|
||||
* <em>Read-only.</em>
|
||||
*
|
||||
* @borrows location.handleLookupString as handleLookupString
|
||||
* @borrows location.goToViewpointForPath as goToViewpointForPath
|
||||
* @borrows location.goBack as goBack
|
||||
* @borrows location.goForward as goForward
|
||||
* @borrows location.goToLocalSandbox as goToLocalSandbox
|
||||
* @borrows location.goToEntry as goToEntry
|
||||
* @borrows location.goToUser as goToUser
|
||||
* @borrows location.goToLastAddress as goToLastAddress
|
||||
* @borrows location.canGoBack as canGoBack
|
||||
* @borrows location.refreshPreviousLookup as refreshPreviousLookup
|
||||
* @borrows location.storeCurrentAddress as storeCurrentAddress
|
||||
* @borrows location.copyAddress as copyAddress
|
||||
* @borrows location.copyPath as copyPath
|
||||
* @borrows location.lookupShareableNameForDomainID as lookupShareableNameForDomainID
|
||||
*
|
||||
* @borrows location.lookupResultsFinished as lookupResultsFinished
|
||||
* @borrows location.lookupResultIsOffline as lookupResultIsOffline
|
||||
* @borrows location.lookupResultIsNotFound as lookupResultIsNotFound
|
||||
* @borrows location.possibleDomainChangeRequired as possibleDomainChangeRequired
|
||||
* @borrows location.locationChangeRequired as locationChangeRequired
|
||||
* @borrows location.possibleDomainChangeRequiredViaICEForID as possibleDomainChangeRequiredViaICEForID
|
||||
* @borrows location.pathChangeRequired as pathChangeRequired
|
||||
* @borrows location.hostChanged as hostChanged
|
||||
* @borrows location.goBackPossible as goBackPossible
|
||||
* @borrows location.goForwardPossible as goForwardPossible
|
||||
*/
|
||||
|
||||
class AddressManager : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
* collisions.
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
/**jsdoc
|
||||
* <p>A type of pick.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
|
|
|
@ -33,13 +33,20 @@
|
|||
#include "MainWindow.h"
|
||||
|
||||
/**jsdoc
|
||||
* The <code>OffscreenFlags</code> API enables gamepad joystick navigation of UI.
|
||||
*
|
||||
* <p><em>This API currently has no effect and is not used.</em></p>
|
||||
*
|
||||
* @namespace OffscreenFlags
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @property {boolean} navigationFocused
|
||||
* @property {boolean} navigationFocusDisabled
|
||||
*
|
||||
* @property {boolean} navigationFocused - <code>true</code> if UI has joystick navigation focus, <code>false</code> if it
|
||||
* doesn't.
|
||||
* @property {boolean} navigationFocusDisabled - <code>true</code> if UI joystick navigation focus is disabled,
|
||||
* <code>false</code> if it isn't.
|
||||
*/
|
||||
|
||||
// Needs to match the constants in resources/qml/Global.js
|
||||
|
@ -72,12 +79,14 @@ public:
|
|||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the value of the <code>navigationFocused</code> property changes.
|
||||
* @function OffscreenFlags.navigationFocusedChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void navigationFocusedChanged();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the value of the <code>navigationFocusDisabled</code> property changes.
|
||||
* @function OffscreenFlags.navigationFocusDisabledChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
|
|
@ -223,10 +223,9 @@ function onAccessApproved(desktop_id) {
|
|||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: desktop_id,
|
||||
minWidth: 1280,
|
||||
maxWidth: 1280,
|
||||
minHeight: 720,
|
||||
maxHeight: 720
|
||||
maxHeight: 720,
|
||||
maxFrameRate: 7
|
||||
}
|
||||
}
|
||||
}, gotStream, handleError);
|
||||
|
@ -261,7 +260,7 @@ function startTokboxPublisher(stream) {
|
|||
audioFallbackEnabled: false,
|
||||
audioSource: null,
|
||||
fitMode: 'contain',
|
||||
frameRate: 30,
|
||||
frameRate: 7,
|
||||
height: 720,
|
||||
insertMode: 'append',
|
||||
publishAudio: false,
|
||||
|
|
Loading…
Reference in a new issue