mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 16:23:39 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into commerce_QmlWhitelist
This commit is contained in:
commit
18d5be147c
31 changed files with 214 additions and 165 deletions
|
@ -46,8 +46,14 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
|
||||
const QCommandLineOption helpOption = parser.addHelpOption();
|
||||
|
||||
const QCommandLineOption clientTypeOption(ASSIGNMENT_TYPE_OVERRIDE_OPTION,
|
||||
"run single assignment client of given type", "type");
|
||||
QString typeDescription = "run single assignment client of given type\n# | Type\n============================";
|
||||
for (Assignment::Type type = Assignment::FirstType;
|
||||
type != Assignment::AllTypes;
|
||||
type = static_cast<Assignment::Type>(static_cast<int>(type) + 1)) {
|
||||
typeDescription.append(QStringLiteral("\n%1 | %2").arg(QString::number(type), Assignment::typeToString(type)));
|
||||
}
|
||||
const QCommandLineOption clientTypeOption(ASSIGNMENT_TYPE_OVERRIDE_OPTION, typeDescription, "type");
|
||||
|
||||
parser.addOption(clientTypeOption);
|
||||
|
||||
const QCommandLineOption poolOption(ASSIGNMENT_POOL_OPTION, "set assignment pool", "pool-name");
|
||||
|
|
|
@ -945,7 +945,7 @@ void DomainServer::createStaticAssignmentsForType(Assignment::Type type, const Q
|
|||
|
||||
void DomainServer::populateDefaultStaticAssignmentsExcludingTypes(const QSet<Assignment::Type>& excludedTypes) {
|
||||
// enumerate over all assignment types and see if we've already excluded it
|
||||
for (Assignment::Type defaultedType = Assignment::AudioMixerType;
|
||||
for (Assignment::Type defaultedType = Assignment::FirstType;
|
||||
defaultedType != Assignment::AllTypes;
|
||||
defaultedType = static_cast<Assignment::Type>(static_cast<int>(defaultedType) + 1)) {
|
||||
if (!excludedTypes.contains(defaultedType) && defaultedType != Assignment::AgentType) {
|
||||
|
|
|
@ -59,6 +59,7 @@ Rectangle {
|
|||
} else if (walletStatus === 2) {
|
||||
if (root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
UserActivityLogger.commercePassphraseEntry("marketplace checkout");
|
||||
}
|
||||
} else if (walletStatus === 3) {
|
||||
authSuccessStep();
|
||||
|
|
|
@ -54,6 +54,7 @@ Rectangle {
|
|||
} else if (walletStatus === 2) {
|
||||
if (root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
UserActivityLogger.commercePassphraseEntry("marketplace purchases");
|
||||
}
|
||||
} else if (walletStatus === 3) {
|
||||
if ((Settings.getValue("isFirstUseOfPurchases", true) || root.isDebuggingFirstUseTutorial) && root.activeView !== "firstUseTutorial") {
|
||||
|
|
|
@ -50,8 +50,10 @@ Item {
|
|||
submitPassphraseInputButton.enabled = true;
|
||||
if (!isAuthenticated) {
|
||||
errorText.text = "Authentication failed - please try again.";
|
||||
UserActivityLogger.commercePassphraseAuthenticationStatus("auth failure");
|
||||
} else {
|
||||
sendSignalToParent({method: 'authSuccess'});;
|
||||
sendSignalToParent({method: 'authSuccess'});
|
||||
UserActivityLogger.commercePassphraseAuthenticationStatus("auth success");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,6 +338,7 @@ Item {
|
|||
text: "Cancel"
|
||||
onClicked: {
|
||||
sendSignalToParent({method: 'passphrasePopup_cancelClicked'});
|
||||
UserActivityLogger.commercePassphraseAuthenticationStatus("passphrase modal cancelled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ Rectangle {
|
|||
} else if (walletStatus === 2) {
|
||||
if (root.activeView !== "passphraseModal") {
|
||||
root.activeView = "passphraseModal";
|
||||
UserActivityLogger.commercePassphraseEntry("wallet app");
|
||||
}
|
||||
} else if (walletStatus === 3) {
|
||||
if (root.activeView !== "walletSetup") {
|
||||
|
|
BIN
interface/resources/qml/js/Utils.jsc
Normal file
BIN
interface/resources/qml/js/Utils.jsc
Normal file
Binary file not shown.
|
@ -1496,6 +1496,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
});
|
||||
|
||||
connect(getEntities()->getTree().get(), &EntityTree::deletingEntity, [=](const EntityItemID& entityItemID) {
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr;
|
||||
if (myAvatar) {
|
||||
myAvatar->clearAvatarEntity(entityItemID);
|
||||
}
|
||||
});
|
||||
|
||||
// Keyboard focus handling for Web overlays.
|
||||
auto overlays = &(qApp->getOverlays());
|
||||
connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) {
|
||||
|
|
|
@ -115,6 +115,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
|||
requestedProperties += PROP_EDITION_NUMBER;
|
||||
requestedProperties += PROP_ENTITY_INSTANCE_NUMBER;
|
||||
requestedProperties += PROP_CERTIFICATE_ID;
|
||||
requestedProperties += PROP_STATIC_CERTIFICATE_VERSION;
|
||||
|
||||
requestedProperties += PROP_NAME;
|
||||
requestedProperties += PROP_HREF;
|
||||
|
@ -272,6 +273,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
|||
APPEND_ENTITY_PROPERTY(PROP_EDITION_NUMBER, getEditionNumber());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ENTITY_INSTANCE_NUMBER, getEntityInstanceNumber());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, getCertificateID());
|
||||
APPEND_ENTITY_PROPERTY(PROP_STATIC_CERTIFICATE_VERSION, getStaticCertificateVersion());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_NAME, getName());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL());
|
||||
|
@ -820,6 +822,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
READ_ENTITY_PROPERTY(PROP_EDITION_NUMBER, quint32, setEditionNumber);
|
||||
READ_ENTITY_PROPERTY(PROP_ENTITY_INSTANCE_NUMBER, quint32, setEntityInstanceNumber);
|
||||
READ_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, QString, setCertificateID);
|
||||
READ_ENTITY_PROPERTY(PROP_STATIC_CERTIFICATE_VERSION, quint32, setStaticCertificateVersion);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
|
||||
READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
|
||||
|
@ -1252,6 +1255,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(editionNumber, getEditionNumber);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(entityInstanceNumber, getEntityInstanceNumber);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(certificateID, getCertificateID);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(staticCertificateVersion, getStaticCertificateVersion);
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(name, getName);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(href, getHref);
|
||||
|
@ -1359,6 +1363,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(editionNumber, setEditionNumber);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(entityInstanceNumber, setEntityInstanceNumber);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(certificateID, setCertificateID);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(staticCertificateVersion, setStaticCertificateVersion);
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(name, setName);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(href, setHref);
|
||||
|
@ -1629,6 +1634,10 @@ void EntityItem::setParentID(const QUuid& value) {
|
|||
newParentNoBootstrapping |= Simulation::NO_BOOTSTRAPPING;
|
||||
}
|
||||
|
||||
if (!oldParentID.isNull() && (oldParentID == Physics::getSessionUUID() || oldParentID == AVATAR_SELF_ID)) {
|
||||
oldParentNoBootstrapping |= Simulation::NO_BOOTSTRAPPING;
|
||||
}
|
||||
|
||||
if ((bool)(oldParentNoBootstrapping ^ newParentNoBootstrapping)) {
|
||||
if ((bool)(newParentNoBootstrapping & Simulation::NO_BOOTSTRAPPING)) {
|
||||
markDirtyFlags(Simulation::NO_BOOTSTRAPPING);
|
||||
|
@ -2786,6 +2795,7 @@ DEFINE_PROPERTY_ACCESSOR(QString, MarketplaceID, marketplaceID)
|
|||
DEFINE_PROPERTY_ACCESSOR(quint32, EditionNumber, editionNumber)
|
||||
DEFINE_PROPERTY_ACCESSOR(quint32, EntityInstanceNumber, entityInstanceNumber)
|
||||
DEFINE_PROPERTY_ACCESSOR(QString, CertificateID, certificateID)
|
||||
DEFINE_PROPERTY_ACCESSOR(quint32, StaticCertificateVersion, staticCertificateVersion)
|
||||
|
||||
uint32_t EntityItem::getDirtyFlags() const {
|
||||
uint32_t result;
|
||||
|
|
|
@ -328,6 +328,8 @@ public:
|
|||
void setEntityInstanceNumber(const quint32&);
|
||||
QString getCertificateID() const;
|
||||
void setCertificateID(const QString& value);
|
||||
quint32 getStaticCertificateVersion() const;
|
||||
void setStaticCertificateVersion(const quint32&);
|
||||
|
||||
// TODO: get rid of users of getRadius()...
|
||||
float getRadius() const;
|
||||
|
@ -547,6 +549,7 @@ protected:
|
|||
quint32 _editionNumber { ENTITY_ITEM_DEFAULT_EDITION_NUMBER };
|
||||
quint32 _entityInstanceNumber { ENTITY_ITEM_DEFAULT_ENTITY_INSTANCE_NUMBER };
|
||||
QString _marketplaceID { ENTITY_ITEM_DEFAULT_MARKETPLACE_ID };
|
||||
quint32 _staticCertificateVersion { ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION };
|
||||
|
||||
|
||||
// NOTE: Damping is applied like this: v *= pow(1 - damping, dt)
|
||||
|
|
|
@ -324,6 +324,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_EDITION_NUMBER, editionNumber);
|
||||
CHECK_PROPERTY_CHANGE(PROP_ENTITY_INSTANCE_NUMBER, entityInstanceNumber);
|
||||
CHECK_PROPERTY_CHANGE(PROP_CERTIFICATE_ID, certificateID);
|
||||
CHECK_PROPERTY_CHANGE(PROP_STATIC_CERTIFICATE_VERSION, staticCertificateVersion);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_NAME, name);
|
||||
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode);
|
||||
|
@ -459,6 +460,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EDITION_NUMBER, editionNumber);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ENTITY_INSTANCE_NUMBER, entityInstanceNumber);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CERTIFICATE_ID, certificateID);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STATIC_CERTIFICATE_VERSION, staticCertificateVersion);
|
||||
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NAME, name);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_SOUND_URL, collisionSoundURL);
|
||||
|
@ -742,6 +744,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(editionNumber, quint32, setEditionNumber);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(entityInstanceNumber, quint32, setEntityInstanceNumber);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(certificateID, QString, setCertificateID);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(staticCertificateVersion, quint32, setStaticCertificateVersion);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL);
|
||||
|
@ -899,6 +902,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(editionNumber);
|
||||
COPY_PROPERTY_IF_CHANGED(entityInstanceNumber);
|
||||
COPY_PROPERTY_IF_CHANGED(certificateID);
|
||||
COPY_PROPERTY_IF_CHANGED(staticCertificateVersion);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(name);
|
||||
COPY_PROPERTY_IF_CHANGED(collisionSoundURL);
|
||||
|
@ -1089,6 +1093,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_PROPERTY_TO_MAP(PROP_EDITION_NUMBER, EditionNumber, editionNumber, quint32);
|
||||
ADD_PROPERTY_TO_MAP(PROP_ENTITY_INSTANCE_NUMBER, EntityInstanceNumber, entityInstanceNumber, quint32);
|
||||
ADD_PROPERTY_TO_MAP(PROP_CERTIFICATE_ID, CertificateID, certificateID, QString);
|
||||
ADD_PROPERTY_TO_MAP(PROP_STATIC_CERTIFICATE_VERSION, StaticCertificateVersion, staticCertificateVersion, quint32);
|
||||
|
||||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor);
|
||||
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float);
|
||||
|
@ -1477,6 +1482,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
APPEND_ENTITY_PROPERTY(PROP_EDITION_NUMBER, properties.getEditionNumber());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ENTITY_INSTANCE_NUMBER, properties.getEntityInstanceNumber());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, properties.getCertificateID());
|
||||
APPEND_ENTITY_PROPERTY(PROP_STATIC_CERTIFICATE_VERSION, properties.getStaticCertificateVersion());
|
||||
}
|
||||
|
||||
if (propertyCount > 0) {
|
||||
|
@ -1828,6 +1834,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EDITION_NUMBER, quint32, setEditionNumber);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ENTITY_INSTANCE_NUMBER, quint32, setEntityInstanceNumber);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CERTIFICATE_ID, QString, setCertificateID);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STATIC_CERTIFICATE_VERSION, quint32, setStaticCertificateVersion);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
@ -1995,6 +2002,7 @@ void EntityItemProperties::markAllChanged() {
|
|||
_editionNumberChanged = true;
|
||||
_entityInstanceNumberChanged = true;
|
||||
_certificateIDChanged = true;
|
||||
_staticCertificateVersionChanged = true;
|
||||
|
||||
_keyLight.markAllChanged();
|
||||
|
||||
|
@ -2337,6 +2345,9 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (certificateIDChanged()) {
|
||||
out += "certificateID";
|
||||
}
|
||||
if (staticCertificateVersionChanged()) {
|
||||
out += "staticCertificateVersion";
|
||||
}
|
||||
|
||||
if (backgroundModeChanged()) {
|
||||
out += "backgroundMode";
|
||||
|
@ -2479,6 +2490,9 @@ QByteArray EntityItemProperties::getStaticCertificateJSON() const {
|
|||
// of the entity as reviewed during the certification submission.
|
||||
|
||||
QJsonObject json;
|
||||
|
||||
quint32 staticCertificateVersion = getStaticCertificateVersion();
|
||||
|
||||
if (!getAnimation().getURL().isEmpty()) {
|
||||
json["animationURL"] = getAnimation().getURL();
|
||||
}
|
||||
|
@ -2495,7 +2509,11 @@ QByteArray EntityItemProperties::getStaticCertificateJSON() const {
|
|||
ADD_STRING_PROPERTY(marketplaceID, MarketplaceID);
|
||||
ADD_STRING_PROPERTY(modelURL, ModelURL);
|
||||
ADD_STRING_PROPERTY(script, Script);
|
||||
if (staticCertificateVersion >= 1) {
|
||||
ADD_STRING_PROPERTY(serverScripts, ServerScripts);
|
||||
}
|
||||
ADD_ENUM_PROPERTY(shapeType, ShapeType);
|
||||
ADD_INT_PROPERTY(staticCertificateVersion, StaticCertificateVersion);
|
||||
json["type"] = EntityTypes::getEntityTypeName(getType());
|
||||
|
||||
return QJsonDocument(json).toJson(QJsonDocument::Compact);
|
||||
|
|
|
@ -220,6 +220,7 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_EDITION_NUMBER, EditionNumber, editionNumber, quint32, ENTITY_ITEM_DEFAULT_EDITION_NUMBER);
|
||||
DEFINE_PROPERTY_REF(PROP_ENTITY_INSTANCE_NUMBER, EntityInstanceNumber, entityInstanceNumber, quint32, ENTITY_ITEM_DEFAULT_ENTITY_INSTANCE_NUMBER);
|
||||
DEFINE_PROPERTY_REF(PROP_CERTIFICATE_ID, CertificateID, certificateID, QString, ENTITY_ITEM_DEFAULT_CERTIFICATE_ID);
|
||||
DEFINE_PROPERTY_REF(PROP_STATIC_CERTIFICATE_VERSION, StaticCertificateVersion, staticCertificateVersion, quint32, ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION);
|
||||
|
||||
// these are used when bouncing location data into and out of scripts
|
||||
DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, glmVec3, ENTITY_ITEM_ZERO_VEC3);
|
||||
|
@ -473,6 +474,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
|||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, EditionNumber, editionNumber, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, EntityInstanceNumber, entityInstanceNumber, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CertificateID, certificateID, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, StaticCertificateVersion, staticCertificateVersion, "");
|
||||
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, HazeMode, hazeMode, "");
|
||||
|
|
|
@ -41,6 +41,7 @@ const QString ENTITY_ITEM_DEFAULT_MARKETPLACE_ID = QString("");
|
|||
const quint32 ENTITY_ITEM_DEFAULT_EDITION_NUMBER = 0;
|
||||
const quint32 ENTITY_ITEM_DEFAULT_ENTITY_INSTANCE_NUMBER = 0;
|
||||
const QString ENTITY_ITEM_DEFAULT_CERTIFICATE_ID = QString("");
|
||||
const quint32 ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION = 0;
|
||||
|
||||
const float ENTITY_ITEM_DEFAULT_ALPHA = 1.0f;
|
||||
const float ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA = 1.0f;
|
||||
|
|
|
@ -200,6 +200,7 @@ enum EntityPropertyList {
|
|||
PROP_EDITION_NUMBER,
|
||||
PROP_ENTITY_INSTANCE_NUMBER,
|
||||
PROP_CERTIFICATE_ID,
|
||||
PROP_STATIC_CERTIFICATE_VERSION,
|
||||
|
||||
PROP_HAZE_MODE,
|
||||
|
||||
|
|
|
@ -1821,6 +1821,19 @@ glm::mat4 EntityScriptingInterface::getEntityLocalTransform(const QUuid& entityI
|
|||
return result;
|
||||
}
|
||||
|
||||
QString EntityScriptingInterface::getStaticCertificateJSON(const QUuid& entityID) {
|
||||
QByteArray result;
|
||||
if (_entityTree) {
|
||||
_entityTree->withReadLock([&] {
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(entityID));
|
||||
if (entity) {
|
||||
result = entity->getProperties().getStaticCertificateJSON();
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::verifyStaticCertificateProperties(const QUuid& entityID) {
|
||||
bool result = false;
|
||||
if (_entityTree) {
|
||||
|
|
|
@ -423,6 +423,12 @@ public slots:
|
|||
*/
|
||||
Q_INVOKABLE glm::mat4 getEntityLocalTransform(const QUuid& entityID);
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Return the Static Certificate JSON for the specified {EntityID}.
|
||||
* @return {QByteArray} The Static Certificate JSON for the specified entity.
|
||||
*/
|
||||
Q_INVOKABLE QString getStaticCertificateJSON(const QUuid& entityID);
|
||||
Q_INVOKABLE bool verifyStaticCertificateProperties(const QUuid& entityID);
|
||||
|
||||
signals:
|
||||
|
|
|
@ -981,7 +981,7 @@ public:
|
|||
static QImage extractEquirectangularFace(const QImage& source, gpu::Texture::CubeFace face, int faceWidth) {
|
||||
QImage image(faceWidth, faceWidth, source.format());
|
||||
|
||||
glm::vec2 dstInvSize(1.0f / (float)source.width(), 1.0f / (float)source.height());
|
||||
glm::vec2 dstInvSize(1.0f / faceWidth);
|
||||
|
||||
struct CubeToXYZ {
|
||||
gpu::Texture::CubeFace _face;
|
||||
|
|
|
@ -127,7 +127,11 @@ void Assignment::swap(Assignment& otherAssignment) {
|
|||
}
|
||||
|
||||
const char* Assignment::getTypeName() const {
|
||||
switch (_type) {
|
||||
return typeToString(_type);
|
||||
}
|
||||
|
||||
const char* Assignment::typeToString(Assignment::Type type) {
|
||||
switch (type) {
|
||||
case Assignment::AudioMixerType:
|
||||
return "audio-mixer";
|
||||
case Assignment::AvatarMixerType:
|
||||
|
|
|
@ -28,6 +28,7 @@ class Assignment : public QObject {
|
|||
public:
|
||||
|
||||
enum Type : uint8_t {
|
||||
FirstType = 0,
|
||||
AudioMixerType = 0,
|
||||
AvatarMixerType = 1,
|
||||
AgentType = 2,
|
||||
|
@ -89,6 +90,7 @@ public:
|
|||
const QString& getNodeVersion() const { return _nodeVersion; }
|
||||
|
||||
const char* getTypeName() const;
|
||||
static const char* typeToString(Assignment::Type type);
|
||||
|
||||
friend QDebug operator<<(QDebug debug, const Assignment& assignment);
|
||||
friend QDataStream& operator<<(QDataStream &out, const Assignment& assignment);
|
||||
|
|
|
@ -141,3 +141,16 @@ void UserActivityLoggerScriptingInterface::commerceWalletSetupFinished(int times
|
|||
payload["secondsToComplete"] = secondsToComplete;
|
||||
doLogAction("commerceWalletSetupFinished", payload);
|
||||
}
|
||||
|
||||
void UserActivityLoggerScriptingInterface::commercePassphraseEntry(QString source) {
|
||||
QJsonObject payload;
|
||||
payload["source"] = source;
|
||||
doLogAction("commercePassphraseEntry", payload);
|
||||
}
|
||||
|
||||
void UserActivityLoggerScriptingInterface::commercePassphraseAuthenticationStatus(QString status) {
|
||||
QJsonObject payload;
|
||||
payload["status"] = status;
|
||||
doLogAction("commercePassphraseAuthenticationStatus", payload);
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ public:
|
|||
Q_INVOKABLE void commerceWalletSetupStarted(int timestamp, QString setupAttemptID, int setupFlowVersion, QString referrer, QString currentDomain);
|
||||
Q_INVOKABLE void commerceWalletSetupProgress(int timestamp, QString setupAttemptID, int secondsElapsed, int currentStepNumber, QString currentStepName);
|
||||
Q_INVOKABLE void commerceWalletSetupFinished(int timestamp, QString setupAttemptID, int secondsToComplete);
|
||||
Q_INVOKABLE void commercePassphraseEntry(QString source);
|
||||
Q_INVOKABLE void commercePassphraseAuthenticationStatus(QString status);
|
||||
private:
|
||||
void doLogAction(QString action, QJsonObject details = {});
|
||||
};
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include "Connection.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
|
@ -60,6 +62,15 @@ Connection::Connection(Socket* parentSocket, HifiSockAddr destination, std::uniq
|
|||
_ack2Packet = ControlPacket::create(ControlPacket::ACK2, ACK2_PAYLOAD_BYTES);
|
||||
_lossReport = ControlPacket::create(ControlPacket::NAK, NAK_PACKET_PAYLOAD_BYTES);
|
||||
_handshakeACK = ControlPacket::create(ControlPacket::HandshakeACK, HANDSHAKE_ACK_PAYLOAD_BYTES);
|
||||
|
||||
|
||||
// setup psuedo-random number generation shared by all connections
|
||||
static std::random_device rd;
|
||||
static std::mt19937 generator(rd());
|
||||
static std::uniform_int_distribution<> distribution(0, SequenceNumber::MAX);
|
||||
|
||||
// randomize the intial sequence number
|
||||
_initialSequenceNumber = SequenceNumber(distribution(generator));
|
||||
}
|
||||
|
||||
Connection::~Connection() {
|
||||
|
@ -79,11 +90,11 @@ void Connection::stopSendQueue() {
|
|||
// tell the send queue to stop and be deleted
|
||||
|
||||
sendQueue->stop();
|
||||
|
||||
_lastMessageNumber = sendQueue->getCurrentMessageNumber();
|
||||
|
||||
sendQueue->deleteLater();
|
||||
|
||||
// since we're stopping the send queue we should consider our handshake ACK not receieved
|
||||
_hasReceivedHandshakeACK = false;
|
||||
|
||||
// wait on the send queue thread so we know the send queue is gone
|
||||
sendQueueThread->quit();
|
||||
sendQueueThread->wait();
|
||||
|
@ -101,13 +112,19 @@ void Connection::setMaxBandwidth(int maxBandwidth) {
|
|||
|
||||
SendQueue& Connection::getSendQueue() {
|
||||
if (!_sendQueue) {
|
||||
|
||||
// we may have a sequence number from the previous inactive queue - re-use that so that the
|
||||
// receiver is getting the sequence numbers it expects (given that the connection must still be active)
|
||||
|
||||
// Lasily create send queue
|
||||
_sendQueue = SendQueue::create(_parentSocket, _destination);
|
||||
_lastReceivedACK = _sendQueue->getCurrentSequenceNumber();
|
||||
|
||||
if (!_hasReceivedHandshakeACK) {
|
||||
// First time creating a send queue for this connection
|
||||
_sendQueue = SendQueue::create(_parentSocket, _destination, _initialSequenceNumber - 1, _lastMessageNumber, _hasReceivedHandshakeACK);
|
||||
_lastReceivedACK = _sendQueue->getCurrentSequenceNumber();
|
||||
} else {
|
||||
// Connection already has a handshake from a previous send queue
|
||||
_sendQueue = SendQueue::create(_parentSocket, _destination, _lastReceivedACK, _lastMessageNumber, _hasReceivedHandshakeACK);
|
||||
}
|
||||
|
||||
#ifdef UDT_CONNECTION_DEBUG
|
||||
qCDebug(networking) << "Created SendQueue for connection to" << _destination;
|
||||
|
@ -142,14 +159,6 @@ void Connection::queueInactive() {
|
|||
#ifdef UDT_CONNECTION_DEBUG
|
||||
qCDebug(networking) << "Connection to" << _destination << "has stopped its SendQueue.";
|
||||
#endif
|
||||
|
||||
if (!_hasReceivedHandshake || !_isReceivingData) {
|
||||
#ifdef UDT_CONNECTION_DEBUG
|
||||
qCDebug(networking) << "Connection SendQueue to" << _destination << "stopped and no data is being received - stopping connection.";
|
||||
#endif
|
||||
|
||||
deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::queueTimeout() {
|
||||
|
@ -184,11 +193,16 @@ void Connection::queueReceivedMessagePacket(std::unique_ptr<Packet> packet) {
|
|||
|
||||
while (pendingMessage.hasAvailablePackets()) {
|
||||
auto packet = pendingMessage.removeNextPacket();
|
||||
_parentSocket->messageReceived(std::move(packet));
|
||||
}
|
||||
|
||||
if (pendingMessage.isComplete()) {
|
||||
_pendingReceivedMessages.erase(messageNumber);
|
||||
auto packetPosition = packet->getPacketPosition();
|
||||
|
||||
_parentSocket->messageReceived(std::move(packet));
|
||||
|
||||
// if this was the last or only packet, then we can remove the pending message from our hash
|
||||
if (packetPosition == Packet::PacketPosition::LAST ||
|
||||
packetPosition == Packet::PacketPosition::ONLY) {
|
||||
_pendingReceivedMessages.erase(messageNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,19 +222,6 @@ void Connection::sync() {
|
|||
&& duration_cast<seconds>(sincePacketReceive).count() >= MIN_SECONDS_BEFORE_EXPIRY ) {
|
||||
// the receive side of this connection is expired
|
||||
_isReceivingData = false;
|
||||
|
||||
// if we don't have a send queue that means the whole connection has expired and we can emit our signal
|
||||
// otherwise we'll wait for it to also timeout before cleaning up
|
||||
if (!_sendQueue) {
|
||||
|
||||
#ifdef UDT_CONNECTION_DEBUG
|
||||
qCDebug(networking) << "Connection to" << _destination << "no longer receiving any data and there is currently no send queue - stopping connection.";
|
||||
#endif
|
||||
|
||||
deactivate();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// reset the number of light ACKs or non SYN ACKs during this sync interval
|
||||
|
@ -242,26 +243,6 @@ void Connection::sync() {
|
|||
sendTimeoutNAK();
|
||||
}
|
||||
}
|
||||
} else if (!_sendQueue) {
|
||||
// we haven't received a packet and we're not sending
|
||||
// this most likely means we were started erroneously
|
||||
// check the start time for this connection and auto expire it after 5 seconds of not receiving or sending any data
|
||||
static const int CONNECTION_NOT_USED_EXPIRY_SECONDS = 5;
|
||||
auto secondsSinceStart = duration_cast<seconds>(p_high_resolution_clock::now() - _connectionStart).count();
|
||||
|
||||
if (secondsSinceStart >= CONNECTION_NOT_USED_EXPIRY_SECONDS) {
|
||||
// it's been CONNECTION_NOT_USED_EXPIRY_SECONDS and nothing has actually happened with this connection
|
||||
// consider it inactive and emit our inactivity signal
|
||||
|
||||
#ifdef UDT_CONNECTION_DEBUG
|
||||
qCDebug(networking) << "Connection to" << _destination << "did not receive or send any data in last"
|
||||
<< CONNECTION_NOT_USED_EXPIRY_SECONDS << "seconds - stopping connection.";
|
||||
#endif
|
||||
|
||||
deactivate();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,7 +425,6 @@ void Connection::sendHandshakeRequest() {
|
|||
}
|
||||
|
||||
bool Connection::processReceivedSequenceNumber(SequenceNumber sequenceNumber, int packetSize, int payloadSize) {
|
||||
|
||||
if (!_hasReceivedHandshake) {
|
||||
// Refuse to process any packets until we've received the handshake
|
||||
// Send handshake request to re-request a handshake
|
||||
|
@ -536,7 +516,7 @@ bool Connection::processReceivedSequenceNumber(SequenceNumber sequenceNumber, in
|
|||
} else {
|
||||
_stats.recordReceivedPackets(payloadSize, packetSize);
|
||||
}
|
||||
|
||||
|
||||
return !wasDuplicate;
|
||||
}
|
||||
|
||||
|
@ -827,11 +807,13 @@ void Connection::processHandshakeACK(ControlPacketPointer controlPacket) {
|
|||
SequenceNumber initialSequenceNumber;
|
||||
controlPacket->readPrimitive(&initialSequenceNumber);
|
||||
|
||||
// hand off this handshake ACK to the send queue so it knows it can start sending
|
||||
getSendQueue().handshakeACK(initialSequenceNumber);
|
||||
|
||||
// indicate that handshake ACK was received
|
||||
_hasReceivedHandshakeACK = true;
|
||||
if (initialSequenceNumber == _initialSequenceNumber) {
|
||||
// hand off this handshake ACK to the send queue so it knows it can start sending
|
||||
getSendQueue().handshakeACK();
|
||||
|
||||
// indicate that handshake ACK was received
|
||||
_hasReceivedHandshakeACK = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ class Socket;
|
|||
class PendingReceivedMessage {
|
||||
public:
|
||||
void enqueuePacket(std::unique_ptr<Packet> packet);
|
||||
bool isComplete() const { return _hasLastPacket && _numPackets == _packets.size(); }
|
||||
bool hasAvailablePackets() const;
|
||||
std::unique_ptr<Packet> removeNextPacket();
|
||||
|
||||
|
@ -72,8 +71,6 @@ public:
|
|||
void queueReceivedMessagePacket(std::unique_ptr<Packet> packet);
|
||||
|
||||
ConnectionStats::Stats sampleStats() { return _stats.sample(); }
|
||||
|
||||
bool isActive() const { return _isActive; }
|
||||
|
||||
HifiSockAddr getDestination() const { return _destination; }
|
||||
|
||||
|
@ -83,7 +80,6 @@ public:
|
|||
|
||||
signals:
|
||||
void packetSent();
|
||||
void connectionInactive(const HifiSockAddr& sockAddr);
|
||||
void receiverHandshakeRequestComplete(const HifiSockAddr& sockAddr);
|
||||
|
||||
private slots:
|
||||
|
@ -112,8 +108,6 @@ private:
|
|||
void resetReceiveState();
|
||||
void resetRTT();
|
||||
|
||||
void deactivate() { _isActive = false; emit connectionInactive(_destination); }
|
||||
|
||||
SendQueue& getSendQueue();
|
||||
SequenceNumber nextACK() const;
|
||||
void updateRTT(int rtt);
|
||||
|
@ -138,9 +132,11 @@ private:
|
|||
p_high_resolution_clock::time_point _lastReceiveTime; // holds the last time we received anything from sender
|
||||
|
||||
bool _isReceivingData { false }; // flag used for expiry of receipt portion of connection
|
||||
bool _isActive { true }; // flag used for inactivity of connection
|
||||
|
||||
SequenceNumber _initialReceiveSequenceNumber; // Randomized by peer SendQueue on creation, identifies connection during re-connect requests
|
||||
SequenceNumber _initialSequenceNumber; // Randomized on Connection creation, identifies connection during re-connect requests
|
||||
SequenceNumber _initialReceiveSequenceNumber; // Randomized by peer Connection on creation, identifies connection during re-connect requests
|
||||
|
||||
MessageNumber _lastMessageNumber { 0 };
|
||||
|
||||
LossList _lossList; // List of all missing packets
|
||||
SequenceNumber _lastReceivedSequenceNumber; // The largest sequence number received from the peer
|
||||
|
|
|
@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::EntityEdit:
|
||||
case PacketType::EntityData:
|
||||
case PacketType::EntityPhysics:
|
||||
return static_cast<PacketVersion>(EntityVersion::HazeEffect);
|
||||
return static_cast<PacketVersion>(EntityVersion::StaticCertJsonVersionOne);
|
||||
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::ConnectionIdentifier);
|
||||
|
|
|
@ -199,7 +199,8 @@ QDebug operator<<(QDebug debug, const PacketType& type);
|
|||
enum class EntityVersion : PacketVersion {
|
||||
StrokeColorProperty = 77,
|
||||
HasDynamicOwnershipTests,
|
||||
HazeEffect
|
||||
HazeEffect,
|
||||
StaticCertJsonVersionOne
|
||||
};
|
||||
|
||||
enum class EntityScriptCallMethodVersion : PacketVersion {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
using namespace udt;
|
||||
|
||||
PacketQueue::PacketQueue() {
|
||||
PacketQueue::PacketQueue(MessageNumber messageNumber) : _currentMessageNumber(messageNumber) {
|
||||
_channels.emplace_back(new std::list<PacketPointer>());
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class PacketQueue {
|
|||
using Channels = std::vector<Channel>;
|
||||
|
||||
public:
|
||||
PacketQueue();
|
||||
PacketQueue(MessageNumber messageNumber = 0);
|
||||
void queuePacket(PacketPointer packet);
|
||||
void queuePacketList(PacketListPointer packetList);
|
||||
|
||||
|
@ -42,6 +42,8 @@ public:
|
|||
PacketPointer takePacket();
|
||||
|
||||
Mutex& getLock() { return _packetsLock; }
|
||||
|
||||
MessageNumber getCurrentMessageNumber() const { return _currentMessageNumber; }
|
||||
|
||||
private:
|
||||
MessageNumber getNextMessageNumber();
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "SendQueue.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
@ -62,10 +61,12 @@ private:
|
|||
Mutex2& _mutex2;
|
||||
};
|
||||
|
||||
std::unique_ptr<SendQueue> SendQueue::create(Socket* socket, HifiSockAddr destination) {
|
||||
std::unique_ptr<SendQueue> SendQueue::create(Socket* socket, HifiSockAddr destination, SequenceNumber currentSequenceNumber,
|
||||
MessageNumber currentMessageNumber, bool hasReceivedHandshakeACK) {
|
||||
Q_ASSERT_X(socket, "SendQueue::create", "Must be called with a valid Socket*");
|
||||
|
||||
auto queue = std::unique_ptr<SendQueue>(new SendQueue(socket, destination));
|
||||
auto queue = std::unique_ptr<SendQueue>(new SendQueue(socket, destination, currentSequenceNumber,
|
||||
currentMessageNumber, hasReceivedHandshakeACK));
|
||||
|
||||
// Setup queue private thread
|
||||
QThread* thread = new QThread;
|
||||
|
@ -84,25 +85,18 @@ std::unique_ptr<SendQueue> SendQueue::create(Socket* socket, HifiSockAddr destin
|
|||
return queue;
|
||||
}
|
||||
|
||||
SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) :
|
||||
SendQueue::SendQueue(Socket* socket, HifiSockAddr dest, SequenceNumber currentSequenceNumber,
|
||||
MessageNumber currentMessageNumber, bool hasReceivedHandshakeACK) :
|
||||
_packets(currentMessageNumber),
|
||||
_socket(socket),
|
||||
_destination(dest)
|
||||
{
|
||||
// setup psuedo-random number generation for all instances of SendQueue
|
||||
static std::random_device rd;
|
||||
static std::mt19937 generator(rd());
|
||||
static std::uniform_int_distribution<> distribution(0, SequenceNumber::MAX);
|
||||
|
||||
// randomize the intial sequence number
|
||||
_initialSequenceNumber = SequenceNumber(distribution(generator));
|
||||
|
||||
// set our member variables from randomized initial number
|
||||
_currentSequenceNumber = _initialSequenceNumber - 1;
|
||||
// set our member variables from current sequence number
|
||||
_currentSequenceNumber = currentSequenceNumber;
|
||||
_atomicCurrentSequenceNumber = uint32_t(_currentSequenceNumber);
|
||||
_lastACKSequenceNumber = uint32_t(_currentSequenceNumber) - 1;
|
||||
_lastACKSequenceNumber = uint32_t(_currentSequenceNumber);
|
||||
|
||||
// default the last receiver response to the current time
|
||||
_lastReceiverResponse = QDateTime::currentMSecsSinceEpoch();
|
||||
_hasReceivedHandshakeACK = hasReceivedHandshakeACK;
|
||||
}
|
||||
|
||||
SendQueue::~SendQueue() {
|
||||
|
@ -114,8 +108,8 @@ void SendQueue::queuePacket(std::unique_ptr<Packet> packet) {
|
|||
// call notify_one on the condition_variable_any in case the send thread is sleeping waiting for packets
|
||||
_emptyCondition.notify_one();
|
||||
|
||||
if (!this->thread()->isRunning() && _state == State::NotStarted) {
|
||||
this->thread()->start();
|
||||
if (!thread()->isRunning() && _state == State::NotStarted) {
|
||||
thread()->start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,8 +119,8 @@ void SendQueue::queuePacketList(std::unique_ptr<PacketList> packetList) {
|
|||
// call notify_one on the condition_variable_any in case the send thread is sleeping waiting for packets
|
||||
_emptyCondition.notify_one();
|
||||
|
||||
if (!this->thread()->isRunning() && _state == State::NotStarted) {
|
||||
this->thread()->start();
|
||||
if (!thread()->isRunning() && _state == State::NotStarted) {
|
||||
thread()->start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,9 +138,6 @@ int SendQueue::sendPacket(const Packet& packet) {
|
|||
}
|
||||
|
||||
void SendQueue::ack(SequenceNumber ack) {
|
||||
// this is a response from the client, re-set our timeout expiry and our last response time
|
||||
_lastReceiverResponse = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
if (_lastACKSequenceNumber == (uint32_t) ack) {
|
||||
return;
|
||||
}
|
||||
|
@ -173,10 +164,7 @@ void SendQueue::ack(SequenceNumber ack) {
|
|||
_emptyCondition.notify_one();
|
||||
}
|
||||
|
||||
void SendQueue::nak(SequenceNumber start, SequenceNumber end) {
|
||||
// this is a response from the client, re-set our timeout expiry
|
||||
_lastReceiverResponse = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
void SendQueue::nak(SequenceNumber start, SequenceNumber end) {
|
||||
{
|
||||
std::lock_guard<std::mutex> nakLocker(_naksLock);
|
||||
_naks.insert(start, end);
|
||||
|
@ -197,9 +185,6 @@ void SendQueue::fastRetransmit(udt::SequenceNumber ack) {
|
|||
}
|
||||
|
||||
void SendQueue::overrideNAKListFromPacket(ControlPacket& packet) {
|
||||
// this is a response from the client, re-set our timeout expiry
|
||||
_lastReceiverResponse = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> nakLocker(_naksLock);
|
||||
_naks.clear();
|
||||
|
@ -225,8 +210,11 @@ void SendQueue::sendHandshake() {
|
|||
std::unique_lock<std::mutex> handshakeLock { _handshakeMutex };
|
||||
if (!_hasReceivedHandshakeACK) {
|
||||
// we haven't received a handshake ACK from the client, send another now
|
||||
// if the handshake hasn't been completed, then the initial sequence number
|
||||
// should be the current sequence number + 1
|
||||
SequenceNumber initialSequenceNumber = _currentSequenceNumber + 1;
|
||||
auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, sizeof(SequenceNumber));
|
||||
handshakePacket->writePrimitive(_initialSequenceNumber);
|
||||
handshakePacket->writePrimitive(initialSequenceNumber);
|
||||
_socket->writeBasePacket(*handshakePacket, _destination);
|
||||
|
||||
// we wait for the ACK or the re-send interval to expire
|
||||
|
@ -235,18 +223,14 @@ void SendQueue::sendHandshake() {
|
|||
}
|
||||
}
|
||||
|
||||
void SendQueue::handshakeACK(SequenceNumber initialSequenceNumber) {
|
||||
if (initialSequenceNumber == _initialSequenceNumber) {
|
||||
{
|
||||
std::lock_guard<std::mutex> locker { _handshakeMutex };
|
||||
_hasReceivedHandshakeACK = true;
|
||||
}
|
||||
|
||||
_lastReceiverResponse = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
// Notify on the handshake ACK condition
|
||||
_handshakeACKCondition.notify_one();
|
||||
void SendQueue::handshakeACK() {
|
||||
{
|
||||
std::lock_guard<std::mutex> locker { _handshakeMutex };
|
||||
_hasReceivedHandshakeACK = true;
|
||||
}
|
||||
|
||||
// Notify on the handshake ACK condition
|
||||
_handshakeACKCondition.notify_one();
|
||||
}
|
||||
|
||||
SequenceNumber SendQueue::getNextSequenceNumber() {
|
||||
|
@ -540,28 +524,6 @@ bool SendQueue::maybeResendPacket() {
|
|||
bool SendQueue::isInactive(bool attemptedToSendPacket) {
|
||||
// check for connection timeout first
|
||||
|
||||
// that will be the case if we have had 16 timeouts since hearing back from the client, and it has been
|
||||
// at least 5 seconds
|
||||
static const int NUM_TIMEOUTS_BEFORE_INACTIVE = 16;
|
||||
static const int MIN_MS_BEFORE_INACTIVE = 5 * 1000;
|
||||
|
||||
auto sinceLastResponse = (QDateTime::currentMSecsSinceEpoch() - _lastReceiverResponse);
|
||||
|
||||
if (sinceLastResponse > 0 &&
|
||||
sinceLastResponse >= int64_t(NUM_TIMEOUTS_BEFORE_INACTIVE * (_estimatedTimeout / USECS_PER_MSEC)) &&
|
||||
sinceLastResponse > MIN_MS_BEFORE_INACTIVE) {
|
||||
// If the flow window has been full for over CONSIDER_INACTIVE_AFTER,
|
||||
// then signal the queue is inactive and return so it can be cleaned up
|
||||
|
||||
#ifdef UDT_CONNECTION_DEBUG
|
||||
qCDebug(networking) << "SendQueue to" << _destination << "reached" << NUM_TIMEOUTS_BEFORE_INACTIVE << "timeouts"
|
||||
<< "and" << MIN_MS_BEFORE_INACTIVE << "milliseconds before receiving any ACK/NAK and is now inactive. Stopping.";
|
||||
#endif
|
||||
|
||||
deactivate();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!attemptedToSendPacket) {
|
||||
// During our processing above we didn't send any packets
|
||||
|
||||
|
|
|
@ -50,7 +50,9 @@ public:
|
|||
Stopped
|
||||
};
|
||||
|
||||
static std::unique_ptr<SendQueue> create(Socket* socket, HifiSockAddr destination);
|
||||
static std::unique_ptr<SendQueue> create(Socket* socket, HifiSockAddr destination,
|
||||
SequenceNumber currentSequenceNumber, MessageNumber currentMessageNumber,
|
||||
bool hasReceivedHandshakeACK);
|
||||
|
||||
virtual ~SendQueue();
|
||||
|
||||
|
@ -58,6 +60,7 @@ public:
|
|||
void queuePacketList(std::unique_ptr<PacketList> packetList);
|
||||
|
||||
SequenceNumber getCurrentSequenceNumber() const { return SequenceNumber(_atomicCurrentSequenceNumber); }
|
||||
MessageNumber getCurrentMessageNumber() const { return _packets.getCurrentMessageNumber(); }
|
||||
|
||||
void setFlowWindowSize(int flowWindowSize) { _flowWindowSize = flowWindowSize; }
|
||||
|
||||
|
@ -76,7 +79,7 @@ public slots:
|
|||
void nak(SequenceNumber start, SequenceNumber end);
|
||||
void fastRetransmit(SequenceNumber ack);
|
||||
void overrideNAKListFromPacket(ControlPacket& packet);
|
||||
void handshakeACK(SequenceNumber initialSequenceNumber);
|
||||
void handshakeACK();
|
||||
|
||||
signals:
|
||||
void packetSent(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint);
|
||||
|
@ -91,7 +94,8 @@ private slots:
|
|||
void run();
|
||||
|
||||
private:
|
||||
SendQueue(Socket* socket, HifiSockAddr dest);
|
||||
SendQueue(Socket* socket, HifiSockAddr dest, SequenceNumber currentSequenceNumber,
|
||||
MessageNumber currentMessageNumber, bool hasReceivedHandshakeACK);
|
||||
SendQueue(SendQueue& other) = delete;
|
||||
SendQueue(SendQueue&& other) = delete;
|
||||
|
||||
|
@ -115,8 +119,6 @@ private:
|
|||
|
||||
Socket* _socket { nullptr }; // Socket to send packet on
|
||||
HifiSockAddr _destination; // Destination addr
|
||||
|
||||
SequenceNumber _initialSequenceNumber; // Randomized on SendQueue creation, identifies connection during re-connect requests
|
||||
|
||||
std::atomic<uint32_t> _lastACKSequenceNumber { 0 }; // Last ACKed sequence number
|
||||
|
||||
|
@ -128,7 +130,6 @@ private:
|
|||
|
||||
std::atomic<int> _estimatedTimeout { 0 }; // Estimated timeout, set from CC
|
||||
std::atomic<int> _syncInterval { udt::DEFAULT_SYN_INTERVAL_USECS }; // Sync interval, set from CC
|
||||
std::atomic<int64_t> _lastReceiverResponse { 0 }; // Timestamp for the last time we got new data from the receiver (ACK/NAK)
|
||||
|
||||
std::atomic<int> _flowWindowSize { 0 }; // Flow control window size (number of packets that can be on wire) - set from CC
|
||||
|
||||
|
|
|
@ -257,9 +257,6 @@ Connection* Socket::findOrCreateConnection(const HifiSockAddr& sockAddr) {
|
|||
congestionControl->setMaxBandwidth(_maxBandwidth);
|
||||
auto connection = std::unique_ptr<Connection>(new Connection(this, sockAddr, std::move(congestionControl)));
|
||||
|
||||
// we queue the connection to cleanup connection in case it asks for it during its own rate control sync
|
||||
QObject::connect(connection.get(), &Connection::connectionInactive, this, &Socket::cleanupConnection);
|
||||
|
||||
// allow higher-level classes to find out when connections have completed a handshake
|
||||
QObject::connect(connection.get(), &Connection::receiverHandshakeRequestComplete,
|
||||
this, &Socket::clientHandshakeRequestComplete);
|
||||
|
|
|
@ -199,7 +199,7 @@
|
|||
var purchasesElement = document.createElement('a');
|
||||
var dropDownElement = document.getElementById('user-dropdown');
|
||||
|
||||
$('#user-dropdown').find('.username')[0].style = "max-width:80px;white-space:nowrap;overflow:hidden;" +
|
||||
$('#user-dropdown').find('.username')[0].style = "max-width:80px;white-space:nowrap;overflow:hidden;" +
|
||||
"text-overflow:ellipsis;display:inline-block;position:relative;top:4px;";
|
||||
$('#user-dropdown').find('.caret')[0].style = "position:relative;top:-3px;";
|
||||
|
||||
|
@ -389,27 +389,40 @@
|
|||
|
||||
var href = purchaseButton.attr('href');
|
||||
purchaseButton.attr('href', '#');
|
||||
purchaseButton.css({
|
||||
"background": "linear-gradient(#00b4ef, #0093C5)",
|
||||
"color": "#FFF",
|
||||
"font-weight": "600",
|
||||
"padding-bottom": "10px"
|
||||
});
|
||||
var availability = $.trim($('.item-availability').text());
|
||||
if (availability === 'available') {
|
||||
purchaseButton.css({
|
||||
"background": "linear-gradient(#00b4ef, #0093C5)",
|
||||
"color": "#FFF",
|
||||
"font-weight": "600",
|
||||
"padding-bottom": "10px"
|
||||
});
|
||||
} else {
|
||||
purchaseButton.css({
|
||||
"background": "linear-gradient(#a2a2a2, #fefefe)",
|
||||
"color": "#000",
|
||||
"font-weight": "600",
|
||||
"padding-bottom": "10px"
|
||||
});
|
||||
}
|
||||
|
||||
var cost = $('.item-cost').text();
|
||||
|
||||
if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
||||
if (availability !== 'available') {
|
||||
purchaseButton.html('UNAVAILABLE (' + availability + ')');
|
||||
} else if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
||||
purchaseButton.html('PURCHASE <span class="hifi-glyph hifi-glyph-hfc" style="filter:invert(1);background-size:20px;' +
|
||||
'width:20px;height:20px;position:relative;top:5px;"></span> ' + cost);
|
||||
}
|
||||
|
||||
purchaseButton.on('click', function () {
|
||||
buyButtonClicked(window.location.pathname.split("/")[3],
|
||||
$('#top-center').find('h1').text(),
|
||||
$('#creator').find('.value').text(),
|
||||
cost,
|
||||
href);
|
||||
});
|
||||
if ('availabile' === availability) {
|
||||
buyButtonClicked(window.location.pathname.split("/")[3],
|
||||
$('#top-center').find('h1').text(),
|
||||
$('#creator').find('.value').text(),
|
||||
cost,
|
||||
href);
|
||||
}
|
||||
});
|
||||
maybeAddPurchasesButton();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue