From 34d9e9b3711a82c1cfc10d92c8b5222c7967a9d3 Mon Sep 17 00:00:00 2001 From: Menithal Date: Tue, 8 Aug 2017 00:03:24 +0300 Subject: [PATCH 01/30] Preliminary Research Complete Found the part that needs updating with the AnimationProperty --- .../src/RenderableModelEntityItem.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 911fdf4184..a1d1b9d866 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -282,7 +282,8 @@ bool RenderableModelEntityItem::getAnimationFrame() { const QVector& frames = animation->getFramesReference(); // NOTE: getFrames() is too heavy auto& fbxJoints = animation->getGeometry().joints; - + auto& originalFbxJoints = _model->getFBXGeometry().joints; // model-> isLoaded above makes sure this doesnt crash to an assert! + int frameCount = frames.size(); if (frameCount > 0) { int animationCurrentFrame = (int)(glm::floor(getAnimationCurrentFrame())) % frameCount; @@ -309,9 +310,18 @@ bool RenderableModelEntityItem::getAnimationFrame() { int index = _jointMapping[j]; if (index >= 0) { glm::mat4 translationMat; - if (index < translations.size()) { + + bool _removeme_flag = false; + // this is the part to attack. + // S omethings off even with the original Joints. + if (!_removeme_flag ){ + + translationMat = glm::translate(originalFbxJoints[index].translation); + + } else if (_removeme_flag && index < translations.size()) { translationMat = glm::translate(translations[index]); - } + } + glm::mat4 rotationMat; if (index < rotations.size()) { rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * rotations[index] * fbxJoints[index].postRotation); From 982d4a451fd3085ef63a47b5fa50c059bd51685d Mon Sep 17 00:00:00 2001 From: Menithal Date: Tue, 8 Aug 2017 23:47:37 +0300 Subject: [PATCH 02/30] Updated Protocol to add allowTranslation There still is a bug for the value no actually updating --- .../src/avatars/ScriptableAvatar.cpp | 2 +- .../src/RenderableModelEntityItem.cpp | 18 ++++++------- .../entities/src/AnimationPropertyGroup.cpp | 26 +++++++++++++++++++ .../entities/src/AnimationPropertyGroup.h | 1 + .../entities/src/EntityItemProperties.cpp | 1 + libraries/entities/src/EntityPropertyFlags.h | 1 + libraries/entities/src/ModelEntityItem.cpp | 8 ++++++ libraries/entities/src/ModelEntityItem.h | 5 +++- libraries/networking/src/udt/PacketHeaders.h | 1 + libraries/shared/src/RegisteredMetaTypes.cpp | 5 ++-- libraries/shared/src/RegisteredMetaTypes.h | 3 ++- .../shared/src/shared/types/AnimationLoop.h | 4 +++ scripts/system/html/entityProperties.html | 4 +++ scripts/system/html/js/entityProperties.js | 3 +++ 14 files changed, 68 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index c7715d4014..5060891284 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -35,7 +35,7 @@ void ScriptableAvatar::startAnimation(const QString& url, float fps, float prior return; } _animation = DependencyManager::get()->getAnimation(url); - _animationDetails = AnimationDetails("", QUrl(url), fps, 0, loop, hold, false, firstFrame, lastFrame, true, firstFrame); + _animationDetails = AnimationDetails("", QUrl(url), fps, 0, loop, hold, false, firstFrame, lastFrame, true, firstFrame, false); _maskedJoints = maskedJoints; } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index a1d1b9d866..ce821c4656 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -279,12 +279,16 @@ bool RenderableModelEntityItem::getAnimationFrame() { auto animation = getAnimation(); if (animation && animation->isLoaded()) { - - const QVector& frames = animation->getFramesReference(); // NOTE: getFrames() is too heavy + + const QVector& frames = animation->getFramesReference(); // NOTE: getFrames() is too heavy auto& fbxJoints = animation->getGeometry().joints; + auto& originalFbxJoints = _model->getFBXGeometry().joints; // model-> isLoaded above makes sure this doesnt crash to an assert! int frameCount = frames.size(); + + bool allowTranslation = getAnimationAllowTranslation(); + if (frameCount > 0) { int animationCurrentFrame = (int)(glm::floor(getAnimationCurrentFrame())) % frameCount; if (animationCurrentFrame < 0 || animationCurrentFrame > frameCount) { @@ -311,14 +315,10 @@ bool RenderableModelEntityItem::getAnimationFrame() { if (index >= 0) { glm::mat4 translationMat; - bool _removeme_flag = false; - // this is the part to attack. - // S omethings off even with the original Joints. - if (!_removeme_flag ){ - + if (allowTranslation){ translationMat = glm::translate(originalFbxJoints[index].translation); - - } else if (_removeme_flag && index < translations.size()) { + } + else if (!allowTranslation && index < translations.size()) { translationMat = glm::translate(translations[index]); } diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 848d4352a7..e53405c989 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -29,6 +29,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame, _animationLoop->getFirstFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame, _animationLoop->getLastFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold, _animationLoop->getHold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation, _animationLoop->getAllowTranslation); } else { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame); @@ -37,6 +38,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation); } } @@ -56,6 +58,7 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, _animationLoop->setFirstFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, _animationLoop->setLastFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, _animationLoop->setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, allowTranslation, bool, _animationLoop->setAllowTranslation); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS); @@ -70,6 +73,7 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, allowTranslation, bool, setAllowTranslation); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS); @@ -112,6 +116,7 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop(); bool hold = _animationLoop ? _animationLoop->getHold() : getHold(); + bool allowTranslation = _animationLoop ? _animationLoop->getAllowTranslation() : getAllowTranslation(); QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); QJsonObject settingsAsJsonObject = settingsAsJson.object(); @@ -146,6 +151,10 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { running = settingsMap["hold"].toBool(); } + if (settingsMap.contains("allowTranslation")) { + allowTranslation = settingsMap["allowTranslation"].toBool(); + } + if (_animationLoop) { _animationLoop->setFPS(fps); _animationLoop->setCurrentFrame(currentFrame); @@ -154,6 +163,7 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { _animationLoop->setLastFrame(lastFrame); _animationLoop->setLoop(loop); _animationLoop->setHold(hold); + _animationLoop->setAllowTranslation(allowTranslation); } else { setFPS(fps); setCurrentFrame(currentFrame); @@ -162,6 +172,7 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { setLastFrame(lastFrame); setLoop(loop); setHold(hold); + setAllowTranslation(allowTranslation); } } @@ -204,6 +215,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, _animationLoop->getAllowTranslation()); } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); @@ -212,6 +224,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, getAllowTranslation()); } return true; @@ -234,6 +247,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, _animationLoop->setAllowTranslation); } else { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); @@ -242,6 +256,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, setAllowTranslation); } DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL); @@ -252,6 +267,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_ALLOW_TRANSLATION, AllowTranslation); processedBytes += bytesRead; @@ -282,6 +298,7 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_ALLOW_TRANSLATION, allowTranslation); return changedProperties; } @@ -296,6 +313,7 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, _animationLoop->getFirstFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, _animationLoop->getLastFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, _animationLoop->getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, AllowTranslation, _animationLoop->getAllowTranslation); } else { COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, getCurrentFrame); @@ -304,6 +322,7 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, AllowTranslation, getAllowTranslation); } } @@ -319,6 +338,7 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, _animationLoop->setFirstFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, _animationLoop->setLastFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, _animationLoop->setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, AllowTranslation, allowTranslation, _animationLoop->setAllowTranslation); } else { SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, setCurrentFrame); @@ -327,6 +347,7 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, AllowTranslation, allowTranslation, setAllowTranslation); } return somethingChanged; @@ -343,6 +364,7 @@ EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamP requestedProperties += PROP_ANIMATION_FIRST_FRAME; requestedProperties += PROP_ANIMATION_LAST_FRAME; requestedProperties += PROP_ANIMATION_HOLD; + requestedProperties += PROP_ANIMATION_ALLOW_TRANSLATION; return requestedProperties; } @@ -366,6 +388,7 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, _animationLoop->getAllowTranslation()); } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); @@ -374,6 +397,7 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getAllowTranslation()); } } @@ -396,6 +420,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, _animationLoop->setAllowTranslation); } else { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); @@ -404,6 +429,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, setAllowTranslation); } return bytesRead; diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index c0086b41b3..474cd453b5 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -86,6 +86,7 @@ public: DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float, 0.0f); // was animationSettings.firstFrame DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, AnimationLoop::MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold + DEFINE_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, AllowTranslation, allowTranslation, bool, true); protected: void setFromOldAnimationSettings(const QString& value); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 1bd75f78d4..b3581f2b07 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1036,6 +1036,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); + ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation); ADD_GROUP_PROPERTY_TO_MAP(PROP_SKYBOX_COLOR, Skybox, skybox, Color, color); ADD_GROUP_PROPERTY_TO_MAP(PROP_SKYBOX_URL, Skybox, skybox, URL, url); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 9600d0d4fe..ef8a0cbb37 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -40,6 +40,7 @@ enum EntityPropertyList { PROP_ANIMATION_FPS, PROP_ANIMATION_FRAME_INDEX, PROP_ANIMATION_PLAYING, + PROP_ANIMATION_ALLOW_TRANSLATION, // these properties are supported by the EntityItem base class PROP_REGISTRATION_POINT, diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index b5e759d2d8..7f37d59b64 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -144,6 +144,10 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, dataAt += bytesFromAnimation; } + if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES){ + READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, setAnimationAllowTranslation); + } + READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType); if (animationPropertiesChanged) { @@ -345,6 +349,10 @@ void ModelEntityItem::setAnimationSettings(const QString& value) { setAnimationHold(hold); } + if (settingsMap.contains("allowTranslation")) { + bool allowTranslation = settingsMap["allowTranslation"].toBool(); + setAnimationAllowTranslation(allowTranslation); + } _dirtyFlags |= Simulation::DIRTY_UPDATEABLE; } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 0c6132e211..9daee95655 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -87,7 +87,10 @@ public: void setAnimationCurrentFrame(float value) { _animationLoop.setCurrentFrame(value); } void setAnimationIsPlaying(bool value); - void setAnimationFPS(float value); + void setAnimationFPS(float value); + + void setAnimationAllowTranslation(bool value) { _animationProperties.setAllowTranslation(value); }; + bool getAnimationAllowTranslation() const { return _animationProperties.getAllowTranslation(); }; void setAnimationLoop(bool loop) { _animationLoop.setLoop(loop); } bool getAnimationLoop() const { return _animationLoop.getLoop(); } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index e2304e62f7..e56666607f 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -258,6 +258,7 @@ const PacketVersion VERSION_ENTITIES_ZONE_FILTERS = 68; const PacketVersion VERSION_ENTITIES_HINGE_CONSTRAINT = 69; const PacketVersion VERSION_ENTITIES_BULLET_DYNAMICS = 70; const PacketVersion VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT = 71; +const PacketVersion VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES = 72; enum class EntityQueryPacketVersion: PacketVersion { JSONFilter = 18, diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index b30637c83f..b4d6ebaa7a 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -808,10 +808,10 @@ AnimationDetails::AnimationDetails() : } AnimationDetails::AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop, - bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame) : + bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame, bool allowTranslation) : role(role), url(url), fps(fps), priority(priority), loop(loop), hold(hold), startAutomatically(startAutomatically), firstFrame(firstFrame), lastFrame(lastFrame), - running(running), currentFrame(currentFrame) { + running(running), currentFrame(currentFrame), allowTranslation(allowTranslation) { } @@ -828,6 +828,7 @@ QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const Animatio obj.setProperty("lastFrame", details.lastFrame); obj.setProperty("running", details.running); obj.setProperty("currentFrame", details.currentFrame); + obj.setProperty("allowTranslation", details.allowTranslation); return obj; } diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 123c769a96..b6e4b01c5f 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -174,7 +174,7 @@ class AnimationDetails { public: AnimationDetails(); AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop, - bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame); + bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame, bool allowTranslation); QString role; QUrl url; @@ -187,6 +187,7 @@ public: float lastFrame; bool running; float currentFrame; + bool allowTranslation; }; Q_DECLARE_METATYPE(AnimationDetails); QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& event); diff --git a/libraries/shared/src/shared/types/AnimationLoop.h b/libraries/shared/src/shared/types/AnimationLoop.h index 33434209e7..604e62446a 100644 --- a/libraries/shared/src/shared/types/AnimationLoop.h +++ b/libraries/shared/src/shared/types/AnimationLoop.h @@ -35,6 +35,9 @@ public: void setHold(bool hold) { _hold = hold; } bool getHold() const { return _hold; } + void setAllowTranslation(bool value) { _allowTranslation = value; } + bool getAllowTranslation() const { return _allowTranslation; } + void setStartAutomatically(bool startAutomatically); bool getStartAutomatically() const { return _startAutomatically; } @@ -67,6 +70,7 @@ private: float _fps; bool _loop; bool _hold; + bool _allowTranslation; bool _startAutomatically; float _firstFrame; float _lastFrame; diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index bf65bdad32..b0676859a0 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -393,6 +393,10 @@ +
+ + +
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index ce2f766946..4a06c89db4 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -609,6 +609,7 @@ function loaded() { var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame"); var elModelAnimationLoop = document.getElementById("property-model-animation-loop"); var elModelAnimationHold = document.getElementById("property-model-animation-hold"); + var elModelAnimationAllowTranslation = document.getElementById("property-model-animation-allow-translation"); var elModelTextures = document.getElementById("property-model-textures"); var elModelOriginalTextures = document.getElementById("property-model-original-textures"); @@ -946,6 +947,7 @@ function loaded() { elModelAnimationLastFrame.value = properties.animation.lastFrame; elModelAnimationLoop.checked = properties.animation.loop; elModelAnimationHold.checked = properties.animation.hold; + elModelAnimationAllowTranslation.checked = properties.animation.allowTranslation; elModelTextures.value = properties.textures; setTextareaScrolling(elModelTextures); elModelOriginalTextures.value = properties.originalTextures; @@ -1298,6 +1300,7 @@ function loaded() { elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame')); elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop')); elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold')); + elModelAnimationAllowTranslation.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'allowTranslation')); elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures')); From e00ef220dacb4f5301d084f5171d6f024df19831 Mon Sep 17 00:00:00 2001 From: algoworks Date: Tue, 8 Aug 2017 14:01:28 -0700 Subject: [PATCH 03/30] 3 file changes, build directory --- interface/src/Application.cpp | 2 +- libraries/physics/src/EntityMotionState.cpp | 2 +- libraries/physics/src/PhysicsEngine.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ceded99f40..0e2f7ca55d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -242,7 +242,7 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI static const uint32_t INVALID_FRAME = UINT32_MAX; -static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check for entities that aren't ready for simulation +static const float PHYSICS_READY_RANGE = 1.0f; // how far from avatar to check for entities that aren't ready for simulation static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index f02dcee8f6..93ef140f30 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -531,7 +531,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ } if (!_body->isStaticOrKinematicObject()) { - const float DYNAMIC_LINEAR_VELOCITY_THRESHOLD = 0.05f; // 5 cm/sec + const float DYNAMIC_LINEAR_VELOCITY_THRESHOLD = 0.02f; // 5 cm/sec const float DYNAMIC_ANGULAR_VELOCITY_THRESHOLD = 0.087266f; // ~5 deg/sec bool movingSlowlyLinear = diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index a64796308e..1dba0e9a07 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -441,7 +441,7 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() { while (contactItr != _contactMap.end()) { ContactInfo& contact = contactItr->second; ContactEventType type = contact.computeType(_numContactFrames); - const btScalar SIGNIFICANT_DEPTH = -0.002f; // penetrations have negative distance + const btScalar SIGNIFICANT_DEPTH = -0.008f; // penetrations have negative distance if (type != CONTACT_EVENT_TYPE_CONTINUE || (contact.distance < SIGNIFICANT_DEPTH && contact.readyForContinue(_numContactFrames))) { From ea79748ed335f0d0fda7c6cb8b96a8a07b4d1e8f Mon Sep 17 00:00:00 2001 From: Menithal Date: Tue, 29 Aug 2017 23:59:36 +0300 Subject: [PATCH 04/30] Some adjustments --- .../src/RenderableModelEntityItem.cpp | 1 - .../entities/src/AnimationPropertyGroup.cpp | 22 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 5914ceb9e1..dbe6eaf501 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -294,7 +294,6 @@ bool RenderableModelEntityItem::getAnimationFrame() { auto& originalFbxJoints = _model->getFBXGeometry().joints; // model-> isLoaded above makes sure this doesnt crash to an assert! int frameCount = frames.size(); - bool allowTranslation = getAnimationAllowTranslation(); if (frameCount > 0) { diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 6482acf944..8b6641bb2a 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -20,6 +20,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation); if (_animationLoop) { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, Animation, animation, FPS, fps, _animationLoop->getFPS); @@ -38,13 +39,12 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); } - - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation); } void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, url, QString, setURL); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, allowTranslation, bool, setAllowTranslation); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationURL, QString, setURL, getURL); @@ -78,13 +78,11 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, setRunning, getRunning); COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setCurrentFrame, getCurrentFrame); } - - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, allowTranslation, bool, setAllowTranslation); - } void AnimationPropertyGroup::merge(const AnimationPropertyGroup& other) { COPY_PROPERTY_IF_CHANGED(url); + COPY_PROPERTY_IF_CHANGED(allowTranslation); if (_animationLoop) { _fps = _animationLoop->getFPS(); _currentFrame = _animationLoop->getCurrentFrame(); @@ -93,7 +91,6 @@ void AnimationPropertyGroup::merge(const AnimationPropertyGroup& other) { _firstFrame = _animationLoop->getFirstFrame(); _lastFrame = _animationLoop->getLastFrame(); _hold = _animationLoop->getHold(); - _allowTranslation = getAllowTranslation(); } else { COPY_PROPERTY_IF_CHANGED(fps); COPY_PROPERTY_IF_CHANGED(currentFrame); @@ -102,9 +99,7 @@ void AnimationPropertyGroup::merge(const AnimationPropertyGroup& other) { COPY_PROPERTY_IF_CHANGED(firstFrame); COPY_PROPERTY_IF_CHANGED(lastFrame); COPY_PROPERTY_IF_CHANGED(hold); - COPY_PROPERTY_IF_CHANGED(allowTranslation); } - } void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { @@ -185,6 +180,7 @@ void AnimationPropertyGroup::debugDump() const { qCDebug(entities) << " url:" << getURL() << " has changed:" << urlChanged(); qCDebug(entities) << " fps:" << getFPS() << " has changed:" << fpsChanged(); qCDebug(entities) << "currentFrame:" << getCurrentFrame() << " has changed:" << currentFrameChanged(); + qCDebug(entities) << "allowTranslation:" << getAllowTranslation() << " has changed:" << allowTranslationChanged(); } void AnimationPropertyGroup::listChangedProperties(QList& out) { @@ -197,6 +193,9 @@ void AnimationPropertyGroup::listChangedProperties(QList& out) { if (currentFrameChanged()) { out << "animation-currentFrame"; } + if (allowTranslationChanged()) { + out << "animation-allowTranslation"; + } } @@ -207,9 +206,11 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, int& propertyCount, OctreeElement::AppendState& appendState) const { - bool successPropertyFits = true; + bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, getAllowTranslation()); + if (_animationLoop) { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getCurrentFrame()); @@ -228,8 +229,6 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); } - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, getAllowTranslation()); - return true; } @@ -287,6 +286,7 @@ void AnimationPropertyGroup::markAllChanged() { _firstFrameChanged = true; _lastFrameChanged = true; _holdChanged = true; + _allowTranslationChanged = true; } EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { From 8fbdd207c8da2933c1177bb896bfc5e1b4fffad2 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 31 Aug 2017 12:10:12 -0700 Subject: [PATCH 05/30] display hfc in "pennies" --- .../qml/hifi/commerce/checkout/Checkout.qml | 28 ++++----- .../qml/hifi/commerce/wallet/WalletHome.qml | 4 +- interface/src/commerce/Ledger.cpp | 59 ++++++++++++++++++- 3 files changed, 73 insertions(+), 18 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 109e357206..72e4e7622b 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -89,8 +89,8 @@ Rectangle { console.log("Failed to get balance", result.data.message); } else { root.balanceReceived = true; - hfcBalanceText.text = (parseFloat(result.data.balance/100).toFixed(2)) + " HFC"; - balanceAfterPurchase = parseFloat(result.data.balance/100) - root.itemPriceFull/100; + hfcBalanceText.text = result.data.balance + " HFC"; + balanceAfterPurchase = result.data.balance - root.itemPriceFull; root.setBuyText(); } } @@ -199,7 +199,7 @@ Rectangle { commerce.getLoginStatus(); } } - + HifiWallet.NeedsLogIn { id: needsLogIn; visible: root.activeView === "needsLogIn"; @@ -222,7 +222,7 @@ Rectangle { } - + // // "WALLET NOT SET UP" START // @@ -233,7 +233,7 @@ Rectangle { anchors.bottom: parent.bottom; anchors.left: parent.left; anchors.right: parent.right; - + RalewayRegular { id: notSetUpText; text: "Your wallet isn't set up.

Set up your Wallet (no credit card necessary) to claim your free HFC " + @@ -264,7 +264,7 @@ Rectangle { anchors.left: parent.left; anchors.bottom: parent.bottom; anchors.bottomMargin: 24; - + // "Cancel" button HifiControlsUit.Button { id: cancelButton; @@ -648,7 +648,7 @@ Rectangle { sendToScript({method: 'checkout_goToPurchases'}); } } - + RalewayRegular { id: buyText; // Text size @@ -687,7 +687,7 @@ Rectangle { anchors.bottom: root.bottom; anchors.left: parent.left; anchors.right: parent.right; - + RalewayRegular { id: completeText; text: "Purchase Complete!

You bought " + (itemNameText.text) + " by " + (itemAuthorText.text) + ""; @@ -706,7 +706,7 @@ Rectangle { horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter; } - + Item { id: checkoutSuccessActionButtonsContainer; // Size @@ -756,7 +756,7 @@ Rectangle { } } } - + Item { id: continueShoppingButtonContainer; // Size @@ -799,7 +799,7 @@ Rectangle { anchors.bottom: root.bottom; anchors.left: parent.left; anchors.right: parent.right; - + RalewayRegular { id: failureHeaderText; text: "Purchase Failed.
Your Purchases and HFC balance haven't changed."; @@ -818,7 +818,7 @@ Rectangle { horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter; } - + RalewayRegular { id: failureErrorText; // Text size @@ -836,7 +836,7 @@ Rectangle { horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter; } - + Item { id: backToMarketplaceButtonContainer; // Size @@ -892,7 +892,7 @@ Rectangle { itemNameText.text = message.params.itemName; itemAuthorText.text = message.params.itemAuthor; root.itemPriceFull = message.params.itemPrice; - itemPriceText.text = root.itemPriceFull === 0 ? "Free" : "" + (parseFloat(root.itemPriceFull/100).toFixed(2)) + " HFC"; + itemPriceText.text = root.itemPriceFull === 0 ? "Free" : "" + root.itemPriceFull + " HFC"; itemHref = message.params.itemHref; if (itemHref.indexOf('.json') === -1) { root.itemIsJson = false; diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index b55f7f800a..413fd8b71c 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -38,7 +38,7 @@ Item { } onBalanceResult : { - balanceText.text = parseFloat(result.data.balance/100).toFixed(2); + balanceText.text = result.data.balance; } onHistoryResult : { @@ -272,7 +272,7 @@ Item { horizontalAlignment: Text.AlignLeft; verticalAlignment: Text.AlignVCenter; } - + HifiControlsUit.Separator { anchors.left: parent.left; anchors.right: parent.right; diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 08eb79017f..9991958455 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include "AccountManager.h" #include "Wallet.h" @@ -45,7 +46,6 @@ Handler(buy) Handler(receiveAt) Handler(balance) Handler(inventory) -Handler(history) void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, QJsonObject request) { auto accountManager = DependencyManager::get(); @@ -108,6 +108,61 @@ void Ledger::inventory(const QStringList& keys) { keysQuery("inventory", "inventorySuccess", "inventoryFailure"); } +QString nameFromKey(const QString& key, const QStringList& publicKeys) { + if (key.isNull() || key.isEmpty()) { + return "Marketplace"; + } + if (publicKeys.contains(key)) { + return "You"; + } + return "Someone"; +} + +void Ledger::historySuccess(QNetworkReply& reply) { + // here we send a historyResult with some extra stuff in it + // Namely, the styled text we'd like to show. The issue is the + // QML cannot do that easily since it doesn't know what the wallet + // public key(s) are. Let's keep it that way + QByteArray response = reply.readAll(); + QJsonObject data = QJsonDocument::fromJson(response).object(); + + // we will need the array of public keys from the wallet + auto wallet = DependencyManager::get(); + auto keys = wallet->listPublicKeys(); + + // now we need to loop through the transactions and add fancy text... + auto historyArray = data.find("data").value().toObject().find("history").value().toArray(); + QJsonArray newHistoryArray; + + // TODO: do this with 0 copies if possible + auto it = historyArray.begin(); + for(auto it = historyArray.begin(); it != historyArray.end(); it++) { + auto valueObject = (*it).toObject(); + QString from = nameFromKey(valueObject["sender_key"].toString(), keys); + QString to = nameFromKey(valueObject["recipient_key"].toString(), keys); + // turns out on my machine, toLocalTime convert to some weird timezone, yet the + // systemTimeZone is correct. To avoid a strange bug with other's systems too, lets + // be explicit + QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC); + QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone()); + valueObject["text"] = QString("%1 sent %2 %3 %4 on %5 with message \"%6\""). + arg(from, to, QString::number(valueObject["quantity"].toInt()), valueObject["asset_title"].toString(), localCreatedAt.toString(Qt::SystemLocaleShortDate), valueObject["message"].toString()); + newHistoryArray.push_back(valueObject); + } + // now copy the rest of the json -- this is inefficient + // TODO: try to do this without making copies + QJsonObject newData; + newData["status"] = "success"; + QJsonObject newDataData; + newDataData["history"] = newHistoryArray; + newData["data"] = newDataData; + emit historyResult(newData); +} + +void Ledger::historyFailure(QNetworkReply& reply) { + failResponse("history", reply); +} + void Ledger::history(const QStringList& keys) { keysQuery("history", "historySuccess", "historyFailure"); } @@ -117,4 +172,4 @@ void Ledger::resetSuccess(QNetworkReply& reply) { apiResponse("reset", reply); } void Ledger::resetFailure(QNetworkReply& reply) { failResponse("reset", reply); } void Ledger::reset() { send("reset_user_hfc_account", "resetSuccess", "resetFailure", QNetworkAccessManager::PutOperation, QJsonObject()); -} \ No newline at end of file +} From 914a6bae00ecd90e0868ffba2f3897a648152533 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 12:18:38 -0700 Subject: [PATCH 06/30] Commerce: Wallet Passphrase Modal --- .../hifi/commerce/wallet/PassphraseModal.qml | 232 ++++++++++++++++++ .../commerce/wallet/PassphraseSelection.qml | 4 - .../qml/hifi/commerce/wallet/Wallet.qml | 32 +++ interface/src/commerce/QmlCommerce.cpp | 1 + interface/src/commerce/QmlCommerce.h | 1 + interface/src/commerce/Wallet.cpp | 7 +- interface/src/commerce/Wallet.h | 3 +- scripts/system/commerce/wallet.js | 1 + 8 files changed, 273 insertions(+), 8 deletions(-) create mode 100644 interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml new file mode 100644 index 0000000000..71cb61686e --- /dev/null +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -0,0 +1,232 @@ +// +// PassphraseModal.qml +// qml/hifi/commerce/wallet +// +// PassphraseModal +// +// Created by Zach Fox on 2017-08-18 +// Copyright 2017 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 +// + +import Hifi 1.0 as Hifi +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import "../../../styles-uit" +import "../../../controls-uit" as HifiControlsUit +import "../../../controls" as HifiControls + +// references XXX from root context + +Item { + HifiConstants { id: hifi; } + + id: root; + Hifi.QmlCommerce { + id: commerce; + + onSecurityImageResult: { + passphraseModalSecurityImage.source = ""; + passphraseModalSecurityImage.source = "image://security/securityImage"; + } + } + + // This object is always used in a popup. + // This MouseArea is used to prevent a user from being + // able to click on a button/mouseArea underneath the popup. + MouseArea { + anchors.fill: parent; + propagateComposedEvents: false; + } + + // This will cause a bug -- if you bring up passphrase selection in HUD mode while + // in HMD while having HMD preview enabled, then move, then finish passphrase selection, + // HMD preview will stay off. + // TODO: Fix this unlikely bug + onVisibleChanged: { + if (visible) { + passphraseField.focus = true; + sendSignalToWallet({method: 'disableHmdPreview'}); + } else { + sendSignalToWallet({method: 'maybeEnableHmdPreview'}); + } + } + + // Background rectangle + Rectangle { + anchors.fill: parent; + color: "black"; + opacity: 0.9; + } + + Rectangle { + anchors.top: parent.top; + anchors.left: parent.left; + anchors.right: parent.right; + height: 220; + color: hifi.colors.baseGray; + + RalewaySemiBold { + id: instructionsText; + text: "Enter Wallet Passphrase"; + size: 16; + anchors.top: parent.top; + anchors.topMargin: 30; + anchors.left: parent.left; + anchors.leftMargin: 16; + width: passphraseField.width; + height: paintedHeight; + // Style + color: hifi.colors.faintGray; + // Alignment + horizontalAlignment: Text.AlignLeft; + } + + HifiControlsUit.TextField { + id: passphraseField; + anchors.top: instructionsText.bottom; + anchors.topMargin: 4; + anchors.left: instructionsText.left; + width: 280; + height: 50; + echoMode: TextInput.Password; + placeholderText: "passphrase"; + + onFocusChanged: { + if (focus) { + sendSignalToWallet({method: 'walletSetup_raiseKeyboard'}); + } else if (!passphraseFieldAgain.focus) { + sendSignalToWallet({method: 'walletSetup_lowerKeyboard'}); + } + } + + MouseArea { + anchors.fill: parent; + onClicked: { + parent.focus = true; + sendSignalToWallet({method: 'walletSetup_raiseKeyboard'}); + } + } + + onAccepted: { + //commerce.submitWalletPassphrase(passphraseField.text); + } + } + + // Show passphrase text + HifiControlsUit.CheckBox { + id: showPassphrase; + colorScheme: hifi.colorSchemes.dark; + anchors.left: passphraseField.left; + anchors.top: passphraseField.bottom; + anchors.topMargin: 8; + height: 30; + text: "Show passphrase as plain text"; + boxSize: 24; + onClicked: { + passphraseField.echoMode = checked ? TextInput.Normal : TextInput.Password; + } + } + + // Security Image + Item { + id: securityImageContainer; + // Anchors + anchors.top: instructionsText.top; + anchors.left: passphraseField.right; + anchors.leftMargin: 12; + anchors.right: parent.right; + Image { + id: passphraseModalSecurityImage; + anchors.top: parent.top; + anchors.horizontalCenter: parent.horizontalCenter; + height: 75; + width: height; + fillMode: Image.PreserveAspectFit; + mipmap: true; + source: "image://security/securityImage"; + cache: false; + onVisibleChanged: { + commerce.getSecurityImage(); + } + } + Image { + id: passphraseModalSecurityImageOverlay; + source: "images/lockOverlay.png"; + width: passphraseModalSecurityImage.width * 0.45; + height: passphraseModalSecurityImage.height * 0.45; + anchors.bottom: passphraseModalSecurityImage.bottom; + anchors.right: passphraseModalSecurityImage.right; + mipmap: true; + opacity: 0.9; + } + // "Security image" text below pic + RalewayRegular { + text: "security image"; + // Text size + size: 12; + // Anchors + anchors.top: passphraseModalSecurityImage.bottom; + anchors.topMargin: 4; + anchors.left: securityImageContainer.left; + anchors.right: securityImageContainer.right; + height: paintedHeight; + // Style + color: hifi.colors.faintGray; + // Alignment + horizontalAlignment: Text.AlignHCenter; + verticalAlignment: Text.AlignVCenter; + } + } + + // + // ACTION BUTTONS START + // + Item { + id: passphrasePopupActionButtonsContainer; + // Size + width: root.width; + height: 50; + // Anchors + anchors.left: parent.left; + anchors.bottom: parent.bottom; + anchors.bottomMargin: 10; + + // "Cancel" button + HifiControlsUit.Button { + id: cancelPassphraseInputButton; + color: hifi.buttons.black; + colorScheme: hifi.colorSchemes.dark; + anchors.top: parent.top; + height: 40; + anchors.left: parent.left; + anchors.leftMargin: 20; + width: parent.width/2 - anchors.leftMargin*2; + text: "Cancel" + onClicked: { + sendSignalToWallet({method: 'passphrasePopup_cancelClicked'}); + } + } + + // "Submit" button + HifiControlsUit.Button { + id: submitPassphraseInputButton; + color: hifi.buttons.blue; + colorScheme: hifi.colorSchemes.dark; + anchors.top: parent.top; + height: 40; + anchors.right: parent.right; + anchors.rightMargin: 20; + width: parent.width/2 - anchors.rightMargin*2; + text: "Submit" + onClicked: { + //commerce.submitWalletPassphrase(passphraseField.text); + } + } + } + } + + signal sendSignalToWallet(var msg); +} diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml index 39d07315d5..2bad454b63 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml @@ -58,10 +58,6 @@ Item { } } - SecurityImageModel { - id: gridModel; - } - HifiControlsUit.TextField { id: passphraseField; anchors.top: parent.top; diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 53838fa58c..42760abacd 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -62,6 +62,16 @@ Rectangle { root.activeView = "walletHome"; } } + + onWalletAuthenticatedStatus: { + if (!isAuthenticated && !passphraseModal.visible) { + passphraseModal.visible = true; + } else if (isAuthenticated && passphraseModal.visible) { + passphraseModal.visible = false; + commerce.getSecurityImage(); + commerce.getKeyFilePathIfExists(); + } + } } SecurityImageModel { @@ -218,6 +228,28 @@ Rectangle { } } + PassphraseModal { + id: passphraseModal; + z: 998; + //visible: false; + anchors.top: titleBarContainer.bottom; + anchors.bottom: parent.bottom; + anchors.left: parent.left; + anchors.right: parent.right; + + Connections { + onSendSignalToWallet: { + if (msg.method === 'walletSetup_raiseKeyboard') { + root.keyboardRaised = true; + } else if (msg.method === 'walletSetup_lowerKeyboard') { + root.keyboardRaised = false; + } else { + sendToScript(msg); + } + } + } + } + NotSetUp { id: notSetUp; visible: root.activeView === "notSetUp"; diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 655f228672..2f424b7cc8 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -27,6 +27,7 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) { connect(wallet.data(), &Wallet::securityImageResult, this, &QmlCommerce::securityImageResult); connect(ledger.data(), &Ledger::historyResult, this, &QmlCommerce::historyResult); connect(wallet.data(), &Wallet::keyFilePathIfExistsResult, this, &QmlCommerce::keyFilePathIfExistsResult); + connect(wallet.data(), &Wallet::walletAuthenticatedStatus, this, &QmlCommerce::walletAuthenticatedStatus); } void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUsername) { diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index deb11b7714..a9eca34242 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -38,6 +38,7 @@ signals: void passphraseSetupStatusResult(bool passphraseIsSetup); void historyResult(QJsonObject result); void keyFilePathIfExistsResult(const QString& path); + void walletAuthenticatedStatus(bool isAuthenticated); protected: Q_INVOKABLE void buy(const QString& assetId, int cost, const QString& buyerUsername = ""); diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 32852602d7..569e0f9110 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -55,13 +55,14 @@ QString imageFilePath() { // use the cached _passphrase if it exists, otherwise we need to prompt int passwordCallback(char* password, int maxPasswordSize, int rwFlag, void* u) { // just return a hardcoded pwd for now - auto passphrase = DependencyManager::get()->getPassphrase(); + auto wallet = DependencyManager::get(); + auto passphrase = wallet->getPassphrase(); if (passphrase) { strcpy(password, passphrase->toLocal8Bit().constData()); + emit wallet->walletAuthenticatedStatus(true); return static_cast(passphrase->size()); } else { - // ok gotta bring up modal dialog... But right now lets just - // just keep it empty + emit wallet->walletAuthenticatedStatus(false); return 0; } } diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 4acd913181..24575c5ca4 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -43,8 +43,9 @@ public: void reset(); signals: - void securityImageResult(bool exists) ; + void securityImageResult(bool exists); void keyFilePathIfExistsResult(const QString& path); + void walletAuthenticatedStatus(bool isAuthenticated); private: QStringList _publicKeys{}; diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index a7b7b50379..5f07c4cbe7 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -56,6 +56,7 @@ var isHmdPreviewDisabled = true; function fromQml(message) { switch (message.method) { + case 'passphrasePopup_cancelClicked': case 'walletSetup_cancelClicked': case 'needsLogIn_cancelClicked': tablet.gotoHomeScreen(); From 396f1081824ff4bc2b5bab40c9a23e9109ba6a22 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 31 Aug 2017 12:18:46 -0700 Subject: [PATCH 07/30] forgot this the first time --- scripts/system/html/js/marketplacesInject.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 2675bb97b6..57450d043b 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -27,7 +27,7 @@ var isPreparing = false; // Explicitly track download request status. var confirmAllPurchases = false; // Set this to "true" to cause Checkout.qml to popup for all items, even if free - + function injectCommonCode(isDirectoryPage) { // Supporting styles from marketplaces.css. @@ -122,7 +122,7 @@ function injectBuyButtonOnMainPage() { var cost; - + $('.grid-item').find('#price-or-edit').find('a').each(function() { $(this).attr('data-href', $(this).attr('href')); $(this).attr('href', '#'); @@ -130,7 +130,7 @@ $(this).closest('.col-xs-3').prev().attr("class", 'col-xs-6'); $(this).closest('.col-xs-3').attr("class", 'col-xs-6'); - + if (parseInt(cost) > 0) { var priceElement = $(this).find('.price') priceElement.css({ "width": "auto", "padding": "3px 5px", "height": "26px" }); @@ -138,8 +138,8 @@ priceElement.css({ "min-width": priceElement.width() + 10 }); } }); - - + + $('.grid-item').find('#price-or-edit').find('a').on('click', function () { buyButtonClicked($(this).closest('.grid-item').attr('data-item-id'), $(this).closest('.grid-item').find('.item-title').text(), @@ -175,11 +175,11 @@ if (confirmAllPurchases) { var href = $('#side-info').find('.btn').attr('href'); $('#side-info').find('.btn').attr('href', '#'); - + var cost = $('.item-cost').text(); if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) { - $('#side-info').find('.btn').html('Own Item: ' + (parseFloat(cost / 100).toFixed(2)) + ' HFC'); + $('#side-info').find('.btn').html('Own Item: ' + cost + ' HFC'); } $('#side-info').find('.btn').on('click', function () { @@ -264,7 +264,7 @@ // Reference: https://clara.io/learn/sdk/api/export //var XMLHTTPREQUEST_URL = "https://clara.io/api/scenes/{uuid}/export/fbx?zip=true¢erScene=true&alignSceneGround=true&fbxUnit=Meter&fbxVersion=7&fbxEmbedTextures=true&imageFormat=WebGL"; - // 13 Jan 2017: Specify FBX version 5 and remove some options in order to make Clara.io site more likely to + // 13 Jan 2017: Specify FBX version 5 and remove some options in order to make Clara.io site more likely to // be successful in generating zip files. var XMLHTTPREQUEST_URL = "https://clara.io/api/scenes/{uuid}/export/fbx?fbxUnit=Meter&fbxVersion=5&fbxEmbedTextures=true&imageFormat=WebGL"; @@ -447,7 +447,7 @@ cancelClaraDownload(); } else { var parsedJsonMessage = JSON.parse(message); - + if (parsedJsonMessage.type === "marketplaces") { if (parsedJsonMessage.action === "inspectionModeSetting") { confirmAllPurchases = !!parsedJsonMessage.data; From 21a73b2f3989a13fe3bd0e67d18732b9acf405cb Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 13:15:22 -0700 Subject: [PATCH 08/30] Changes in what I think are the right direction --- .../qml/hifi/commerce/wallet/Wallet.qml | 43 +++++++++++++------ interface/src/commerce/QmlCommerce.cpp | 16 +++++-- interface/src/commerce/QmlCommerce.h | 3 +- interface/src/commerce/Wallet.cpp | 8 ++-- interface/src/commerce/Wallet.h | 4 +- 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 42760abacd..04278e85a9 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -40,8 +40,32 @@ Rectangle { root.activeView = "needsLogIn"; } else if (isLoggedIn) { root.activeView = "initialize"; - commerce.getSecurityImage(); - commerce.getKeyFilePathIfExists(); + commerce.getPassphraseSetupStatus(); + } + } + + onPassphraseSetupStatusResult: { + if (!passphraseIsSetup && root.activeView !== "notSetUp") { + root.activeView = "notSetUp"; + } else if (passphraseIsSetup && root.activeView === "initialize") { + commerce.getWalletAuthenticatedStatus(); + } + } + + onWalletAuthenticatedStatusResult: { + if (!isAuthenticated && !passphraseModal.visible) { + passphraseModal.visible = true; + } else if (isAuthenticated) { + if (passphraseModal.visible) { + passphraseModal.visible = false; + } + + if (!securityImageResultReceived) { + commerce.getSecurityImage(); + } + if (!keyFilePathIfExistsResultReceived) { + commerce.getKeyFilePathIfExists(); + } } } @@ -62,16 +86,6 @@ Rectangle { root.activeView = "walletHome"; } } - - onWalletAuthenticatedStatus: { - if (!isAuthenticated && !passphraseModal.visible) { - passphraseModal.visible = true; - } else if (isAuthenticated && passphraseModal.visible) { - passphraseModal.visible = false; - commerce.getSecurityImage(); - commerce.getKeyFilePathIfExists(); - } - } } SecurityImageModel { @@ -99,7 +113,8 @@ Rectangle { if (msg.method === 'walletSetup_cancelClicked') { walletSetupLightbox.visible = false; } else if (msg.method === 'walletSetup_finished') { - root.activeView = "walletHome"; + root.activeView = "initialize"; + commerce.getPassphraseSetupStatus(); } else if (msg.method === 'walletSetup_raiseKeyboard') { root.keyboardRaised = true; } else if (msg.method === 'walletSetup_lowerKeyboard') { @@ -231,7 +246,7 @@ Rectangle { PassphraseModal { id: passphraseModal; z: 998; - //visible: false; + visible: false; anchors.top: titleBarContainer.bottom; anchors.bottom: parent.bottom; anchors.left: parent.left; diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 2f424b7cc8..ccbc37ed13 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -27,7 +27,6 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) { connect(wallet.data(), &Wallet::securityImageResult, this, &QmlCommerce::securityImageResult); connect(ledger.data(), &Ledger::historyResult, this, &QmlCommerce::historyResult); connect(wallet.data(), &Wallet::keyFilePathIfExistsResult, this, &QmlCommerce::keyFilePathIfExistsResult); - connect(wallet.data(), &Wallet::walletAuthenticatedStatus, this, &QmlCommerce::walletAuthenticatedStatus); } void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUsername) { @@ -76,12 +75,23 @@ void QmlCommerce::getLoginStatus() { } void QmlCommerce::setPassphrase(const QString& passphrase) { - emit passphraseSetupStatusResult(true); + auto wallet = DependencyManager::get(); + wallet->setPassphrase(passphrase); + getPassphraseSetupStatus(); } void QmlCommerce::getPassphraseSetupStatus() { - emit passphraseSetupStatusResult(false); + auto wallet = DependencyManager::get(); + // ????? WHAT DO I DO HERE + emit passphraseSetupStatusResult(wallet->getPassphraseIsCached()); } + +void QmlCommerce::getWalletAuthenticatedStatus() { + auto wallet = DependencyManager::get(); + // ????? WHAT DO I DO HERE + emit walletAuthenticatedStatusResult(wallet->getPassphraseIsCached()); +} + void QmlCommerce::getKeyFilePathIfExists() { auto wallet = DependencyManager::get(); wallet->sendKeyFilePathIfExists(); diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index a9eca34242..5561f331f9 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -38,7 +38,7 @@ signals: void passphraseSetupStatusResult(bool passphraseIsSetup); void historyResult(QJsonObject result); void keyFilePathIfExistsResult(const QString& path); - void walletAuthenticatedStatus(bool isAuthenticated); + void walletAuthenticatedStatusResult(bool isAuthenticated); protected: Q_INVOKABLE void buy(const QString& assetId, int cost, const QString& buyerUsername = ""); @@ -50,6 +50,7 @@ protected: Q_INVOKABLE void getLoginStatus(); Q_INVOKABLE void setPassphrase(const QString& passphrase); Q_INVOKABLE void getPassphraseSetupStatus(); + Q_INVOKABLE void getWalletAuthenticatedStatus(); Q_INVOKABLE void getKeyFilePathIfExists(); Q_INVOKABLE void reset(); }; diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 569e0f9110..cfd5b6baa5 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -55,14 +55,14 @@ QString imageFilePath() { // use the cached _passphrase if it exists, otherwise we need to prompt int passwordCallback(char* password, int maxPasswordSize, int rwFlag, void* u) { // just return a hardcoded pwd for now - auto wallet = DependencyManager::get(); - auto passphrase = wallet->getPassphrase(); + auto passphrase = DependencyManager::get()->getPassphrase(); if (passphrase) { strcpy(password, passphrase->toLocal8Bit().constData()); - emit wallet->walletAuthenticatedStatus(true); return static_cast(passphrase->size()); } else { - emit wallet->walletAuthenticatedStatus(false); + // Old comment below...this should never happen once we're here...what if it does? + // ok gotta bring up modal dialog... But right now lets just + // just keep it empty return 0; } } diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 24575c5ca4..cb0e318598 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -39,19 +39,19 @@ public: void setPassphrase(const QString& passphrase); QString* getPassphrase() { return _passphrase; } + bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); } void reset(); signals: void securityImageResult(bool exists); void keyFilePathIfExistsResult(const QString& path); - void walletAuthenticatedStatus(bool isAuthenticated); private: QStringList _publicKeys{}; QPixmap* _securityImage { nullptr }; QByteArray _salt {"iamsalt!"}; - QString* _passphrase { new QString("pwd") }; + QString* _passphrase { new QString("") }; void updateImageProvider(); bool encryptFile(const QString& inputFilePath, const QString& outputFilePath); From f8341ce1daacf48626516b756b8605f4102c90e4 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 31 Aug 2017 13:24:07 -0700 Subject: [PATCH 09/30] warning --- interface/src/commerce/Ledger.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 9991958455..0f7f533e13 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -135,7 +135,6 @@ void Ledger::historySuccess(QNetworkReply& reply) { QJsonArray newHistoryArray; // TODO: do this with 0 copies if possible - auto it = historyArray.begin(); for(auto it = historyArray.begin(); it != historyArray.end(); it++) { auto valueObject = (*it).toObject(); QString from = nameFromKey(valueObject["sender_key"].toString(), keys); From cdadaa8c9c220b15d868095d8e68b43432a2c0fa Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 31 Aug 2017 13:41:53 -0700 Subject: [PATCH 10/30] missed one --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 72e4e7622b..d3de8f745b 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -553,7 +553,7 @@ Rectangle { } RalewayRegular { id: balanceAfterPurchaseText; - text: balanceAfterPurchase.toFixed(2) + " HFC"; + text: balanceAfterPurchase + " HFC"; // Text size size: balanceAfterPurchaseTextLabel.size; // Anchors From 663e8514de62fc56710ecd4a252d8bddce8355ca Mon Sep 17 00:00:00 2001 From: Menithal Date: Fri, 1 Sep 2017 00:00:24 +0300 Subject: [PATCH 11/30] Found the culprit. Was overriding the value --- libraries/entities/src/AnimationPropertyGroup.cpp | 1 + libraries/entities/src/ModelEntityItem.cpp | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 8b6641bb2a..18f56fa703 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -414,6 +414,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, setAllowTranslation); + if (_animationLoop) { // apply new properties to our associated AnimationLoop READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 7f37d59b64..07b55d419e 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -144,10 +144,6 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, dataAt += bytesFromAnimation; } - if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES){ - READ_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, bool, setAnimationAllowTranslation); - } - READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType); if (animationPropertiesChanged) { @@ -160,6 +156,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, QVector, setJointTranslationsSet); READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, QVector, setJointTranslations); + return bytesRead; } From ce32d2d42068c45ae99b4da58807f9a2c10f9425 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 14:12:05 -0700 Subject: [PATCH 12/30] Checkout and Purchases --- .../qml/hifi/commerce/checkout/Checkout.qml | 54 ++++++++++++++++--- .../qml/hifi/commerce/purchases/Purchases.qml | 48 +++++++++++++++-- .../hifi/commerce/wallet/PassphraseModal.qml | 54 ++++++++++++++++--- .../qml/hifi/commerce/wallet/Wallet.qml | 10 +--- scripts/system/marketplaces/marketplaces.js | 1 + 5 files changed, 141 insertions(+), 26 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 109e357206..04dacf67c0 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -46,10 +46,38 @@ Rectangle { root.activeView = "needsLogIn"; } else if (isLoggedIn) { root.activeView = "initialize"; - commerce.getSecurityImage(); - commerce.getKeyFilePathIfExists(); - commerce.balance(); - commerce.inventory(); + commerce.getPassphraseSetupStatus(); + } + } + + onPassphraseSetupStatusResult: { + if (!passphraseIsSetup && root.activeView !== "notSetUp") { + root.activeView = "notSetUp"; + } else if (passphraseIsSetup && root.activeView === "initialize") { + commerce.getWalletAuthenticatedStatus(); + } + } + + onWalletAuthenticatedStatusResult: { + if (!isAuthenticated && !passphraseModal.visible) { + passphraseModal.visible = true; + } else if (isAuthenticated) { + if (passphraseModal.visible) { + passphraseModal.visible = false; + } + + if (!securityImageResultReceived) { + commerce.getSecurityImage(); + } + if (!keyFilePathIfExistsResultReceived) { + commerce.getKeyFilePathIfExists(); + } + if (!balanceReceived) { + commerce.balance(); + } + if (!purchasesReceived) { + commerce.inventory(); + } } } @@ -110,10 +138,6 @@ Rectangle { } } - HifiWallet.SecurityImageModel { - id: securityImageModel; - } - // // TITLE BAR START // @@ -221,7 +245,21 @@ Rectangle { } } + PassphraseModal { + id: passphraseModal; + z: 998; + visible: false; + anchors.top: titleBarContainer.bottom; + anchors.bottom: parent.bottom; + anchors.left: parent.left; + anchors.right: parent.right; + Connections { + onSendSignalToParent: { + sendToScript(msg); + } + } + } // // "WALLET NOT SET UP" START diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index bc843a140d..f9871d1b2a 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -41,9 +41,35 @@ Rectangle { root.activeView = "needsLogIn"; } else if (isLoggedIn) { root.activeView = "initialize"; - commerce.getSecurityImage(); - commerce.getKeyFilePathIfExists(); - commerce.inventory(); + commerce.getPassphraseSetupStatus(); + } + } + + onPassphraseSetupStatusResult: { + if (!passphraseIsSetup && root.activeView !== "notSetUp") { + root.activeView = "notSetUp"; + } else if (passphraseIsSetup && root.activeView === "initialize") { + commerce.getWalletAuthenticatedStatus(); + } + } + + onWalletAuthenticatedStatusResult: { + if (!isAuthenticated && !passphraseModal.visible) { + passphraseModal.visible = true; + } else if (isAuthenticated) { + if (passphraseModal.visible) { + passphraseModal.visible = false; + } + + if (!securityImageResultReceived) { + commerce.getSecurityImage(); + } + if (!keyFilePathIfExistsResultReceived) { + commerce.getKeyFilePathIfExists(); + } + if (!purchasesReceived) { + commerce.inventory(); + } } } @@ -191,6 +217,22 @@ Rectangle { commerce.getLoginStatus(); } } + + PassphraseModal { + id: passphraseModal; + z: 998; + visible: false; + anchors.top: titleBarContainer.bottom; + anchors.bottom: parent.bottom; + anchors.left: parent.left; + anchors.right: parent.right; + + Connections { + onSendSignalToParent: { + sendToScript(msg); + } + } + } // // "WALLET NOT SET UP" START diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index 71cb61686e..5a6df37485 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -48,9 +48,9 @@ Item { onVisibleChanged: { if (visible) { passphraseField.focus = true; - sendSignalToWallet({method: 'disableHmdPreview'}); + sendSignalToParent({method: 'disableHmdPreview'}); } else { - sendSignalToWallet({method: 'maybeEnableHmdPreview'}); + sendSignalToParent({method: 'maybeEnableHmdPreview'}); } } @@ -96,9 +96,9 @@ Item { onFocusChanged: { if (focus) { - sendSignalToWallet({method: 'walletSetup_raiseKeyboard'}); + keyboard.raised = true; } else if (!passphraseFieldAgain.focus) { - sendSignalToWallet({method: 'walletSetup_lowerKeyboard'}); + keyboard.raised = false; } } @@ -106,7 +106,7 @@ Item { anchors.fill: parent; onClicked: { parent.focus = true; - sendSignalToWallet({method: 'walletSetup_raiseKeyboard'}); + keyboard.raised = true; } } @@ -206,7 +206,7 @@ Item { width: parent.width/2 - anchors.leftMargin*2; text: "Cancel" onClicked: { - sendSignalToWallet({method: 'passphrasePopup_cancelClicked'}); + sendSignalToParent({method: 'passphrasePopup_cancelClicked'}); } } @@ -228,5 +228,45 @@ Item { } } - signal sendSignalToWallet(var msg); + Item { + id: keyboardContainer; + z: 999; + visible: keyboard.raised; + property bool punctuationMode: false; + anchors { + bottom: parent.bottom; + left: parent.left; + right: parent.right; + } + + Image { + id: lowerKeyboardButton; + source: "images/lowerKeyboard.png"; + anchors.horizontalCenter: parent.horizontalCenter; + anchors.bottom: keyboard.top; + height: 30; + width: 120; + + MouseArea { + anchors.fill: parent; + + onClicked: { + root.keyboardRaised = false; + } + } + } + + HifiControlsUit.Keyboard { + id: keyboard; + raised: HMD.mounted && root.keyboardRaised; + numeric: parent.punctuationMode; + anchors { + bottom: parent.bottom; + left: parent.left; + right: parent.right; + } + } + } + + signal sendSignalToParent(var msg); } diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 04278e85a9..8858c25964 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -253,14 +253,8 @@ Rectangle { anchors.right: parent.right; Connections { - onSendSignalToWallet: { - if (msg.method === 'walletSetup_raiseKeyboard') { - root.keyboardRaised = true; - } else if (msg.method === 'walletSetup_lowerKeyboard') { - root.keyboardRaised = false; - } else { - sendToScript(msg); - } + onSendSignalToParent: { + sendToScript(msg); } } } diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 7d1aaee157..ccaa03baa8 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -231,6 +231,7 @@ case 'purchases_goToMarketplaceClicked': tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL); break; + case 'passphrasePopup_cancelClicked': case 'needsLogIn_cancelClicked': tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL); break; From 0e3fc64f63b16b02db4ae453faf5ffbe87e31f5b Mon Sep 17 00:00:00 2001 From: Menithal Date: Fri, 1 Sep 2017 00:31:59 +0300 Subject: [PATCH 13/30] Fixed Inverse logic and Cleanup --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 6 +++--- libraries/entities/src/AnimationPropertyGroup.cpp | 2 +- libraries/entities/src/ModelEntityItem.cpp | 1 - libraries/entities/src/ModelEntityItem.h | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index dbe6eaf501..dbde6fe1e4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -287,7 +287,7 @@ bool RenderableModelEntityItem::getAnimationFrame() { auto animation = getAnimation(); if (animation && animation->isLoaded()) { - + const QVector& frames = animation->getFramesReference(); // NOTE: getFrames() is too heavy auto& fbxJoints = animation->getGeometry().joints; @@ -322,10 +322,10 @@ bool RenderableModelEntityItem::getAnimationFrame() { if (index >= 0) { glm::mat4 translationMat; - if (allowTranslation){ + if (!allowTranslation){ translationMat = glm::translate(originalFbxJoints[index].translation); } - else if (!allowTranslation && index < translations.size()) { + else if (allowTranslation && index < translations.size()) { translationMat = glm::translate(translations[index]); } diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 18f56fa703..f1c5de53cf 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -206,7 +206,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, int& propertyCount, OctreeElement::AppendState& appendState) const { - bool successPropertyFits = true; + bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, getAllowTranslation()); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 07b55d419e..7237ced556 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -156,7 +156,6 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, QVector, setJointTranslationsSet); READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, QVector, setJointTranslations); - return bytesRead; } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 4dcd01b8cb..9daee95655 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -152,7 +152,7 @@ protected: bool isAnimatingSomething() const; rgbColor _color; - QString _modelURL; + QString _modelURL; QUrl _parsedModelURL; QString _compoundShapeURL; From eab2947d4055e1073c88af89941234dc92757c19 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 15:16:29 -0700 Subject: [PATCH 14/30] Auth flow --- .../qml/hifi/commerce/checkout/Checkout.qml | 69 ++++++++----------- .../qml/hifi/commerce/purchases/Purchases.qml | 58 ++++++---------- .../hifi/commerce/wallet/PassphraseModal.qml | 14 +++- .../commerce/wallet/PassphraseSelection.qml | 8 +-- .../qml/hifi/commerce/wallet/Wallet.qml | 53 +++++--------- .../commerce/wallet/WalletSetupLightbox.qml | 4 +- interface/src/commerce/QmlCommerce.cpp | 69 +++++++++---------- interface/src/commerce/QmlCommerce.h | 26 +++---- interface/src/commerce/Wallet.cpp | 18 +++++ interface/src/commerce/Wallet.h | 1 + 10 files changed, 154 insertions(+), 166 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 04dacf67c0..1a1579443c 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -29,7 +29,6 @@ Rectangle { property bool purchasesReceived: false; property bool balanceReceived: false; property bool securityImageResultReceived: false; - property bool keyFilePathIfExistsResultReceived: false; property string itemId: ""; property string itemHref: ""; property double balanceAfterPurchase: 0; @@ -46,38 +45,15 @@ Rectangle { root.activeView = "needsLogIn"; } else if (isLoggedIn) { root.activeView = "initialize"; - commerce.getPassphraseSetupStatus(); - } - } - - onPassphraseSetupStatusResult: { - if (!passphraseIsSetup && root.activeView !== "notSetUp") { - root.activeView = "notSetUp"; - } else if (passphraseIsSetup && root.activeView === "initialize") { - commerce.getWalletAuthenticatedStatus(); + commerce.getKeyFilePathIfExists(); } } - onWalletAuthenticatedStatusResult: { - if (!isAuthenticated && !passphraseModal.visible) { - passphraseModal.visible = true; - } else if (isAuthenticated) { - if (passphraseModal.visible) { - passphraseModal.visible = false; - } - - if (!securityImageResultReceived) { - commerce.getSecurityImage(); - } - if (!keyFilePathIfExistsResultReceived) { - commerce.getKeyFilePathIfExists(); - } - if (!balanceReceived) { - commerce.balance(); - } - if (!purchasesReceived) { - commerce.inventory(); - } + onKeyFilePathIfExistsResult: { + if (path === "" && root.activeView !== "notSetUp") { + root.activeView = "notSetUp"; + } else if (path !== "" && root.activeView === "initialize") { + commerce.getSecurityImage(); } } @@ -85,8 +61,9 @@ Rectangle { securityImageResultReceived = true; if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up" root.activeView = "notSetUp"; - } else if (root.securityImageResultReceived && exists && root.keyFilePathIfExistsResultReceived && root.activeView === "initialize") { + } else if (exists && root.activeView === "initialize") { root.activeView = "checkoutMain"; + commerce.getWalletAuthenticatedStatus(); } else if (exists) { // just set the source again (to be sure the change was noticed) securityImage.source = ""; @@ -94,12 +71,16 @@ Rectangle { } } - onKeyFilePathIfExistsResult: { - keyFilePathIfExistsResultReceived = true; - if (path === "" && root.activeView !== "notSetUp") { - root.activeView = "notSetUp"; - } else if (root.securityImageResultReceived && root.keyFilePathIfExistsResultReceived && path !== "" && root.activeView === "initialize") { - root.activeView = "checkoutMain"; + onWalletAuthenticatedStatusResult: { + if (!isAuthenticated && !passphraseModal.visible) { + passphraseModal.visible = true; + } else if (isAuthenticated) { + if (!balanceReceived) { + commerce.balance(); + } + if (!purchasesReceived) { + commerce.inventory(); + } } } @@ -219,7 +200,6 @@ Rectangle { securityImageResultReceived = false; purchasesReceived = false; balanceReceived = false; - keyFilePathIfExistsResultReceived = false; commerce.getLoginStatus(); } } @@ -245,7 +225,7 @@ Rectangle { } } - PassphraseModal { + HifiWallet.PassphraseModal { id: passphraseModal; z: 998; visible: false; @@ -256,7 +236,16 @@ Rectangle { Connections { onSendSignalToParent: { - sendToScript(msg); + if (msg.method === 'passphraseModal_authSuccess') { + if (!balanceReceived) { + commerce.balance(); + } + if (!purchasesReceived) { + commerce.inventory(); + } + } else { + sendToScript(msg); + } } } } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index f9871d1b2a..a3a09f6452 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -28,7 +28,6 @@ Rectangle { property string activeView: "initialize"; property string referrerURL: ""; property bool securityImageResultReceived: false; - property bool keyFilePathIfExistsResultReceived: false; property bool purchasesReceived: false; property bool punctuationMode: false; // Style @@ -41,35 +40,15 @@ Rectangle { root.activeView = "needsLogIn"; } else if (isLoggedIn) { root.activeView = "initialize"; - commerce.getPassphraseSetupStatus(); - } - } - - onPassphraseSetupStatusResult: { - if (!passphraseIsSetup && root.activeView !== "notSetUp") { - root.activeView = "notSetUp"; - } else if (passphraseIsSetup && root.activeView === "initialize") { - commerce.getWalletAuthenticatedStatus(); + commerce.getKeyFilePathIfExists(); } } - onWalletAuthenticatedStatusResult: { - if (!isAuthenticated && !passphraseModal.visible) { - passphraseModal.visible = true; - } else if (isAuthenticated) { - if (passphraseModal.visible) { - passphraseModal.visible = false; - } - - if (!securityImageResultReceived) { - commerce.getSecurityImage(); - } - if (!keyFilePathIfExistsResultReceived) { - commerce.getKeyFilePathIfExists(); - } - if (!purchasesReceived) { - commerce.inventory(); - } + onKeyFilePathIfExistsResult: { + if (path === "" && root.activeView !== "notSetUp") { + root.activeView = "notSetUp"; + } else if (path !== "" && root.activeView === "initialize") { + commerce.getSecurityImage(); } } @@ -77,8 +56,9 @@ Rectangle { securityImageResultReceived = true; if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up" root.activeView = "notSetUp"; - } else if (root.securityImageResultReceived && exists && root.keyFilePathIfExistsResultReceived && root.activeView === "initialize") { + } else if (exists && root.activeView === "initialize") { root.activeView = "purchasesMain"; + commerce.getWalletAuthenticatedStatus(); } else if (exists) { // just set the source again (to be sure the change was noticed) securityImage.source = ""; @@ -86,12 +66,11 @@ Rectangle { } } - onKeyFilePathIfExistsResult: { - keyFilePathIfExistsResultReceived = true; - if (path === "" && root.activeView !== "notSetUp") { - root.activeView = "notSetUp"; - } else if (root.securityImageResultReceived && root.keyFilePathIfExistsResultReceived && path !== "" && root.activeView === "initialize") { - root.activeView = "purchasesMain"; + onWalletAuthenticatedStatusResult: { + if (!isAuthenticated && !passphraseModal.visible) { + passphraseModal.visible = true; + } else if (isAuthenticated) { + commerce.inventory(); } } @@ -192,7 +171,6 @@ Rectangle { Component.onCompleted: { securityImageResultReceived = false; purchasesReceived = false; - keyFilePathIfExistsResultReceived = false; commerce.getLoginStatus(); } } @@ -218,7 +196,7 @@ Rectangle { } } - PassphraseModal { + HifiWallet.PassphraseModal { id: passphraseModal; z: 998; visible: false; @@ -229,7 +207,13 @@ Rectangle { Connections { onSendSignalToParent: { - sendToScript(msg); + if (msg.method === 'passphraseModal_authSuccess') { + if (!purchasesReceived) { + commerce.inventory(); + } + } else { + sendToScript(msg); + } } } } diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index 5a6df37485..f9b2c88a5b 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -31,6 +31,17 @@ Item { passphraseModalSecurityImage.source = ""; passphraseModalSecurityImage.source = "image://security/securityImage"; } + + onWalletAuthenticatedStatusResult: { + submitPassphraseInputButton.enabled = true; + if (!isAuthenticated) { + // Auth failed, show error text + + } else { + root.visible = false; + sendSignalToParent({method: 'passphraseModal_authSuccess'}); + } + } } // This object is always used in a popup. @@ -222,7 +233,8 @@ Item { width: parent.width/2 - anchors.rightMargin*2; text: "Submit" onClicked: { - //commerce.submitWalletPassphrase(passphraseField.text); + submitPassphraseInputButton.enabled = false; + commerce.setPassphrase(passphraseField.text); } } } diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml index 2bad454b63..7dca5a75b8 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml @@ -40,8 +40,8 @@ Item { passphrasePageSecurityImage.source = "image://security/securityImage"; } - onPassphraseSetupStatusResult: { - sendMessageToLightbox({method: 'statusResult', status: passphraseIsSetup}); + onWalletAuthenticatedStatusResult: { + sendMessageToLightbox({method: 'statusResult', status: isAuthenticated}); } } @@ -195,7 +195,7 @@ Item { // Text below TextFields RalewaySemiBold { id: passwordReqs; - text: "Passphrase must be at least 4 characters"; + text: "Passphrase must be at least 3 characters"; // Text size size: 16; // Anchors @@ -252,7 +252,7 @@ Item { } function validateAndSubmitPassphrase() { - if (passphraseField.text.length < 4) { + if (passphraseField.text.length < 3) { setErrorText("Passphrase too short."); return false; } else if (passphraseField.text !== passphraseFieldAgain.text) { diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 8858c25964..f672530d1f 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -26,8 +26,6 @@ Rectangle { id: root; property string activeView: "initialize"; - property bool securityImageResultReceived: false; - property bool keyFilePathIfExistsResultReceived: false; property bool keyboardRaised: false; // Style @@ -40,14 +38,22 @@ Rectangle { root.activeView = "needsLogIn"; } else if (isLoggedIn) { root.activeView = "initialize"; - commerce.getPassphraseSetupStatus(); + commerce.getKeyFilePathIfExists(); } } - - onPassphraseSetupStatusResult: { - if (!passphraseIsSetup && root.activeView !== "notSetUp") { + + onKeyFilePathIfExistsResult: { + if (path === "" && root.activeView !== "notSetUp") { root.activeView = "notSetUp"; - } else if (passphraseIsSetup && root.activeView === "initialize") { + } else if (path !== "" && root.activeView === "initialize") { + commerce.getSecurityImage(); + } + } + + onSecurityImageResult: { + if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up" + root.activeView = "notSetUp"; + } else if (exists && root.activeView === "initialize") { commerce.getWalletAuthenticatedStatus(); } } @@ -56,33 +62,6 @@ Rectangle { if (!isAuthenticated && !passphraseModal.visible) { passphraseModal.visible = true; } else if (isAuthenticated) { - if (passphraseModal.visible) { - passphraseModal.visible = false; - } - - if (!securityImageResultReceived) { - commerce.getSecurityImage(); - } - if (!keyFilePathIfExistsResultReceived) { - commerce.getKeyFilePathIfExists(); - } - } - } - - onSecurityImageResult: { - securityImageResultReceived = true; - if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up" - root.activeView = "notSetUp"; - } else if (root.securityImageResultReceived && exists && root.keyFilePathIfExistsResultReceived && root.activeView === "initialize") { - root.activeView = "walletHome"; - } - } - - onKeyFilePathIfExistsResult: { - keyFilePathIfExistsResultReceived = true; - if (path === "" && root.activeView !== "notSetUp") { - root.activeView = "notSetUp"; - } else if (root.securityImageResultReceived && root.keyFilePathIfExistsResultReceived && path !== "" && root.activeView === "initialize") { root.activeView = "walletHome"; } } @@ -254,7 +233,11 @@ Rectangle { Connections { onSendSignalToParent: { - sendToScript(msg); + if (msg.method === 'passphraseModal_authSuccess') { + root.activeView = "walletHome"; + } else { + sendToScript(msg); + } } } } diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml index 4470ec7a75..982a2cf9a4 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml @@ -39,9 +39,9 @@ Rectangle { } } - onPassphraseSetupStatusResult: { + onWalletAuthenticatedStatusResult: { securityImageContainer.visible = false; - if (passphraseIsSetup) { + if (isAuthenticated) { privateKeysReadyContainer.visible = true; } else { choosePassphraseContainer.visible = true; diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index ccbc37ed13..32abb11ab0 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -29,6 +29,40 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) { connect(wallet.data(), &Wallet::keyFilePathIfExistsResult, this, &QmlCommerce::keyFilePathIfExistsResult); } +void QmlCommerce::getLoginStatus() { + emit loginStatusResult(DependencyManager::get()->isLoggedIn()); +} + +void QmlCommerce::getKeyFilePathIfExists() { + auto wallet = DependencyManager::get(); + wallet->sendKeyFilePathIfExists(); +} + +void QmlCommerce::getWalletAuthenticatedStatus() { + auto wallet = DependencyManager::get(); + emit walletAuthenticatedStatusResult(wallet->walletIsAuthenticatedWithPassphrase()); +} + +void QmlCommerce::getSecurityImage() { + auto wallet = DependencyManager::get(); + wallet->getSecurityImage(); +} + + + +void QmlCommerce::chooseSecurityImage(const QString& imageFile) { + auto wallet = DependencyManager::get(); + wallet->chooseSecurityImage(imageFile); +} + +void QmlCommerce::setPassphrase(const QString& passphrase) { + auto wallet = DependencyManager::get(); + wallet->setPassphrase(passphrase); + getWalletAuthenticatedStatus(); +} + + + void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUsername) { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); @@ -60,42 +94,7 @@ void QmlCommerce::history() { ledger->history(wallet->listPublicKeys()); } -void QmlCommerce::chooseSecurityImage(const QString& imageFile) { - auto wallet = DependencyManager::get(); - wallet->chooseSecurityImage(imageFile); -} -void QmlCommerce::getSecurityImage() { - auto wallet = DependencyManager::get(); - wallet->getSecurityImage(); -} - -void QmlCommerce::getLoginStatus() { - emit loginStatusResult(DependencyManager::get()->isLoggedIn()); -} - -void QmlCommerce::setPassphrase(const QString& passphrase) { - auto wallet = DependencyManager::get(); - wallet->setPassphrase(passphrase); - getPassphraseSetupStatus(); -} - -void QmlCommerce::getPassphraseSetupStatus() { - auto wallet = DependencyManager::get(); - // ????? WHAT DO I DO HERE - emit passphraseSetupStatusResult(wallet->getPassphraseIsCached()); -} - -void QmlCommerce::getWalletAuthenticatedStatus() { - auto wallet = DependencyManager::get(); - // ????? WHAT DO I DO HERE - emit walletAuthenticatedStatusResult(wallet->getPassphraseIsCached()); -} - -void QmlCommerce::getKeyFilePathIfExists() { - auto wallet = DependencyManager::get(); - wallet->sendKeyFilePathIfExists(); -} void QmlCommerce::reset() { auto ledger = DependencyManager::get(); diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index 5561f331f9..f66bf518f5 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -28,30 +28,32 @@ public: QmlCommerce(QQuickItem* parent = nullptr); signals: + void loginStatusResult(bool isLoggedIn); + void keyFilePathIfExistsResult(const QString& path); + void securityImageResult(bool exists); + void walletAuthenticatedStatusResult(bool isAuthenticated); + void buyResult(QJsonObject result); // Balance and Inventory are NOT properties, because QML can't change them (without risk of failure), and // because we can't scalably know of out-of-band changes (e.g., another machine interacting with the block chain). void balanceResult(QJsonObject result); void inventoryResult(QJsonObject result); - void securityImageResult(bool exists); - void loginStatusResult(bool isLoggedIn); - void passphraseSetupStatusResult(bool passphraseIsSetup); void historyResult(QJsonObject result); - void keyFilePathIfExistsResult(const QString& path); - void walletAuthenticatedStatusResult(bool isAuthenticated); protected: + Q_INVOKABLE void getLoginStatus(); + Q_INVOKABLE void getKeyFilePathIfExists(); + Q_INVOKABLE void getSecurityImage(); + Q_INVOKABLE void getWalletAuthenticatedStatus(); + + Q_INVOKABLE void chooseSecurityImage(const QString& imageFile); + Q_INVOKABLE void setPassphrase(const QString& passphrase); + Q_INVOKABLE void buy(const QString& assetId, int cost, const QString& buyerUsername = ""); Q_INVOKABLE void balance(); Q_INVOKABLE void inventory(); Q_INVOKABLE void history(); - Q_INVOKABLE void chooseSecurityImage(const QString& imageFile); - Q_INVOKABLE void getSecurityImage(); - Q_INVOKABLE void getLoginStatus(); - Q_INVOKABLE void setPassphrase(const QString& passphrase); - Q_INVOKABLE void getPassphraseSetupStatus(); - Q_INVOKABLE void getWalletAuthenticatedStatus(); - Q_INVOKABLE void getKeyFilePathIfExists(); + Q_INVOKABLE void reset(); }; diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index cfd5b6baa5..7d427bf70f 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -342,6 +342,24 @@ bool Wallet::decryptFile(const QString& inputFilePath, unsigned char** outputBuf return true; } +bool Wallet::walletIsAuthenticatedWithPassphrase() { + // try to read existing keys if they exist... + + // FIXME: initialize OpenSSL elsewhere soon + initialize(); + + auto publicKey = readPublicKey(keyFilePath().toStdString().c_str()); + + if (publicKey.size() > 0) { + if (auto key = readPrivateKey(keyFilePath().toStdString().c_str())) { + RSA_free(key); + return true; + } + } + + return false; +} + bool Wallet::createIfNeeded() { if (_publicKeys.count() > 0) return false; diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index cb0e318598..675fbc7dd8 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -40,6 +40,7 @@ public: void setPassphrase(const QString& passphrase); QString* getPassphrase() { return _passphrase; } bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); } + bool walletIsAuthenticatedWithPassphrase(); void reset(); From 6f1bb6abe28df76956db1be8e55e007f745fa3e7 Mon Sep 17 00:00:00 2001 From: Hisham Qayum Date: Thu, 31 Aug 2017 14:29:03 -0800 Subject: [PATCH 15/30] wallet icon now has white background, diff design --- .../resources/icons/tablet-icons/wallet-a.svg | 181 +---------- .../resources/icons/tablet-icons/wallet-i.svg | 290 +----------------- 2 files changed, 15 insertions(+), 456 deletions(-) diff --git a/interface/resources/icons/tablet-icons/wallet-a.svg b/interface/resources/icons/tablet-icons/wallet-a.svg index 4a0bab4b33..50ea64848f 100644 --- a/interface/resources/icons/tablet-icons/wallet-a.svg +++ b/interface/resources/icons/tablet-icons/wallet-a.svg @@ -1,180 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - HFC - + \ No newline at end of file diff --git a/interface/resources/icons/tablet-icons/wallet-i.svg b/interface/resources/icons/tablet-icons/wallet-i.svg index 2a16ecf973..4e27e41b44 100644 --- a/interface/resources/icons/tablet-icons/wallet-i.svg +++ b/interface/resources/icons/tablet-icons/wallet-i.svg @@ -1,276 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - HFC - + + + + + + + + From 2c2500875fb7e2665e8b00805c4efd1581176fd7 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 15:39:58 -0700 Subject: [PATCH 16/30] Fixes and improvements --- .../qml/hifi/commerce/checkout/Checkout.qml | 1 - .../qml/hifi/commerce/purchases/Purchases.qml | 1 - .../hifi/commerce/wallet/PassphraseModal.qml | 43 ++++++++++++++----- .../qml/hifi/commerce/wallet/Wallet.qml | 1 - 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 1a1579443c..4d019685fd 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -227,7 +227,6 @@ Rectangle { HifiWallet.PassphraseModal { id: passphraseModal; - z: 998; visible: false; anchors.top: titleBarContainer.bottom; anchors.bottom: parent.bottom; diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index a3a09f6452..71e182e023 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -198,7 +198,6 @@ Rectangle { HifiWallet.PassphraseModal { id: passphraseModal; - z: 998; visible: false; anchors.top: titleBarContainer.bottom; anchors.bottom: parent.bottom; diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index f9b2c88a5b..ae4ad63047 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -24,6 +24,9 @@ Item { HifiConstants { id: hifi; } id: root; + z: 998; + property bool keyboardRaised: false; + Hifi.QmlCommerce { id: commerce; @@ -35,8 +38,7 @@ Item { onWalletAuthenticatedStatusResult: { submitPassphraseInputButton.enabled = true; if (!isAuthenticated) { - // Auth failed, show error text - + errorText.text = "Authentication failed - please try again."; } else { root.visible = false; sendSignalToParent({method: 'passphraseModal_authSuccess'}); @@ -76,7 +78,7 @@ Item { anchors.top: parent.top; anchors.left: parent.left; anchors.right: parent.right; - height: 220; + height: 250; color: hifi.colors.baseGray; RalewaySemiBold { @@ -106,23 +108,21 @@ Item { placeholderText: "passphrase"; onFocusChanged: { - if (focus) { - keyboard.raised = true; - } else if (!passphraseFieldAgain.focus) { - keyboard.raised = false; - } + root.keyboardRaised = focus; } MouseArea { anchors.fill: parent; + onClicked: { parent.focus = true; - keyboard.raised = true; + root.keyboardRaised = true; } } onAccepted: { - //commerce.submitWalletPassphrase(passphraseField.text); + submitPassphraseInputButton.enabled = false; + commerce.setPassphrase(passphraseField.text); } } @@ -139,7 +139,7 @@ Item { onClicked: { passphraseField.echoMode = checked ? TextInput.Normal : TextInput.Password; } - } + } // Security Image Item { @@ -191,6 +191,27 @@ Item { verticalAlignment: Text.AlignVCenter; } } + + // Error text above buttons + RalewaySemiBold { + id: errorText; + text: ""; + // Text size + size: 16; + // Anchors + anchors.bottom: passphrasePopupActionButtonsContainer.top; + anchors.bottomMargin: 4; + anchors.left: parent.left; + anchors.leftMargin: 16; + anchors.right: parent.right; + anchors.rightMargin: 16; + height: 30; + // Style + color: hifi.colors.redHighlight; + // Alignment + horizontalAlignment: Text.AlignHCenter; + verticalAlignment: Text.AlignVCenter; + } // // ACTION BUTTONS START diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index f672530d1f..ad8f6531bc 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -224,7 +224,6 @@ Rectangle { PassphraseModal { id: passphraseModal; - z: 998; visible: false; anchors.top: titleBarContainer.bottom; anchors.bottom: parent.bottom; From 0a9e3e8967c90dee56fb961df7c6b36d8b134b14 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 15:42:32 -0700 Subject: [PATCH 17/30] Remove unnecessary code --- .../qml/hifi/commerce/checkout/Checkout.qml | 13 ++----------- .../qml/hifi/commerce/purchases/Purchases.qml | 10 ++-------- .../qml/hifi/commerce/wallet/PassphraseModal.qml | 1 - .../resources/qml/hifi/commerce/wallet/Wallet.qml | 6 +----- 4 files changed, 5 insertions(+), 25 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 4d019685fd..28e5b32c4d 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -62,7 +62,6 @@ Rectangle { if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up" root.activeView = "notSetUp"; } else if (exists && root.activeView === "initialize") { - root.activeView = "checkoutMain"; commerce.getWalletAuthenticatedStatus(); } else if (exists) { // just set the source again (to be sure the change was noticed) @@ -75,6 +74,7 @@ Rectangle { if (!isAuthenticated && !passphraseModal.visible) { passphraseModal.visible = true; } else if (isAuthenticated) { + root.activeView = "checkoutMain"; if (!balanceReceived) { commerce.balance(); } @@ -235,16 +235,7 @@ Rectangle { Connections { onSendSignalToParent: { - if (msg.method === 'passphraseModal_authSuccess') { - if (!balanceReceived) { - commerce.balance(); - } - if (!purchasesReceived) { - commerce.inventory(); - } - } else { - sendToScript(msg); - } + sendToScript(msg); } } } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 71e182e023..383223a49c 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -57,7 +57,6 @@ Rectangle { if (!exists && root.activeView !== "notSetUp") { // "If security image is not set up" root.activeView = "notSetUp"; } else if (exists && root.activeView === "initialize") { - root.activeView = "purchasesMain"; commerce.getWalletAuthenticatedStatus(); } else if (exists) { // just set the source again (to be sure the change was noticed) @@ -70,6 +69,7 @@ Rectangle { if (!isAuthenticated && !passphraseModal.visible) { passphraseModal.visible = true; } else if (isAuthenticated) { + root.activeView = "purchasesMain"; commerce.inventory(); } } @@ -206,13 +206,7 @@ Rectangle { Connections { onSendSignalToParent: { - if (msg.method === 'passphraseModal_authSuccess') { - if (!purchasesReceived) { - commerce.inventory(); - } - } else { - sendToScript(msg); - } + sendToScript(msg); } } } diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index ae4ad63047..519885acc9 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -41,7 +41,6 @@ Item { errorText.text = "Authentication failed - please try again."; } else { root.visible = false; - sendSignalToParent({method: 'passphraseModal_authSuccess'}); } } } diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index ad8f6531bc..5adf37ba2b 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -232,11 +232,7 @@ Rectangle { Connections { onSendSignalToParent: { - if (msg.method === 'passphraseModal_authSuccess') { - root.activeView = "walletHome"; - } else { - sendToScript(msg); - } + sendToScript(msg); } } } From fa25c434ca64065ee8efe9222f586ad4ea87ee50 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 15:50:19 -0700 Subject: [PATCH 18/30] Messages to marketplaces.js --- .../qml/hifi/commerce/wallet/PassphraseModal.qml | 2 +- scripts/system/marketplaces/marketplaces.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index 519885acc9..4157e4082f 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -4,7 +4,7 @@ // // PassphraseModal // -// Created by Zach Fox on 2017-08-18 +// Created by Zach Fox on 2017-08-31 // Copyright 2017 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index ccaa03baa8..2eaefe7565 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -197,6 +197,7 @@ // Description: // -Called when a message is received from Checkout.qml. The "message" argument is what is sent from the Checkout QML // in the format "{method, params}", like json-rpc. + var isHmdPreviewDisabled = true; function fromQml(message) { switch (message.method) { case 'checkout_setUpClicked': @@ -238,6 +239,13 @@ case 'needsLogIn_loginClicked': openLoginWindow(); break; + case 'disableHmdPreview': + isHmdPreviewDisabled = Menu.isOptionChecked("Disable Preview"); + Menu.setIsOptionChecked("Disable Preview", true); + break; + case 'maybeEnableHmdPreview': + Menu.setIsOptionChecked("Disable Preview", isHmdPreviewDisabled); + break; default: print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message)); } From 1bfc767dafc4bc967b4cb9602ce0b0e20444956a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 16:42:14 -0700 Subject: [PATCH 19/30] Quick fixes --- interface/resources/qml/hifi/commerce/wallet/Wallet.qml | 2 +- .../resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 5adf37ba2b..5695d47a68 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -93,7 +93,7 @@ Rectangle { walletSetupLightbox.visible = false; } else if (msg.method === 'walletSetup_finished') { root.activeView = "initialize"; - commerce.getPassphraseSetupStatus(); + commerce.getLoginStatus(); } else if (msg.method === 'walletSetup_raiseKeyboard') { root.keyboardRaised = true; } else if (msg.method === 'walletSetup_lowerKeyboard') { diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml index 982a2cf9a4..2c02dc78a5 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml @@ -210,7 +210,7 @@ Rectangle { onVisibleChanged: { if (visible) { - commerce.getPassphraseSetupStatus(); + commerce.getWalletAuthenticatedStatus(); } } From 1eb503f526b548705c3695cdfd4932562726cc52 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 31 Aug 2017 16:49:12 -0700 Subject: [PATCH 20/30] we are qt5.6 on mac --- interface/src/commerce/Ledger.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 0f7f533e13..7937fa4bbb 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -142,7 +142,11 @@ void Ledger::historySuccess(QNetworkReply& reply) { // turns out on my machine, toLocalTime convert to some weird timezone, yet the // systemTimeZone is correct. To avoid a strange bug with other's systems too, lets // be explicit +#ifdef Q_OS_MAC + QDateTime createdAt = QDateTime::fromTime_t(valueObject["created_at"].toInt(), Qt::UTC); +#elif QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC); +#endif QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone()); valueObject["text"] = QString("%1 sent %2 %3 %4 on %5 with message \"%6\""). arg(from, to, QString::number(valueObject["quantity"].toInt()), valueObject["asset_title"].toString(), localCreatedAt.toString(Qt::SystemLocaleShortDate), valueObject["message"].toString()); From 8fcdfa171d8a9703b930886697ba2d62a13b8c4b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 31 Aug 2017 16:47:24 -0700 Subject: [PATCH 21/30] Add debug button to clear passphrase --- .../qml/hifi/commerce/wallet/Help.qml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml index 47b3f6daf6..402209f38d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Help.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml @@ -47,11 +47,26 @@ Item { HifiControlsUit.Button { color: hifi.buttons.black; colorScheme: hifi.colorSchemes.dark; - anchors.bottom: helpText.bottom; + anchors.bottom: resetButton.top; + anchors.bottomMargin: 15; anchors.horizontalCenter: parent.horizontalCenter; height: 50; width: 250; - text: "Testing: Reset Wallet!"; + text: "DEBUG: Clear Cached Passphrase"; + onClicked: { + commerce.setPassphrase(""); + } + } + HifiControlsUit.Button { + id: resetButton; + color: hifi.buttons.red; + colorScheme: hifi.colorSchemes.dark; + anchors.bottom: helpText.bottom; + anchors.bottomMargin: 15; + anchors.horizontalCenter: parent.horizontalCenter; + height: 50; + width: 250; + text: "DEBUG: Reset Wallet!"; onClicked: { commerce.reset(); sendSignalToWallet({method: 'walletReset'}); From 451936214dab3202526a8419b0ed42e98c12a11a Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 31 Aug 2017 17:05:55 -0700 Subject: [PATCH 22/30] initial stab at changing passphrase --- interface/src/commerce/QmlCommerce.cpp | 22 ++++---- interface/src/commerce/Wallet.cpp | 76 ++++++++++++++++++++++++++ interface/src/commerce/Wallet.h | 3 +- 3 files changed, 88 insertions(+), 13 deletions(-) diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 32abb11ab0..b03da0d8b7 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -48,21 +48,11 @@ void QmlCommerce::getSecurityImage() { wallet->getSecurityImage(); } - - void QmlCommerce::chooseSecurityImage(const QString& imageFile) { auto wallet = DependencyManager::get(); wallet->chooseSecurityImage(imageFile); } -void QmlCommerce::setPassphrase(const QString& passphrase) { - auto wallet = DependencyManager::get(); - wallet->setPassphrase(passphrase); - getWalletAuthenticatedStatus(); -} - - - void QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUsername) { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); @@ -94,11 +84,19 @@ void QmlCommerce::history() { ledger->history(wallet->listPublicKeys()); } - +void QmlCommerce::setPassphrase(const QString& passphrase) { + auto wallet = DependencyManager::get(); + if (wallet->getPassphrase()) { + wallet->changePassphrase(passphrase); + } else { + wallet->setPassphrase(passphrase); + } + getWalletAuthenticatedStatus(); +} void QmlCommerce::reset() { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); ledger->reset(); wallet->reset(); -} \ No newline at end of file +} diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 7d427bf70f..1385067bd0 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -217,6 +217,55 @@ RSA* readPrivateKey(const char* filename) { return key; } +RSA* readKeys(const char* filename) { + FILE* fp; + RSA* key = NULL; + if ((fp = fopen(filename, "rt"))) { + // file opened successfully + qCDebug(commerce) << "opened key file" << filename; + if ((key = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL))) { + // now read private key + + qCDebug(commerce) << "read public key"; + + if ((key = PEM_read_RSAPrivateKey(fp, &key, passwordCallback, NULL))) { + qCDebug(commerce) << "read private key"; + + return key; + } + qCDebug(commerce) << "failed to read private key"; + } + qCDebug(commerce) << "failed to read public key"; + } else { + qCDebug(commerce) << "failed to open key file" << filename; + } + return key; +} + +bool writeKeys(const char* filename, RSA* keys) { + FILE* fp; + bool retval = false; + if ((fp = fopen(filename, "wt"))) { + if (!PEM_write_RSAPublicKey(fp, keys)) { + fclose(fp); + qCDebug(commerce) << "failed to write public key"; + return retval; + } + + if (!PEM_write_RSAPrivateKey(fp, keys, EVP_des_ede3_cbc(), NULL, 0, passwordCallback, NULL)) { + fclose(fp); + qCDebug(commerce) << "failed to write private key"; + return retval; + } + + retval = true; + qCDebug(commerce) << "wrote keys successfully"; + } else { + qCDebug(commerce) << "failed to open key file" << filename; + } + return retval; +} + static const unsigned char IVEC[16] = "IAmAnIVecYay123"; void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArray& salt) { @@ -531,3 +580,30 @@ void Wallet::reset() { keyFile.remove(); imageFile.remove(); } + +bool Wallet::changePassphrase(const QString& newPassphrase) { + RSA* keys = readKeys(keyFilePath().toStdString().c_str()); + if (keys) { + // we read successfully, so now write to a new temp file + // save old passphrase just in case + // TODO: force re-enter? + QString oldPassphrase = *_passphrase; + setPassphrase(newPassphrase); + QString tempFileName = QString("%1.%2").arg(keyFilePath(), QString("temp")); + if (writeKeys(tempFileName.toStdString().c_str(), keys)) { + // ok, now move the temp file to the correct spot + QFile(QString(keyFilePath())).remove(); + QFile(tempFileName).rename(QString(keyFilePath())); + emit passphraseSetupStatusResult(true); + return true; + } else { + qCDebug(commerce) << "couldn't write keys"; + setPassphrase(oldPassphrase); + emit passphraseSetupStatusResult(false); + return false; + } + } + qCDebug(commerce) << "couldn't read keys"; + emit passphraseSetupStatusResult(false); + return false; +} diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 675fbc7dd8..19f5f64590 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -41,13 +41,14 @@ public: QString* getPassphrase() { return _passphrase; } bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); } bool walletIsAuthenticatedWithPassphrase(); + bool changePassphrase(const QString& newPassphrase); void reset(); signals: void securityImageResult(bool exists); void keyFilePathIfExistsResult(const QString& path); - + void passphraseSetupStatusResult(bool successful); private: QStringList _publicKeys{}; QPixmap* _securityImage { nullptr }; From ff6217069b7b16f5c94ccc4c21b55e968e98012d Mon Sep 17 00:00:00 2001 From: Hisham Qayum Date: Thu, 31 Aug 2017 17:30:24 -0800 Subject: [PATCH 23/30] reverting some unneeded code changes --- interface/src/Application.cpp | 2 +- libraries/physics/src/EntityMotionState.cpp | 2 +- libraries/physics/src/PhysicsEngine.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b48ef22763..88003bb10f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -319,7 +319,7 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI static const uint32_t INVALID_FRAME = UINT32_MAX; -static const float PHYSICS_READY_RANGE = 1.0f; // how far from avatar to check for entities that aren't ready for simulation +static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check for entities that aren't ready for simulation static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 93ef140f30..f02dcee8f6 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -531,7 +531,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ } if (!_body->isStaticOrKinematicObject()) { - const float DYNAMIC_LINEAR_VELOCITY_THRESHOLD = 0.02f; // 5 cm/sec + const float DYNAMIC_LINEAR_VELOCITY_THRESHOLD = 0.05f; // 5 cm/sec const float DYNAMIC_ANGULAR_VELOCITY_THRESHOLD = 0.087266f; // ~5 deg/sec bool movingSlowlyLinear = diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 1dba0e9a07..a64796308e 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -441,7 +441,7 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() { while (contactItr != _contactMap.end()) { ContactInfo& contact = contactItr->second; ContactEventType type = contact.computeType(_numContactFrames); - const btScalar SIGNIFICANT_DEPTH = -0.008f; // penetrations have negative distance + const btScalar SIGNIFICANT_DEPTH = -0.002f; // penetrations have negative distance if (type != CONTACT_EVENT_TYPE_CONTINUE || (contact.distance < SIGNIFICANT_DEPTH && contact.readyForContinue(_numContactFrames))) { From 5506520226e65025898348b9a0198a09d91dd619 Mon Sep 17 00:00:00 2001 From: Menithal Date: Fri, 1 Sep 2017 08:20:54 +0300 Subject: [PATCH 24/30] Fixed missing semi colon --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index fa8b0befe1..22b2cffbcb 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -910,7 +910,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { const QVector& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy auto& fbxJoints = _animation->getGeometry().joints; - auto& originalFbxJoints = _model->getFBXGeometry().joints + auto& originalFbxJoints = _model->getFBXGeometry().joints; bool allowTranslation = entity->getAnimationAllowTranslation(); int frameCount = frames.size(); if (frameCount <= 0) { From 655dc61ff270f717755896b33b92674023e04fdf Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 1 Sep 2017 10:16:45 -0700 Subject: [PATCH 25/30] doh --- interface/src/commerce/Ledger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 7937fa4bbb..2055229059 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -144,7 +144,7 @@ void Ledger::historySuccess(QNetworkReply& reply) { // be explicit #ifdef Q_OS_MAC QDateTime createdAt = QDateTime::fromTime_t(valueObject["created_at"].toInt(), Qt::UTC); -#elif +#else QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC); #endif QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone()); From 51699c9a6a4662a0d7593c90472c0230c878e00e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 1 Sep 2017 11:44:46 -0700 Subject: [PATCH 26/30] Minor changes to fonts and colors --- .../qml/hifi/commerce/wallet/WalletHome.qml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index b55f7f800a..077c1ae52c 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -88,13 +88,14 @@ Item { height: 60; Rectangle { id: hfcBalanceField; + color: hifi.colors.darkGray; anchors.right: parent.right; anchors.left: parent.left; anchors.bottom: parent.bottom; height: parent.height - 15; // "HFC" balance label - RalewayRegular { + FiraSansRegular { id: balanceLabel; text: "HFC"; // Text size @@ -106,7 +107,7 @@ Item { anchors.rightMargin: 4; width: paintedWidth; // Style - color: hifi.colors.darkGray; + color: hifi.colors.lightGrayText; // Alignment horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter; @@ -121,7 +122,7 @@ Item { } // Balance Text - FiraSansRegular { + FiraSansSemiBold { id: balanceText; text: "--"; // Text size @@ -133,7 +134,7 @@ Item { anchors.right: balanceLabel.left; anchors.rightMargin: 4; // Style - color: hifi.colors.darkGray; + color: hifi.colors.lightGrayText; // Alignment horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter; @@ -258,7 +259,7 @@ Item { delegate: Item { width: parent.width; height: transactionText.height + 30; - RalewayRegular { + FiraSansRegular { id: transactionText; text: model.text; // Style @@ -288,7 +289,7 @@ Item { } // This should never be visible (since you immediately get 100 HFC) - RalewayRegular { + FiraSansRegular { id: emptyTransationHistory; size: 24; visible: !transactionHistory.visible && root.historyReceived; From 9fe6ce0337e769794a4d61c837495b2b85b9e04c Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 1 Sep 2017 13:11:56 -0700 Subject: [PATCH 27/30] working change passphrase. some cleanup to come --- .../qml/hifi/commerce/wallet/Wallet.qml | 2 +- .../commerce/wallet/WalletSetupLightbox.qml | 4 ++-- interface/src/commerce/QmlCommerce.cpp | 2 +- interface/src/commerce/Wallet.cpp | 21 +++++++++++-------- interface/src/commerce/Wallet.h | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 5adf37ba2b..f18e520ae6 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -93,7 +93,7 @@ Rectangle { walletSetupLightbox.visible = false; } else if (msg.method === 'walletSetup_finished') { root.activeView = "initialize"; - commerce.getPassphraseSetupStatus(); + commerce.getWalletAuthenticatedStatus(); } else if (msg.method === 'walletSetup_raiseKeyboard') { root.keyboardRaised = true; } else if (msg.method === 'walletSetup_lowerKeyboard') { diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml index 982a2cf9a4..2956dfb518 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetupLightbox.qml @@ -117,7 +117,7 @@ Rectangle { anchors.right: parent.right; anchors.rightMargin: 16; height: 280; - + Connections { onSendSignalToWallet: { sendSignalToWallet(msg); @@ -210,7 +210,7 @@ Rectangle { onVisibleChanged: { if (visible) { - commerce.getPassphraseSetupStatus(); + commerce.getWalletAuthenticatedStatus(); } } diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index b03da0d8b7..96f2a02f31 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -86,7 +86,7 @@ void QmlCommerce::history() { void QmlCommerce::setPassphrase(const QString& passphrase) { auto wallet = DependencyManager::get(); - if (wallet->getPassphrase()) { + if (wallet->getPassphrase() && !wallet->getPassphrase()->isEmpty()) { wallet->changePassphrase(passphrase); } else { wallet->setPassphrase(passphrase); diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 1385067bd0..58ad70a365 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -56,7 +56,7 @@ QString imageFilePath() { int passwordCallback(char* password, int maxPasswordSize, int rwFlag, void* u) { // just return a hardcoded pwd for now auto passphrase = DependencyManager::get()->getPassphrase(); - if (passphrase) { + if (passphrase && !passphrase->isEmpty()) { strcpy(password, passphrase->toLocal8Bit().constData()); return static_cast(passphrase->size()); } else { @@ -134,12 +134,14 @@ QPair generateRSAKeypair() { if ((fp = fopen(keyFilePath().toStdString().c_str(), "at"))) { if (!PEM_write_RSAPublicKey(fp, keyPair)) { fclose(fp); + QFile(keyFilePath()).remove(); qCDebug(commerce) << "failed to write public key"; return retval; } if (!PEM_write_RSAPrivateKey(fp, keyPair, EVP_des_ede3_cbc(), NULL, 0, passwordCallback, NULL)) { fclose(fp); + QFile(keyFilePath()).remove(); qCDebug(commerce) << "failed to write private key"; return retval; } @@ -202,9 +204,6 @@ RSA* readPrivateKey(const char* filename) { // file opened successfully qCDebug(commerce) << "opened key file" << filename; if ((key = PEM_read_RSAPrivateKey(fp, &key, passwordCallback, NULL))) { - // cleanup - fclose(fp); - qCDebug(commerce) << "parsed private key file successfully"; } else { @@ -230,12 +229,14 @@ RSA* readKeys(const char* filename) { if ((key = PEM_read_RSAPrivateKey(fp, &key, passwordCallback, NULL))) { qCDebug(commerce) << "read private key"; - + fclose(fp); return key; } qCDebug(commerce) << "failed to read private key"; + } else { + qCDebug(commerce) << "failed to read public key"; } - qCDebug(commerce) << "failed to read public key"; + fclose(fp); } else { qCDebug(commerce) << "failed to open key file" << filename; } @@ -249,17 +250,20 @@ bool writeKeys(const char* filename, RSA* keys) { if (!PEM_write_RSAPublicKey(fp, keys)) { fclose(fp); qCDebug(commerce) << "failed to write public key"; + QFile(QString(filename)).remove(); return retval; } if (!PEM_write_RSAPrivateKey(fp, keys, EVP_des_ede3_cbc(), NULL, 0, passwordCallback, NULL)) { fclose(fp); qCDebug(commerce) << "failed to write private key"; + QFile(QString(filename)).remove(); return retval; } retval = true; qCDebug(commerce) << "wrote keys successfully"; + fclose(fp); } else { qCDebug(commerce) << "failed to open key file" << filename; } @@ -582,6 +586,7 @@ void Wallet::reset() { } bool Wallet::changePassphrase(const QString& newPassphrase) { + qCDebug(commerce) << "changing passphrase"; RSA* keys = readKeys(keyFilePath().toStdString().c_str()); if (keys) { // we read successfully, so now write to a new temp file @@ -594,16 +599,14 @@ bool Wallet::changePassphrase(const QString& newPassphrase) { // ok, now move the temp file to the correct spot QFile(QString(keyFilePath())).remove(); QFile(tempFileName).rename(QString(keyFilePath())); - emit passphraseSetupStatusResult(true); + qCDebug(commerce) << "passphrase changed successfully"; return true; } else { qCDebug(commerce) << "couldn't write keys"; setPassphrase(oldPassphrase); - emit passphraseSetupStatusResult(false); return false; } } qCDebug(commerce) << "couldn't read keys"; - emit passphraseSetupStatusResult(false); return false; } diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 19f5f64590..3b470210de 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -48,7 +48,7 @@ public: signals: void securityImageResult(bool exists); void keyFilePathIfExistsResult(const QString& path); - void passphraseSetupStatusResult(bool successful); + private: QStringList _publicKeys{}; QPixmap* _securityImage { nullptr }; From feaa8d312022289e1aacb1ccef1eb3ea20998679 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 1 Sep 2017 14:06:43 -0700 Subject: [PATCH 28/30] Someday, a real rain will come and wash Wallet.cpp Till then, this little change will have to do. --- interface/src/commerce/Wallet.cpp | 135 +++++++++++++----------------- 1 file changed, 59 insertions(+), 76 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 58ad70a365..6caa9c9a5b 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -67,6 +67,61 @@ int passwordCallback(char* password, int maxPasswordSize, int rwFlag, void* u) { } } +RSA* readKeys(const char* filename) { + FILE* fp; + RSA* key = NULL; + if ((fp = fopen(filename, "rt"))) { + // file opened successfully + qCDebug(commerce) << "opened key file" << filename; + if ((key = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL))) { + // now read private key + + qCDebug(commerce) << "read public key"; + + if ((key = PEM_read_RSAPrivateKey(fp, &key, passwordCallback, NULL))) { + qCDebug(commerce) << "read private key"; + fclose(fp); + return key; + } + qCDebug(commerce) << "failed to read private key"; + } else { + qCDebug(commerce) << "failed to read public key"; + } + fclose(fp); + } else { + qCDebug(commerce) << "failed to open key file" << filename; + } + return key; +} + +bool writeKeys(const char* filename, RSA* keys) { + FILE* fp; + bool retval = false; + if ((fp = fopen(filename, "wt"))) { + if (!PEM_write_RSAPublicKey(fp, keys)) { + fclose(fp); + qCDebug(commerce) << "failed to write public key"; + QFile(QString(filename)).remove(); + return retval; + } + + if (!PEM_write_RSAPrivateKey(fp, keys, EVP_des_ede3_cbc(), NULL, 0, passwordCallback, NULL)) { + fclose(fp); + qCDebug(commerce) << "failed to write private key"; + QFile(QString(filename)).remove(); + return retval; + } + + retval = true; + qCDebug(commerce) << "wrote keys successfully"; + fclose(fp); + } else { + qCDebug(commerce) << "failed to open key file" << filename; + } + return retval; +} + + // BEGIN copied code - this will be removed/changed at some point soon // copied (without emits for various signals) from libraries/networking/src/RSAKeypairGenerator.cpp. // We will have a different implementation in practice, but this gives us a start for now @@ -125,27 +180,9 @@ QPair generateRSAKeypair() { } - - // now lets persist them to files - // FIXME: for now I'm appending to the file if it exists. As long as we always put - // the keys in the same order, this works fine. TODO: verify this will skip over - // anything else (like an embedded image) - FILE* fp; - if ((fp = fopen(keyFilePath().toStdString().c_str(), "at"))) { - if (!PEM_write_RSAPublicKey(fp, keyPair)) { - fclose(fp); - QFile(keyFilePath()).remove(); - qCDebug(commerce) << "failed to write public key"; - return retval; - } - - if (!PEM_write_RSAPrivateKey(fp, keyPair, EVP_des_ede3_cbc(), NULL, 0, passwordCallback, NULL)) { - fclose(fp); - QFile(keyFilePath()).remove(); - qCDebug(commerce) << "failed to write private key"; - return retval; - } - fclose(fp); + if (!writeKeys(keyFilePath().toStdString().c_str(), keyPair)) { + qCDebug(commerce) << "couldn't save keys!"; + return retval; } RSA_free(keyPair); @@ -215,61 +252,6 @@ RSA* readPrivateKey(const char* filename) { } return key; } - -RSA* readKeys(const char* filename) { - FILE* fp; - RSA* key = NULL; - if ((fp = fopen(filename, "rt"))) { - // file opened successfully - qCDebug(commerce) << "opened key file" << filename; - if ((key = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL))) { - // now read private key - - qCDebug(commerce) << "read public key"; - - if ((key = PEM_read_RSAPrivateKey(fp, &key, passwordCallback, NULL))) { - qCDebug(commerce) << "read private key"; - fclose(fp); - return key; - } - qCDebug(commerce) << "failed to read private key"; - } else { - qCDebug(commerce) << "failed to read public key"; - } - fclose(fp); - } else { - qCDebug(commerce) << "failed to open key file" << filename; - } - return key; -} - -bool writeKeys(const char* filename, RSA* keys) { - FILE* fp; - bool retval = false; - if ((fp = fopen(filename, "wt"))) { - if (!PEM_write_RSAPublicKey(fp, keys)) { - fclose(fp); - qCDebug(commerce) << "failed to write public key"; - QFile(QString(filename)).remove(); - return retval; - } - - if (!PEM_write_RSAPrivateKey(fp, keys, EVP_des_ede3_cbc(), NULL, 0, passwordCallback, NULL)) { - fclose(fp); - qCDebug(commerce) << "failed to write private key"; - QFile(QString(filename)).remove(); - return retval; - } - - retval = true; - qCDebug(commerce) << "wrote keys successfully"; - fclose(fp); - } else { - qCDebug(commerce) << "failed to open key file" << filename; - } - return retval; -} - static const unsigned char IVEC[16] = "IAmAnIVecYay123"; void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArray& salt) { @@ -603,6 +585,7 @@ bool Wallet::changePassphrase(const QString& newPassphrase) { return true; } else { qCDebug(commerce) << "couldn't write keys"; + QFile(tempFileName).remove(); setPassphrase(oldPassphrase); return false; } From 47cd47f819052becaa57680422e586912e93c395 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 1 Sep 2017 14:50:45 -0700 Subject: [PATCH 29/30] log when no passphrase was set before trying to decrypt --- interface/src/commerce/Wallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 6caa9c9a5b..1f56ae32c4 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -60,9 +60,9 @@ int passwordCallback(char* password, int maxPasswordSize, int rwFlag, void* u) { strcpy(password, passphrase->toLocal8Bit().constData()); return static_cast(passphrase->size()); } else { - // Old comment below...this should never happen once we're here...what if it does? - // ok gotta bring up modal dialog... But right now lets just - // just keep it empty + // this shouldn't happen - so lets log it to tell us we have + // a problem with the flow... + qCCritical(commerce) << "no cached passphrase while decrypting!"; return 0; } } From 0855dfc1c60c8c2ce2e3c80b7f54b11f785f2867 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 1 Sep 2017 17:26:32 -0700 Subject: [PATCH 30/30] PR-11290 didn't actually bump protocol version --- libraries/networking/src/udt/PacketHeaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index c9961cc53a..6e899c21df 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE; + return VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES; case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::JSONFilterWithFamilyTree); case PacketType::AvatarIdentity: