Merge branch 'master' of git://github.com/highfidelity/hifi into 19779

Conflicts:
	interface/src/location/LocationManager.cpp
This commit is contained in:
Ryan Huffman 2014-06-16 11:35:55 -07:00
commit a13810bd72
17 changed files with 605 additions and 495 deletions

View file

@ -15,6 +15,7 @@
#include <AccountManager.h>
#include <Assignment.h>
#include <HifiConfigVariantMap.h>
#include <Logging.h>
#include <NodeList.h>
#include <PacketHeaders.h>
@ -42,41 +43,37 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
setApplicationName("assignment-client");
QSettings::setDefaultFormat(QSettings::IniFormat);
QStringList argumentList = arguments();
// register meta type is required for queued invoke method on Assignment subclasses
// set the logging target to the the CHILD_TARGET_NAME
Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
const QString ASSIGNMENT_TYPE_OVVERIDE_OPTION = "-t";
int argumentIndex = argumentList.indexOf(ASSIGNMENT_TYPE_OVVERIDE_OPTION);
const QVariantMap argumentVariantMap = HifiConfigVariantMap::mergeCLParametersWithJSONConfig(arguments());
const QString ASSIGNMENT_TYPE_OVERRIDE_OPTION = "t";
const QString ASSIGNMENT_POOL_OPTION = "pool";
const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "wallet";
const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "a";
Assignment::Type requestAssignmentType = Assignment::AllTypes;
if (argumentIndex != -1) {
requestAssignmentType = (Assignment::Type) argumentList[argumentIndex + 1].toInt();
// check for an assignment type passed on the command line or in the config
if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) {
requestAssignmentType = (Assignment::Type) argumentVariantMap.value(ASSIGNMENT_TYPE_OVERRIDE_OPTION).toInt();
}
const QString ASSIGNMENT_POOL_OPTION = "--pool";
argumentIndex = argumentList.indexOf(ASSIGNMENT_POOL_OPTION);
QString assignmentPool;
if (argumentIndex != -1) {
assignmentPool = argumentList[argumentIndex + 1];
// check for an assignment pool passed on the command line or in the config
if (argumentVariantMap.contains(ASSIGNMENT_POOL_OPTION)) {
assignmentPool = argumentVariantMap.value(ASSIGNMENT_POOL_OPTION).toString();
}
// setup our _requestAssignment member variable from the passed arguments
_requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool);
// check if we were passed a wallet UUID on the command line
// check for a wallet UUID on the command line or in the config
// this would represent where the user running AC wants funds sent to
const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "--wallet";
if ((argumentIndex = argumentList.indexOf(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) != -1) {
QUuid walletUUID = QString(argumentList[argumentIndex + 1]);
if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) {
QUuid walletUUID = argumentVariantMap.value(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION).toString();
qDebug() << "The destination wallet UUID for credits is" << uuidStringWithoutCurlyBraces(walletUUID);
_requestAssignment.setWalletUUID(walletUUID);
}
@ -85,12 +82,8 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned);
// check for an overriden assignment server hostname
const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "-a";
argumentIndex = argumentList.indexOf(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION);
if (argumentIndex != -1) {
_assignmentServerHostname = argumentList[argumentIndex + 1];
if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION)) {
_assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString();
// set the custom assignment socket on our NodeList
HifiSockAddr customAssignmentSocket = HifiSockAddr(_assignmentServerHostname, DEFAULT_DOMAIN_SERVER_PORT);

View file

@ -195,7 +195,8 @@ bool DomainServer::optionallySetupAssignmentPayment() {
const QString HIFI_USERNAME_ENV_KEY = "DOMAIN_SERVER_USERNAME";
const QString HIFI_PASSWORD_ENV_KEY = "DOMAIN_SERVER_PASSWORD";
if (_argumentVariantMap.contains(PAY_FOR_ASSIGNMENTS_OPTION)) {
if (_argumentVariantMap.contains(PAY_FOR_ASSIGNMENTS_OPTION) &&
_argumentVariantMap.value(PAY_FOR_ASSIGNMENTS_OPTION).toBool()) {
if (!_oauthProviderURL.isEmpty()) {
AccountManager& accountManager = AccountManager::getInstance();

View file

@ -691,6 +691,10 @@ function rayPlaneIntersection(pickRay, point, normal) {
}
function mousePressEvent(event) {
if (altIsPressed) {
return;
}
mouseLastPosition = { x: event.x, y: event.y };
modelSelected = false;
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
@ -790,6 +794,10 @@ var oldModifier = 0;
var modifier = 0;
var wasShifted = false;
function mouseMoveEvent(event) {
if (altIsPressed) {
return;
}
var pickRay = Camera.computePickRay(event.x, event.y);
if (!modelSelected) {
@ -894,6 +902,10 @@ function mouseMoveEvent(event) {
}
function mouseReleaseEvent(event) {
if (altIsPressed) {
return;
}
modelSelected = false;
glowedModelID.id = -1;
@ -962,4 +974,16 @@ Menu.menuItemEvent.connect(function(menuItem){
}
});
// handling of inspect.js concurrence
altIsPressed = false;
Controller.keyPressEvent.connect(function(event) {
if (event.text == "ALT") {
altIsPressed = true;
}
});
Controller.keyReleaseEvent.connect(function(event) {
if (event.text == "ALT") {
altIsPressed = false;
}
});

View file

@ -177,30 +177,45 @@ function keyReleaseEvent(event) {
function mousePressEvent(event) {
if (alt && !isActive) {
isActive = true;
mouseLastX = event.x;
mouseLastY = event.y;
// Compute trajectories related values
var pickRay = Camera.computePickRay(mouseLastX, mouseLastY);
var intersection = Voxels.findRayIntersection(pickRay);
var voxelIntersection = Voxels.findRayIntersection(pickRay);
var modelIntersection = Models.findRayIntersection(pickRay);
position = Camera.getPosition();
avatarTarget = MyAvatar.getTargetAvatarPosition();
voxelTarget = intersection.intersection;
if (Vec3.length(Vec3.subtract(avatarTarget, position)) < Vec3.length(Vec3.subtract(voxelTarget, position))) {
if (avatarTarget.x != 0 || avatarTarget.y != 0 || avatarTarget.z != 0) {
center = avatarTarget;
} else {
center = voxelTarget;
}
} else {
if (voxelTarget.x != 0 || voxelTarget.y != 0 || voxelTarget.z != 0) {
center = voxelTarget;
} else {
center = avatarTarget;
}
var avatarTarget = MyAvatar.getTargetAvatarPosition();
var voxelTarget = voxelIntersection.intersection;
var distance = -1;
var string;
if (modelIntersection.intersects && modelIntersection.accurate) {
distance = modelIntersection.distance;
center = modelIntersection.modelProperties.position;
string = "Inspecting model";
}
if ((distance == -1 || Vec3.length(Vec3.subtract(avatarTarget, position)) < distance) &&
(avatarTarget.x != 0 || avatarTarget.y != 0 || avatarTarget.z != 0)) {
distance = Vec3.length(Vec3.subtract(avatarTarget, position));
center = avatarTarget;
string = "Inspecting avatar";
}
if ((distance == -1 || Vec3.length(Vec3.subtract(voxelTarget, position)) < distance) &&
(voxelTarget.x != 0 || voxelTarget.y != 0 || voxelTarget.z != 0)) {
distance = Vec3.length(Vec3.subtract(voxelTarget, position));
center = voxelTarget;
string = "Inspecting voxel";
}
if (distance == -1) {
return;
}
vector = Vec3.subtract(position, center);
@ -209,6 +224,8 @@ function mousePressEvent(event) {
altitude = Math.asin(vector.y / Vec3.length(vector));
Camera.keepLookingAt(center);
print(string);
isActive = true;
}
}

View file

@ -1379,6 +1379,9 @@ void Application::setEnable3DTVMode(bool enable3DTVMode) {
resizeGL(_glWidget->width(),_glWidget->height());
}
void Application::setEnableVRMode(bool enableVRMode) {
resizeGL(_glWidget->width(), _glWidget->height());
}
void Application::setRenderVoxels(bool voxelRender) {
_voxelEditSender.setShouldSend(voxelRender);

View file

@ -346,6 +346,7 @@ private slots:
void setFullscreen(bool fullscreen);
void setEnable3DTVMode(bool enable3DTVMode);
void setEnableVRMode(bool enableVRMode);
void cameraMenuChanged();
glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint);

View file

@ -127,7 +127,7 @@ Menu::Menu() :
toggleLoginMenuItem();
// connect to the appropriate slots of the AccountManager so that we can change the Login/Logout menu item
connect(&accountManager, &AccountManager::accessTokenChanged, this, &Menu::toggleLoginMenuItem);
connect(&accountManager, &AccountManager::profileChanged, this, &Menu::toggleLoginMenuItem);
connect(&accountManager, &AccountManager::logoutComplete, this, &Menu::toggleLoginMenuItem);
addDisabledActionAndSeparator(fileMenu, "Scripts");
@ -256,6 +256,11 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false,
appInstance, SLOT(cameraMenuChanged()));
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0,
false,
appInstance,
SLOT(setEnableVRMode(bool)));
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0,
false,
appInstance,
@ -1772,4 +1777,3 @@ QString Menu::getSnapshotsLocation() const {
}
return _snapshotsLocation;
}

View file

@ -336,6 +336,7 @@ namespace MenuOption {
const QString EchoLocalAudio = "Echo Local Audio";
const QString EchoServerAudio = "Echo Server Audio";
const QString Enable3DTVMode = "Enable 3DTV Mode";
const QString EnableVRMode = "Enable VR Mode";
const QString ExpandMiscAvatarTiming = "Expand Misc MyAvatar Timing";
const QString ExpandAvatarUpdateTiming = "Expand MyAvatar update Timing";
const QString ExpandAvatarSimulateTiming = "Expand MyAvatar simulate Timing";

View file

@ -23,7 +23,7 @@ XmppClient::XmppClient() :
_xmppMUCManager()
{
AccountManager& accountManager = AccountManager::getInstance();
connect(&accountManager, SIGNAL(accessTokenChanged()), this, SLOT(connectToServer()));
connect(&accountManager, SIGNAL(profileChanged()), this, SLOT(connectToServer()));
connect(&accountManager, SIGNAL(logoutComplete()), this, SLOT(disconnectFromServer()));
}

View file

@ -72,6 +72,14 @@ void OculusManager::connect() {
#endif
}
bool OculusManager::isConnected() {
#ifdef HAVE_LIBOVR
return _isConnected && Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode);
#else
return false;
#endif
}
void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) {
#ifdef HAVE_LIBOVR
_stereoConfig.SetFullViewport(Viewport(0, 0, screenWidth, screenHeight));

View file

@ -27,7 +27,7 @@ class OculusManager {
public:
static void connect();
static bool isConnected() { return _isConnected; }
static bool isConnected();
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);

View file

@ -76,6 +76,7 @@ void LocationManager::goTo(QString destination) {
// go to coordinate destination or to Username
if (!goToDestination(destination)) {
destination = QString(QUrl::toPercentEncoding(destination));
JSONCallbackParameters callbackParams;
callbackParams.jsonCallbackReceiver = this;
callbackParams.jsonCallbackMethod = "goToAddressFromResponse";

View file

@ -123,7 +123,12 @@ void AccountManager::setAuthURL(const QUrl& authURL) {
_accountInfo = settings.value(key).value<DataServerAccountInfo>();
qDebug() << "Found a data-server access token for" << qPrintable(keyURL.toString());
emit accessTokenChanged();
// profile info isn't guaranteed to be saved too
if (_accountInfo.hasProfile()) {
emit profileChanged();
} else {
requestProfile();
}
}
}
@ -320,12 +325,12 @@ void AccountManager::requestAccessToken(const QString& login, const QString& pas
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QNetworkReply* requestReply = _networkAccessManager->post(request, postData);
connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestFinished);
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError)));
connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestAccessTokenFinished);
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError)));
}
void AccountManager::requestFinished() {
void AccountManager::requestAccessTokenFinished() {
QNetworkReply* requestReply = reinterpret_cast<QNetworkReply*>(sender());
QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll());
@ -345,20 +350,18 @@ void AccountManager::requestFinished() {
qDebug() << "Storing an account with access-token for" << qPrintable(rootURL.toString());
_accountInfo = DataServerAccountInfo(rootObject);
_accountInfo = DataServerAccountInfo();
_accountInfo.setAccessTokenFromJSON(rootObject);
emit loginComplete(rootURL);
// the username has changed to whatever came back
emit usernameChanged(_accountInfo.getUsername());
// we have found or requested an access token
emit accessTokenChanged();
// store this access token into the local settings
QSettings localSettings;
localSettings.beginGroup(ACCOUNTS_GROUP);
localSettings.setValue(rootURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
QVariant::fromValue(_accountInfo));
requestProfile();
}
} else {
// TODO: error handling
@ -367,7 +370,53 @@ void AccountManager::requestFinished() {
}
}
void AccountManager::requestError(QNetworkReply::NetworkError error) {
void AccountManager::requestAccessTokenError(QNetworkReply::NetworkError error) {
// TODO: error handling
qDebug() << "AccountManager requestError - " << error;
}
void AccountManager::requestProfile() {
if (!_networkAccessManager) {
_networkAccessManager = new QNetworkAccessManager(this);
}
QUrl profileURL = _authURL;
profileURL.setPath("/api/v1/users/profile");
profileURL.setQuery("access_token=" + _accountInfo.getAccessToken().token);
QNetworkReply* profileReply = _networkAccessManager->get(QNetworkRequest(profileURL));
connect(profileReply, &QNetworkReply::finished, this, &AccountManager::requestProfileFinished);
connect(profileReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestProfileError(QNetworkReply::NetworkError)));
}
void AccountManager::requestProfileFinished() {
QNetworkReply* profileReply = reinterpret_cast<QNetworkReply*>(sender());
QJsonDocument jsonResponse = QJsonDocument::fromJson(profileReply->readAll());
const QJsonObject& rootObject = jsonResponse.object();
if (rootObject.contains("status") && rootObject["status"].toString() == "success") {
_accountInfo.setProfileInfoFromJSON(rootObject);
emit profileChanged();
// the username has changed to whatever came back
emit usernameChanged(_accountInfo.getUsername());
// store the whole profile into the local settings
QUrl rootURL = profileReply->url();
rootURL.setPath("");
QSettings localSettings;
localSettings.beginGroup(ACCOUNTS_GROUP);
localSettings.setValue(rootURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
QVariant::fromValue(_accountInfo));
} else {
// TODO: error handling
qDebug() << "Error in response for profile";
}
}
void AccountManager::requestProfileError(QNetworkReply::NetworkError error) {
// TODO: error handling
qDebug() << "AccountManager requestProfileError - " << error;
}

View file

@ -54,14 +54,17 @@ public:
Q_INVOKABLE bool checkAndSignalForAccessToken();
void requestAccessToken(const QString& login, const QString& password);
void requestProfile();
const DataServerAccountInfo& getAccountInfo() const { return _accountInfo; }
void destroy() { delete _networkAccessManager; }
public slots:
void requestFinished();
void requestError(QNetworkReply::NetworkError error);
void requestAccessTokenFinished();
void requestProfileFinished();
void requestAccessTokenError(QNetworkReply::NetworkError error);
void requestProfileError(QNetworkReply::NetworkError error);
void logout();
void updateBalance();
void accountInfoBalanceChanged(qint64 newBalance);
@ -69,7 +72,7 @@ signals:
void authRequired();
void authEndpointChanged();
void usernameChanged(const QString& username);
void accessTokenChanged();
void profileChanged();
void loginComplete(const QUrl& authURL);
void loginFailed();
void logoutComplete();

View file

@ -24,19 +24,6 @@ DataServerAccountInfo::DataServerAccountInfo() :
}
DataServerAccountInfo::DataServerAccountInfo(const QJsonObject& jsonObject) :
_accessToken(jsonObject),
_username(),
_xmppPassword(),
_balance(0),
_hasBalance(false)
{
QJsonObject userJSONObject = jsonObject["user"].toObject();
setUsername(userJSONObject["username"].toString());
setXMPPPassword(userJSONObject["xmpp_password"].toString());
setDiscourseApiKey(userJSONObject["discourse_api_key"].toString());
}
DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherInfo) {
_accessToken = otherInfo._accessToken;
_username = otherInfo._username;
@ -63,6 +50,10 @@ void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) {
swap(_hasBalance, otherInfo._hasBalance);
}
void DataServerAccountInfo::setAccessTokenFromJSON(const QJsonObject& jsonObject) {
_accessToken = OAuthAccessToken(jsonObject);
}
void DataServerAccountInfo::setUsername(const QString& username) {
if (_username != username) {
_username = username;
@ -99,6 +90,17 @@ void DataServerAccountInfo::setBalanceFromJSON(const QJsonObject& jsonObject) {
}
}
bool DataServerAccountInfo::hasProfile() const {
return _username.length() > 0;
}
void DataServerAccountInfo::setProfileInfoFromJSON(const QJsonObject& jsonObject) {
QJsonObject user = jsonObject["data"].toObject()["user"].toObject();
setUsername(user["username"].toString());
setXMPPPassword(user["xmpp_password"].toString());
setDiscourseApiKey(user["discourse_api_key"].toString());
}
QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info) {
out << info._accessToken << info._username << info._xmppPassword << info._discourseApiKey;
return out;

View file

@ -22,11 +22,11 @@ class DataServerAccountInfo : public QObject {
Q_OBJECT
public:
DataServerAccountInfo();
DataServerAccountInfo(const QJsonObject& jsonObject);
DataServerAccountInfo(const DataServerAccountInfo& otherInfo);
DataServerAccountInfo& operator=(const DataServerAccountInfo& otherInfo);
const OAuthAccessToken& getAccessToken() const { return _accessToken; }
void setAccessTokenFromJSON(const QJsonObject& jsonObject);
const QString& getUsername() const { return _username; }
void setUsername(const QString& username);
@ -43,6 +43,10 @@ public:
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
Q_INVOKABLE void setBalanceFromJSON(const QJsonObject& jsonObject);
bool hasProfile() const;
void setProfileInfoFromJSON(const QJsonObject& jsonObject);
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
signals:

View file

@ -42,18 +42,17 @@ QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringL
nextKeyIndex = argumentList.indexOf(dashedKeyRegex, keyIndex + 1);
if (nextKeyIndex == keyIndex + 1 || keyIndex == argumentList.size() - 1) {
// there's no value associated with this option, it's a boolean
// so add it to the variant map with NULL as value
mergedMap.insertMulti(key, QVariant());
// this option is simply a switch, so add it to the map with a value of `true`
mergedMap.insertMulti(key, QVariant(true));
} else {
int maxIndex = (nextKeyIndex == -1) ? argumentList.size() - 1: nextKeyIndex;
int maxIndex = (nextKeyIndex == -1) ? argumentList.size() : nextKeyIndex;
// there's at least one value associated with the option
// pull the first value to start
QString value = argumentList[keyIndex + 1];
// for any extra values, append them, with a space, to the value string
for (int i = keyIndex + 2; i <= maxIndex; i++) {
for (int i = keyIndex + 2; i < maxIndex; i++) {
value += " " + argumentList[i];
}