This commit is contained in:
Stephen Birarda 2014-12-19 12:50:32 -08:00
commit 08581b4dac
12 changed files with 135 additions and 144 deletions

View file

@ -549,7 +549,9 @@ void DomainServer::populateDefaultStaticAssignmentsExcludingTypes(const QSet<Ass
for (Assignment::Type defaultedType = Assignment::AudioMixerType;
defaultedType != Assignment::AllTypes;
defaultedType = static_cast<Assignment::Type>(static_cast<int>(defaultedType) + 1)) {
if (!excludedTypes.contains(defaultedType) && defaultedType != Assignment::AgentType) {
if (!excludedTypes.contains(defaultedType)
&& defaultedType != Assignment::UNUSED
&& defaultedType != Assignment::AgentType) {
// type has not been set from a command line or config file config, use the default
// by clearing whatever exists and writing a single default assignment with no payload
Assignment* newAssignment = new Assignment(Assignment::CreateCommand, (Assignment::Type) defaultedType);

View file

@ -1,25 +1,32 @@
//
// notifications.js
// notifications.js
// Version 0.801
// Created by Adrian
//
// Adrian McCarlie 8-10-14
// This script demonstrates on-screen overlay type notifications.
// Copyright 2014 High Fidelity, Inc.
//
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// This script demonstrates notifications created via a number of ways, such as:
// Simple key press alerts, which only depend on a key being pressed,
// dummy examples of this are "q", "w", "e", "r", and "SPACEBAR".
// actual working examples are "a" for left turn, "d" for right turn and Ctrl/s for snapshot.
// System generated alerts such as users joining and leaving and chat messages which mention this user.
// System generated alerts which originate with a user interface event such as Window Resize, and Mic Mute/Unmute.
// Mic Mute/Unmute may appear to be a key press alert, but it actually gets the call from the system as mic is muted and unmuted,
// so the mic mute/unmute will also trigger the notification by clicking the Mic Mute button at the top of the screen.
// This script generates notifications created via a number of ways, such as:
// keystroke:
//
// "q" returns number of users currently online (for debug purposes)
// CTRL/s for snapshot.
// CTRL/m for mic mute and unmute.
// System generated notifications:
// Displays users online at startup.
// If Screen is resized.
// Triggers notification if @MyUserName is mentioned in chat.
// Announces existing user logging out.
// Announces new user logging in.
// If mic is muted for any reason.
//
// To add a new System notification type:
//
// 1. Set the Event Connector at the bottom of the script.
@ -45,22 +52,23 @@
// 2. Declare a text string.
// 3. Call createNotifications(text) parsing the text.
// example:
// if (key.text == "a") {
// var noteString = "Turning to the Left";
// createNotification(noteString);
// }
// if (key.text == "q") { //queries number of users online
// var numUsers = GlobalServices.onlineUsers.length;
// var welcome = "There are " + numUsers + " users online now.";
// createNotification(welcome);
// }
var width = 340.0; //width of notification overlay
var height = 40.0; // height of a single line notification overlay
var windowDimensions = Controller.getViewportDimensions(); // get the size of the interface window
var overlayLocationX = (windowDimensions.x - (width + 60.0));// positions window 60px from the right of the interface window
var overlayLocationX = (windowDimensions.x - (width + 20.0));// positions window 20px from the right of the interface window
var buttonLocationX = overlayLocationX + (width - 28.0);
var locationY = 20.0; // position down from top of interface window
var topMargin = 13.0;
var leftMargin = 10.0;
var textColor = { red: 228, green: 228, blue: 228}; // text color
var backColor = { red: 38, green: 38, blue: 38}; // background color
var backColor = { red: 2, green: 2, blue: 2}; // background color was 38,38,38
var backgroundAlpha = 0;
var fontSize = 12.0;
var persistTime = 10.0; // time in seconds before notification fades
@ -115,7 +123,6 @@ function createNotification(text) {
color: textColor,
backgroundColor: backColor,
alpha: backgroundAlpha,
backgroundAlpha: backgroundAlpha,
topMargin: topMargin,
leftMargin: leftMargin,
font: {size: fontSize},
@ -125,8 +132,8 @@ function createNotification(text) {
var buttonProperties = {
x: buttonLocationX,
y: bLevel,
width: 15.0,
height: 15.0,
width: 10.0,
height: 10.0,
subImage: { x: 0, y: 0, width: 10, height: 10 },
imageURL: "http://hifi-public.s3.amazonaws.com/images/close-small-light.svg",
color: { red: 255, green: 255, blue: 255},
@ -161,7 +168,7 @@ function fadeIn(noticeIn, buttonIn) {
pauseTimer = Script.setInterval(function() {
q++;
qFade = q / 10.0;
Overlays.editOverlay(noticeIn, {alpha: qFade, backgroundAlpha: qFade});
Overlays.editOverlay(noticeIn, {alpha: qFade});
Overlays.editOverlay(buttonIn, {alpha: qFade});
if (q >= 9.0) {
Script.clearInterval(pauseTimer);
@ -203,41 +210,18 @@ function keyPressEvent(key) {
if (key.key == 16777249) {
ctrlIsPressed = true;
}
if (key.text == "a") {
var noteString = "Turning to the Left";
createNotification(noteString);
}
if (key.text == "d") {
var noteString = "Turning to the Right";
createNotification(noteString);
}
if (key.text == "q") { //queries number of users online
var numUsers = GlobalServices.onlineUsers.length;
var welcome = "There are " + numUsers + " users online now.";
createNotification(welcome);
}
if (key.text == "s") {
if (ctrlIsPressed == true){
var noteString = "You have taken a snapshot";
var noteString = "Snapshot taken.";
createNotification(noteString);
}
}
if (key.text == "q") {
var noteString = "Enable Scripted Motor control is now on.";
wordWrap(noteString);
}
if (key.text == "w") {
var noteString = "This notification spans 2 lines. The overlay will resize to fit new lines.";
var noteString = "editVoxels.js stopped, editModels.js stopped, selectAudioDevice.js stopped.";
wordWrap(noteString);
}
if (key.text == "e") {
var noteString = "This is an example of a multiple line notification. This notification will span 3 lines."
wordWrap(noteString);
}
if (key.text == "r") {
var noteString = "This is a very long line of text that we are going to use in this example to divide it into rows of maximum 43 chars and see how many lines we use.";
wordWrap(noteString);
}
if (key.text == "SPACE") {
var noteString = "You have pressed the Spacebar, This is an example of a multiple line notification. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.";
wordWrap(noteString);
}
}
// formats string to add newline every 43 chars
@ -275,18 +259,14 @@ function checkSize(){
// Triggers notification if a user logs on or off
function onOnlineUsersChanged(users) {
var joiners = [];
var leavers = [];
for (user in users) {
if (last_users.indexOf(users[user]) == -1.0) {
joiners.push(users[user]);
createNotification(users[user] + " Has joined");
if (last_users.indexOf(users[user]) == -1.0) {
createNotification(users[user] + " has joined");
}
}
for (user in last_users) {
if (users.indexOf(last_users[user]) == -1.0) {
leavers.push(last_users[user]);
createNotification(last_users[user] + " Has left");
createNotification(last_users[user] + " has left");
}
}
last_users = users;
@ -303,8 +283,8 @@ function onIncomingMessage(user, message) {
}
// Triggers mic mute notification
function onMuteStateChanged() {
var muteState = AudioDevice.getMuted() ? "Muted" : "Unmuted";
var muteString = "Microphone is set to " + muteState;
var muteState = AudioDevice.getMuted() ? "muted" : "unmuted";
var muteString = "Microphone is now " + muteState;
createNotification(muteString);
}
@ -345,7 +325,7 @@ function fadeOut(noticeOut, buttonOut, arraysOut) {
pauseTimer = Script.setInterval(function() {
r--;
rFade = r / 10.0;
Overlays.editOverlay(noticeOut, {alpha: rFade, backgroundAlpha: rFade});
Overlays.editOverlay(noticeOut, {alpha: rFade});
Overlays.editOverlay(buttonOut, {alpha: rFade});
if (r < 0) {
dismiss(noticeOut, buttonOut, arraysOut);
@ -368,10 +348,17 @@ function dismiss(firstNoteOut, firstButOut, firstOut) {
myAlpha.splice(firstOut,1);
}
onMuteStateChanged();
// This is meant to show users online at startup but currently shows 0 users.
function onConnected() {
var numUsers = GlobalServices.onlineUsers.length;
var welcome = "Welcome! There are " + numUsers + " users online now.";
createNotification(welcome);
}
AudioDevice.muteToggled.connect(onMuteStateChanged);
Controller.keyPressEvent.connect(keyPressEvent);
Controller.mousePressEvent.connect(mousePressEvent);
GlobalServices.connected.connect(onConnected);
GlobalServices.onlineUsersChanged.connect(onOnlineUsersChanged);
GlobalServices.incomingMessage.connect(onIncomingMessage);
Controller.keyReleaseEvent.connect(keyReleaseEvent);

View file

@ -309,13 +309,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
// use our MyAvatar position and quat for address manager path
addressManager.setPositionGetter(getPositionForPath);
addressManager.setOrientationGetter(getOrientationForPath);
// handle domain change signals from AddressManager
connect(&addressManager, &AddressManager::possibleDomainChangeRequiredToHostname,
this, &Application::changeDomainHostname);
connect(&addressManager, &AddressManager::possibleDomainChangeRequiredViaICEForID,
&domainHandler, &DomainHandler::setIceServerHostnameAndID);
_settings = new QSettings(this);
_numChangedSettings = 0;
@ -1433,7 +1426,7 @@ void Application::dropEvent(QDropEvent *event) {
SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath);
if (snapshotData) {
if (!snapshotData->getDomain().isEmpty()) {
changeDomainHostname(snapshotData->getDomain());
NodeList::getInstance()->getDomainHandler().setHostnameAndPort(snapshotData->getDomain());
}
_myAvatar->setPosition(snapshotData->getLocation());
@ -3698,19 +3691,6 @@ void Application::updateLocationInServer() {
}
}
void Application::changeDomainHostname(const QString &newDomainHostname) {
NodeList* nodeList = NodeList::getInstance();
if (!nodeList->getDomainHandler().isCurrentHostname(newDomainHostname)) {
// tell the MyAvatar object to send a kill packet so that it dissapears from its old avatar mixer immediately
_myAvatar->sendKillAvatar();
// call the domain hostname change as a queued connection on the nodelist
QMetaObject::invokeMethod(&NodeList::getInstance()->getDomainHandler(), "setHostname",
Q_ARG(const QString&, newDomainHostname));
}
}
void Application::clearDomainOctreeDetails() {
qDebug() << "Clearing domain octree details...";
// reset the environment so that we don't erroneously end up with multiple

View file

@ -335,7 +335,6 @@ signals:
void importDone();
public slots:
void changeDomainHostname(const QString& newDomainHostname);
void domainChanged(const QString& domainHostname);
void updateWindowTitle();
void updateLocationInServer();

View file

@ -116,8 +116,9 @@ void AddressBarDialog::setupUI() {
void AddressBarDialog::showEvent(QShowEvent* event) {
_goButton->setIcon(QIcon(PathUtils::resourcesPath() + ADDRESSBAR_GO_BUTTON_ICON));
_addressLineEdit->setText(QString());
_addressLineEdit->setText(AddressManager::getInstance().currentAddress().toString());
_addressLineEdit->setFocus();
_addressLineEdit->selectAll();
FramelessDialog::showEvent(event);
}

View file

@ -443,7 +443,14 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
// key state, stored as a semi-nibble in the bitItems
_keyState = (KeyState)getSemiNibbleAt(bitItems,KEY_STATE_START_BIT);
// hand state, stored as a semi-nibble plus a bit in the bitItems
// we store the hand state as well as other items in a shared bitset. The hand state is an octal, but is split
// into two sections to maintain backward compatibility. The bits are ordered as such (0-7 left to right).
// +---+-----+-----+--+
// |x,x|H0,H1|x,x,x|H2|
// +---+-----+-----+--+
// Hand state - H0,H1,H2 is found in the 3rd, 4th, and 8th bits
_handState = getSemiNibbleAt(bitItems, HAND_STATE_START_BIT)
+ (oneAtBit(bitItems, HAND_STATE_FINGER_POINTING_BIT) ? IS_FINGER_POINTING_FLAG : 0);

View file

@ -76,7 +76,17 @@ const quint32 AVATAR_MOTION_SCRIPTABLE_BITS =
AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
// First bitset
// Bitset of state flags - we store the key state, hand state, faceshift, chat circling, and existance of
// referential data in this bit set. The hand state is an octal, but is split into two sections to maintain
// backward compatibility. The bits are ordered as such (0-7 left to right).
// +-----+-----+-+-+-+--+
// |K0,K1|H0,H1|F|C|R|H2|
// +-----+-----+-+-+-+--+
// Key state - K0,K1 is found in the 1st and 2nd bits
// Hand state - H0,H1,H2 is found in the 3rd, 4th, and 8th bits
// Faceshift - F is found in the 5th bit
// Chat Circling - C is found in the 6th bit
// Referential Data - R is found in the 7th bit
const int KEY_STATE_START_BIT = 0; // 1st and 2nd bits
const int HAND_STATE_START_BIT = 2; // 3rd and 4th bits
const int IS_FACESHIFT_CONNECTED = 4; // 5th bit

View file

@ -107,7 +107,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl) {
if (!handleUsername(lookupUrl.authority())) {
// we're assuming this is either a network address or global place name
// check if it is a network address first
if (!handleNetworkAddress(lookupUrl.host())) {
if (!handleNetworkAddress(lookupUrl.host()
+ (lookupUrl.port() == -1 ? "" : ":" + QString::number(lookupUrl.port())))) {
// wasn't an address - lookup the place name
attemptPlaceNameLookup(lookupUrl.host());
}
@ -172,7 +173,7 @@ void AddressManager::goToAddressFromObject(const QVariantMap& addressMap) {
if (domainObject.contains(DOMAIN_NETWORK_ADDRESS_KEY)) {
QString domainHostname = domainObject[DOMAIN_NETWORK_ADDRESS_KEY].toString();
emit possibleDomainChangeRequiredToHostname(domainHostname);
emit possibleDomainChangeRequired(domainHostname, DEFAULT_DOMAIN_SERVER_PORT);
} else {
QString iceServerAddress = domainObject[DOMAIN_ICE_SERVER_ADDRESS_KEY].toString();
@ -240,30 +241,40 @@ void AddressManager::attemptPlaceNameLookup(const QString& lookupString) {
}
bool AddressManager::handleNetworkAddress(const QString& lookupString) {
const QString IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}"
"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:\\d{1,5})?$";
const QString IP_ADDRESS_REGEX_STRING = "^((?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}"
"(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(?::(\\d{1,5}))?$";
const QString HOSTNAME_REGEX_STRING = "^((?:[A-Z0-9]|[A-Z0-9][A-Z0-9\\-]{0,61}[A-Z0-9])"
"(?:\\.(?:[A-Z0-9]|[A-Z0-9][A-Z0-9\\-]{0,61}[A-Z0-9]))+|localhost)(:{1}\\d{1,5})?$";
QRegExp hostnameRegex(HOSTNAME_REGEX_STRING, Qt::CaseInsensitive);
if (hostnameRegex.indexIn(lookupString) != -1) {
QString domainHostname = hostnameRegex.cap(0);
emit lookupResultsFinished();
setDomainHostnameAndName(domainHostname);
return true;
}
"(?:\\.(?:[A-Z0-9]|[A-Z0-9][A-Z0-9\\-]{0,61}[A-Z0-9]))+|localhost)(?::(\\d{1,5}))?$";
QRegExp ipAddressRegex(IP_ADDRESS_REGEX_STRING);
if (ipAddressRegex.indexIn(lookupString) != -1) {
QString domainIPString = ipAddressRegex.cap(0);
QString domainIPString = ipAddressRegex.cap(1);
qint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
if (!ipAddressRegex.cap(2).isEmpty()) {
domainPort = (qint16) ipAddressRegex.cap(2).toInt();
}
emit lookupResultsFinished();
setDomainHostnameAndName(domainIPString);
setDomainInfo(domainIPString, domainPort);
return true;
}
QRegExp hostnameRegex(HOSTNAME_REGEX_STRING, Qt::CaseInsensitive);
if (hostnameRegex.indexIn(lookupString) != -1) {
QString domainHostname = hostnameRegex.cap(1);
qint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
if (!hostnameRegex.cap(2).isEmpty()) {
domainPort = (qint16) hostnameRegex.cap(2).toInt();
}
emit lookupResultsFinished();
setDomainInfo(domainHostname, domainPort);
return true;
}
@ -339,9 +350,9 @@ bool AddressManager::handleUsername(const QString& lookupString) {
}
void AddressManager::setDomainHostnameAndName(const QString& hostname, const QString& domainName) {
void AddressManager::setDomainInfo(const QString& hostname, quint16 port, const QString& domainName) {
_currentDomain = domainName.isEmpty() ? hostname : domainName;
emit possibleDomainChangeRequiredToHostname(hostname);
emit possibleDomainChangeRequired(hostname, port);
}
void AddressManager::goToUser(const QString& username) {

View file

@ -59,7 +59,7 @@ signals:
void lookupResultsFinished();
void lookupResultIsOffline();
void lookupResultIsNotFound();
void possibleDomainChangeRequiredToHostname(const QString& newHostname);
void possibleDomainChangeRequired(const QString& newHostname, quint16 newPort);
void possibleDomainChangeRequiredViaICEForID(const QString& iceServerHostname, const QUuid& domainID);
void locationChangeRequired(const glm::vec3& newPosition,
bool hasOrientationChange, const glm::quat& newOrientation,
@ -70,7 +70,7 @@ private slots:
private:
AddressManager();
void setDomainHostnameAndName(const QString& hostname, const QString& domainName = QString());
void setDomainInfo(const QString& hostname, quint16 port, const QString& domainName = QString());
const JSONCallbackParameters& apiCallbackParameters();

View file

@ -97,46 +97,32 @@ void DomainHandler::setUUID(const QUuid& uuid) {
}
}
QString DomainHandler::hostnameWithoutPort(const QString& hostname) {
int colonIndex = hostname.indexOf(':');
return colonIndex > 0 ? hostname.left(colonIndex) : hostname;
}
bool DomainHandler::isCurrentHostname(const QString& hostname) {
return hostnameWithoutPort(hostname) == _hostname;
}
void DomainHandler::setHostname(const QString& hostname) {
void DomainHandler::setHostnameAndPort(const QString& hostname, quint16 port) {
if (hostname != _hostname) {
if (hostname != _hostname || _sockAddr.getPort() != port) {
// re-set the domain info so that auth information is reloaded
hardReset();
int colonIndex = hostname.indexOf(':');
if (colonIndex > 0) {
// the user has included a custom DS port with the hostname
// the new hostname is everything up to the colon
_hostname = hostname.left(colonIndex);
// grab the port by reading the string after the colon
_sockAddr.setPort(atoi(hostname.mid(colonIndex + 1, hostname.size()).toLocal8Bit().constData()));
qDebug() << "Updated hostname to" << _hostname << "and port to" << _sockAddr.getPort();
} else {
// no port included with the hostname, simply set the member variable and reset the domain server port to default
if (hostname != _hostname) {
// set the new hostname
_hostname = hostname;
_sockAddr.setPort(DEFAULT_DOMAIN_SERVER_PORT);
qDebug() << "Updated domain hostname to" << _hostname;
// re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname
qDebug("Looking up DS hostname %s.", _hostname.toLocal8Bit().constData());
QHostInfo::lookupHost(_hostname, this, SLOT(completedHostnameLookup(const QHostInfo&)));
UserActivityLogger::getInstance().changedDomain(_hostname);
emit hostnameChanged(_hostname);
}
// re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname
qDebug("Looking up DS hostname %s.", _hostname.toLocal8Bit().constData());
QHostInfo::lookupHost(_hostname, this, SLOT(completedHostnameLookup(const QHostInfo&)));
if (_sockAddr.getPort() != port) {
qDebug() << "Updated domain port to" << port;
}
UserActivityLogger::getInstance().changedDomain(_hostname);
emit hostnameChanged(_hostname);
// grab the port by reading the string after the colon
_sockAddr.setPort(port);
}
}

View file

@ -37,9 +37,7 @@ public:
const QUuid& getUUID() const { return _uuid; }
void setUUID(const QUuid& uuid);
static QString hostnameWithoutPort(const QString& hostname);
bool isCurrentHostname(const QString& hostname);
const QString& getHostname() const { return _hostname; }
const QHostAddress& getIP() const { return _sockAddr.getAddress(); }
@ -75,7 +73,7 @@ public:
void softReset();
public slots:
void setHostname(const QString& hostname);
void setHostnameAndPort(const QString& hostname, quint16 port = DEFAULT_DOMAIN_SERVER_PORT);
void setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id);
private slots:

View file

@ -18,6 +18,7 @@
#include <LogHandler.h>
#include "AccountManager.h"
#include "AddressManager.h"
#include "Assignment.h"
#include "HifiSockAddr.h"
#include "NodeList.h"
@ -62,6 +63,15 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
_hasCompletedInitialSTUNFailure(false),
_stunRequestsSinceSuccess(0)
{
AddressManager& addressManager = AddressManager::getInstance();
// handle domain change signals from AddressManager
connect(&addressManager, &AddressManager::possibleDomainChangeRequired,
&_domainHandler, &DomainHandler::setHostnameAndPort);
connect(&addressManager, &AddressManager::possibleDomainChangeRequiredViaICEForID,
&_domainHandler, &DomainHandler::setIceServerHostnameAndID);
// clear our NodeList when the domain changes
connect(&_domainHandler, &DomainHandler::disconnectedFromDomain, this, &NodeList::reset);