AssignmentClients accept an id on the command-line.

AssignmentClientMonitor now has a NodeList.  It stores its local port
in shared memory, like the DomainServer does.  As it spawns children,
it addes Nodes to the NodeList for each one.  The children send status
updates to the Monitor.  The Monitor will notice if there are no
spares and fork another child.
This commit is contained in:
Seth Alves 2015-02-19 17:44:06 -08:00
parent ac3b172dee
commit 4b3183d820
14 changed files with 389 additions and 77 deletions

View file

@ -22,6 +22,7 @@
#include <HifiConfigVariantMap.h>
#include <LogHandler.h>
#include <LogUtils.h>
#include <LimitedNodeList.h>
#include <NodeList.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
@ -40,10 +41,11 @@ SharedAssignmentPointer AssignmentClient::_currentAssignment;
int hifiSockAddrMeta = qRegisterMetaType<HifiSockAddr>("HifiSockAddr");
AssignmentClient::AssignmentClient(int &argc, char **argv) :
AssignmentClient::AssignmentClient(int &argc, char **argv, QUuid nodeUUID) :
QCoreApplication(argc, argv),
_assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME),
_localASPortSharedMem(NULL)
_localASPortSharedMem(NULL),
_localACMPortSharedMem(NULL)
{
LogUtils::init();
@ -57,6 +59,8 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
auto addressManager = DependencyManager::set<AddressManager>();
auto nodeList = DependencyManager::set<NodeList>(NodeType::Unassigned);
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
nodeList->setSessionUUID(nodeUUID);
// setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us
#ifdef _WIN32
@ -123,9 +127,8 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
// call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required
qDebug() << "Waiting for assignment -" << _requestAssignment;
QTimer* timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SLOT(sendAssignmentRequest()));
timer->start(ASSIGNMENT_REQUEST_INTERVAL_MSECS);
connect(&_requestTimer, SIGNAL(timeout()), SLOT(sendAssignmentRequest()));
_requestTimer.start(ASSIGNMENT_REQUEST_INTERVAL_MSECS);
// connect our readPendingDatagrams method to the readyRead() signal of the socket
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams);
@ -136,6 +139,36 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
// Create Singleton objects on main thread
NetworkAccessManager::getInstance();
setUpStatsToMonitor();
}
void AssignmentClient::setUpStatsToMonitor() {
// Figure out the address to send out stats to
quint16 localMonitorServerPort = DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT;
auto nodeList = DependencyManager::get<NodeList>();
nodeList->getLocalPortFromSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY,
_localACMPortSharedMem, localMonitorServerPort);
_assignmentClientMonitorSocket = HifiSockAddr(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME, localMonitorServerPort, true);
// send a stats packet every 1 seconds
connect(&_statsTimerACM, &QTimer::timeout, this, &AssignmentClient::sendStatsPacketToACM);
_statsTimerACM.start(1000);
}
void AssignmentClient::sendStatsPacketToACM() {
// tell the assignment client monitor what this assignment client is doing (if anything)
QJsonObject statsObject;
auto nodeList = DependencyManager::get<NodeList>();
if (_currentAssignment) {
statsObject["assignment_type"] = _currentAssignment->getTypeName();
} else {
statsObject["assignment_type"] = "none";
}
nodeList->sendStats(statsObject, _assignmentClientMonitorSocket);
}
void AssignmentClient::sendAssignmentRequest() {
@ -145,34 +178,22 @@ void AssignmentClient::sendAssignmentRequest() {
if (_assignmentServerHostname == "localhost") {
// we want to check again for the local domain-server port in case the DS has restarted
if (!_localASPortSharedMem) {
_localASPortSharedMem = new QSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this);
if (!_localASPortSharedMem->attach(QSharedMemory::ReadOnly)) {
qWarning() << "Could not attach to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY
<< "- will attempt to connect to domain-server on" << _assignmentServerSocket.getPort();
}
}
if (_localASPortSharedMem->isAttached()) {
_localASPortSharedMem->lock();
quint16 localAssignmentServerPort;
memcpy(&localAssignmentServerPort, _localASPortSharedMem->data(), sizeof(localAssignmentServerPort));
_localASPortSharedMem->unlock();
quint16 localAssignmentServerPort;
if (nodeList->getLocalPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, _localASPortSharedMem,
localAssignmentServerPort)) {
if (localAssignmentServerPort != _assignmentServerSocket.getPort()) {
qDebug() << "Port for local assignment server read from shared memory is"
<< localAssignmentServerPort;
<< localAssignmentServerPort;
_assignmentServerSocket.setPort(localAssignmentServerPort);
nodeList->setAssignmentServerSocket(_assignmentServerSocket);
}
}
else {
qDebug () << "- will attempt to connect to domain-server on" << _assignmentServerSocket.getPort();
}
}
nodeList->sendAssignment(_requestAssignment);
}
}
@ -227,10 +248,16 @@ void AssignmentClient::readPendingDatagrams() {
} else {
qDebug() << "Received an assignment that could not be unpacked. Re-requesting.";
}
} else if (packetTypeForPacket(receivedPacket) == PacketTypeStopNode) {
qDebug() << "Network told me to exit";
quit();
} else {
qDebug() << "punt";
// have the NodeList attempt to handle it
nodeList->processNodeData(senderSockAddr, receivedPacket);
}
} else {
qDebug() << "packetVersionAndHashMatch said no";
}
}
}

View file

@ -21,7 +21,7 @@ class QSharedMemory;
class AssignmentClient : public QCoreApplication {
Q_OBJECT
public:
AssignmentClient(int &argc, char **argv);
AssignmentClient(int &argc, char **argv, QUuid nodeUUID);
static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; }
private slots:
@ -29,13 +29,21 @@ private slots:
void readPendingDatagrams();
void assignmentCompleted();
void handleAuthenticationRequest();
void sendStatsPacketToACM();
private:
void setUpStatsToMonitor();
Assignment _requestAssignment;
static SharedAssignmentPointer _currentAssignment;
QString _assignmentServerHostname;
HifiSockAddr _assignmentServerSocket;
QSharedMemory* _localASPortSharedMem;
QSharedMemory* _localASPortSharedMem; // memory shared with domain server
QSharedMemory* _localACMPortSharedMem; // memory shared with assignment client monitor
QTimer _requestTimer; // timer for requesting and assignment
QTimer _statsTimerACM; // timer for sending stats to assignment client monitor
protected:
HifiSockAddr _assignmentClientMonitorSocket;
};
#endif // hifi_AssignmentClient_h

View file

@ -0,0 +1,84 @@
//
// AssignmentClientapp.cpp
// assignment-client/src
//
// Created by Seth Alves on 2/19/15.
// Copyright 2015 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
//
#include <QCommandLineParser>
#include <LogHandler.h>
#include <SharedUtil.h>
#include "Assignment.h"
#include "AssignmentClient.h"
#include "AssignmentClientMonitor.h"
#include "AssignmentClientApp.h"
AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
QApplication(argc, argv)
{
# ifndef WIN32
setvbuf(stdout, NULL, _IOLBF, 0);
# endif
// use the verbose message handler in Logging
qInstallMessageHandler(LogHandler::verboseMessageHandler);
// parse command-line
QCommandLineParser parser;
parser.setApplicationDescription("High Fidelity Assignment Client");
parser.addHelpOption();
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption numChildsOption("n", "number of children to fork", "child-count");
parser.addOption(numChildsOption);
const QCommandLineOption idOption("i", "assignment client id", "uuid");
parser.addOption(idOption);
if (!parser.parse(QCoreApplication::arguments())) {
qCritical() << parser.errorText() << endl;
parser.showHelp();
Q_UNREACHABLE();
}
if (parser.isSet(helpOption)) {
parser.showHelp();
Q_UNREACHABLE();
}
if (parser.isSet(numChildsOption) && parser.isSet(idOption)) {
qCritical() << "using both -i and -n doesn't make sense.";
parser.showHelp();
Q_UNREACHABLE();
}
unsigned int numForks = 0;
if (parser.isSet(numChildsOption)) {
numForks = parser.value(numChildsOption).toInt();
}
QUuid nodeUUID = QUuid::createUuid();
if (parser.isSet(idOption)) {
nodeUUID = QUuid(parser.value(idOption));
}
if (numForks) {
AssignmentClientMonitor monitor(argc, argv, numForks);
monitor.exec();
} else {
AssignmentClient client(argc, argv, nodeUUID);
client.exec();
}
}
AssignmentClientApp::~AssignmentClientApp() {
}

View file

@ -0,0 +1,19 @@
//
// AssignmentClientapp.h
// assignment-client/src
//
// Created by Seth Alves on 2/19/15.
// Copyright 2015 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
//
#include <QApplication>
class AssignmentClientApp : public QApplication {
Q_OBJECT
public:
AssignmentClientApp(int argc, char* argv[]);
~AssignmentClientApp();
};

View file

@ -14,13 +14,18 @@
#include <LogHandler.h>
#include <ShutdownEventListener.h>
#include <AddressManager.h> // XXX need this?
#include "AssignmentClientMonitor.h"
#include "PacketHeaders.h"
const char* NUM_FORKS_PARAMETER = "-n";
const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor";
AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks) :
AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, const unsigned int numAssignmentClientForks) :
QCoreApplication(argc, argv)
{
// start the Logging class with the parent's target name
@ -41,17 +46,38 @@ AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int num
// this removes both the "-n" parameter and the number of forks passed
_childArguments.removeAt(forksParameterIndex);
_childArguments.removeAt(forksParameterIndex);
// create a NodeList so we can receive stats from children
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
auto addressManager = DependencyManager::set<AddressManager>();
// auto nodeList = DependencyManager::set<NodeList>(NodeType::Unassigned);
auto nodeList = DependencyManager::set<LimitedNodeList>(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT,
DEFAULT_ASSIGNMENT_CLIENT_MONITOR_DTLS_PORT);
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClientMonitor::readPendingDatagrams);
nodeList->putLocalPortIntoSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY, this);
// use QProcess to fork off a process for each of the child assignment clients
for (int i = 0; i < numAssignmentClientForks; i++) {
for (unsigned int i = 0; i < numAssignmentClientForks; i++) {
spawnChildClient();
}
connect(&_checkSparesTimer, SIGNAL(timeout()), SLOT(checkSpares()));
_checkSparesTimer.start(5000);
}
AssignmentClientMonitor::~AssignmentClientMonitor() {
stopChildProcesses();
foreach (AssignmentClientChildData* childStatus, _childStatus) {
delete childStatus;
}
}
void AssignmentClientMonitor::stopChildProcesses() {
QList<QPointer<QProcess> >::Iterator it = _childProcesses.begin();
@ -74,11 +100,18 @@ void AssignmentClientMonitor::spawnChildClient() {
QProcess *assignmentClient = new QProcess(this);
_childProcesses.append(QPointer<QProcess>(assignmentClient));
QUuid childUUID = QUuid::createUuid();
// create a Node for this child. this is done so we can idenitfy packets from unknown children
DependencyManager::get<LimitedNodeList>()->addOrUpdateNode
(childUUID, NodeType::Unassigned, HifiSockAddr("localhost", 0), HifiSockAddr("localhost", 0), false);
// make sure that the output from the child process appears in our output
assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels);
assignmentClient->start(applicationFilePath(), _childArguments);
QStringList idArgs = QStringList() << "-i" << childUUID.toString();
assignmentClient->start(applicationFilePath(), _childArguments + idArgs);
// link the child processes' finished slot to our childProcessFinished slot
connect(assignmentClient, SIGNAL(finished(int, QProcess::ExitStatus)), this,
@ -96,3 +129,105 @@ void AssignmentClientMonitor::childProcessFinished(int exitCode, QProcess::ExitS
spawnChildClient();
}
void AssignmentClientMonitor::checkSpares() {
qDebug() << "check spares:";
QString aSpareId = "";
unsigned int spareCount = 0;
QHash<QString, AssignmentClientChildData*>::const_iterator i = _childStatus.constBegin();
while (i != _childStatus.constEnd()) {
qDebug() << " " << i.key() << i.value()->getChildType();
if (i.value()->getChildType() == "none") {
spareCount ++;
aSpareId = i.key();
}
++i;
}
qDebug() << "spare count is" << spareCount;
if (spareCount < 1) {
qDebug() << "FORK";
spawnChildClient();
}
if (spareCount > 1) {
qDebug() << "KILL";
}
}
void AssignmentClientMonitor::readPendingDatagrams() {
auto nodeList = DependencyManager::get<NodeList>();
QByteArray receivedPacket;
HifiSockAddr senderSockAddr;
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
if (nodeList->packetVersionAndHashMatch(receivedPacket)) {
if (packetTypeForPacket(receivedPacket) == PacketTypeNodeJsonStats) {
QUuid packetUUID = uuidFromPacketHeader(receivedPacket);
// qDebug() << "packetUUID = " << packetUUID;
SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket);
if (!matchingNode) {
qDebug() << "got packet from unknown child, id =" << packetUUID.toString();
// tell unknown assignment-client child to exit.
QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode);
nodeList->writeUnverifiedDatagram(diePacket, senderSockAddr);
}
if (matchingNode) {
// update our records about how to reach this child
matchingNode->setLocalSocket(senderSockAddr);
// push past the packet header
QDataStream packetStream(receivedPacket);
packetStream.skipRawData(numBytesForPacketHeader(receivedPacket));
QVariantMap unpackedVariantMap;
packetStream >> unpackedVariantMap;
QJsonObject unpackedStatsJSON = QJsonObject::fromVariantMap(unpackedVariantMap);
// qDebug() << "ACM got stats packet, id =" << packetUUID.toString()
// << "type =" << unpackedStatsJSON["assignment_type"];
QString key(QString(packetUUID.toString()));
if (_childStatus.contains(key)) {
delete _childStatus[ key ];
}
QString childType = unpackedStatsJSON["assignment_type"].toString();
auto childStatus = new AssignmentClientChildData(childType);
_childStatus[ key ] = childStatus;
}
} else {
// have the NodeList attempt to handle it
nodeList->processNodeData(senderSockAddr, receivedPacket);
}
}
}
}
AssignmentClientChildData::AssignmentClientChildData(QString childType) {
_childType = childType;
}
AssignmentClientChildData::~AssignmentClientChildData() {
}

View file

@ -20,20 +20,39 @@
extern const char* NUM_FORKS_PARAMETER;
class AssignmentClientChildData {
public:
AssignmentClientChildData(QString childType);
~AssignmentClientChildData();
QString getChildType() { return _childType; }
private:
QString _childType;
// ... timestamp
};
class AssignmentClientMonitor : public QCoreApplication {
Q_OBJECT
public:
AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks);
AssignmentClientMonitor(int &argc, char **argv, const unsigned int numAssignmentClientForks);
~AssignmentClientMonitor();
void stopChildProcesses();
private slots:
void childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void readPendingDatagrams();
void checkSpares();
private:
void spawnChildClient();
QList<QPointer<QProcess> > _childProcesses;
QStringList _childArguments;
QHash<QString, AssignmentClientChildData*> _childStatus;
QTimer _checkSparesTimer; // every few seconds see if it need fewer or more spare children
};
#endif // hifi_AssignmentClientMonitor_h

View file

@ -9,34 +9,10 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <LogHandler.h>
#include <SharedUtil.h>
#include "Assignment.h"
#include "AssignmentClient.h"
#include "AssignmentClientMonitor.h"
#include "AssignmentClientApp.h"
int main(int argc, char* argv[]) {
#ifndef WIN32
setvbuf(stdout, NULL, _IOLBF, 0);
#endif
// use the verbose message handler in Logging
qInstallMessageHandler(LogHandler::verboseMessageHandler);
const char* numForksString = getCmdOption(argc, (const char**)argv, NUM_FORKS_PARAMETER);
int numForks = 0;
if (numForksString) {
numForks = atoi(numForksString);
}
if (numForks) {
AssignmentClientMonitor monitor(argc, argv, numForks);
return monitor.exec();
} else {
AssignmentClient client(argc, argv);
return client.exec();
}
AssignmentClientApp app(argc, argv);
return 0;
}

View file

@ -244,21 +244,9 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) {
populateStaticScriptedAssignmentsFromSettings();
auto nodeList = DependencyManager::set<LimitedNodeList>(domainServerPort, domainServerDTLSPort);
// no matter the local port, save it to shared mem so that local assignment clients can ask what it is
QSharedMemory* sharedPortMem = new QSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this);
quint16 localPort = nodeList->getNodeSocket().localPort();
// attempt to create the shared memory segment
if (sharedPortMem->create(sizeof(localPort)) || sharedPortMem->attach()) {
sharedPortMem->lock();
memcpy(sharedPortMem->data(), &localPort, sizeof(localPort));
sharedPortMem->unlock();
qDebug() << "Wrote local listening port" << localPort << "to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY;
} else {
qWarning() << "Failed to create and attach to shared memory to share local port with assignment-client children.";
}
nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this);
// set our LimitedNodeList UUID to match the UUID from our config
// nodes will currently use this to add resources to data-web that relate to our domain

View file

@ -669,3 +669,41 @@ void LimitedNodeList::sendHeartbeatToIceServer(const HifiSockAddr& iceServerSock
writeUnverifiedDatagram(iceRequestByteArray, iceServerSockAddr);
}
void LimitedNodeList::putLocalPortIntoSharedMemory(const QString key, QObject* parent) {
// save our local port to shared memory so that assignment client children know how to talk to this parent
QSharedMemory* sharedPortMem = new QSharedMemory(key, parent);
quint16 localPort = getNodeSocket().localPort();
// attempt to create the shared memory segment
if (sharedPortMem->create(sizeof(localPort)) || sharedPortMem->attach()) {
sharedPortMem->lock();
memcpy(sharedPortMem->data(), &localPort, sizeof(localPort));
sharedPortMem->unlock();
qDebug() << "Wrote local listening port" << localPort << "to shared memory at key" << key;
} else {
qWarning() << "Failed to create and attach to shared memory to share local port with assignment-client children.";
}
}
bool LimitedNodeList::getLocalPortFromSharedMemory(const QString key, QSharedMemory* &sharedMem,
quint16& localPort) {
if (!sharedMem) {
sharedMem = new QSharedMemory(key, this);
if (!sharedMem->attach(QSharedMemory::ReadOnly)) {
qWarning() << "Could not attach to shared memory at key" << key;
}
}
if (sharedMem->isAttached()) {
sharedMem->lock();
memcpy(&localPort, sharedMem->data(), sizeof(localPort));
sharedMem->unlock();
return true;
}
return false;
}

View file

@ -25,6 +25,8 @@
#include <qset.h>
#include <qsharedpointer.h>
#include <QtNetwork/qudpsocket.h>
#include <QSharedMemory>
#include <QtNetwork/qhostaddress.h>
#include <tbb/concurrent_unordered_map.h>
@ -49,6 +51,11 @@ const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io";
const unsigned short STUN_SERVER_PORT = 3478;
const QString DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY = "domain-server.local-port";
const QString ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY = "assignment-client-monitor.local-port";
const char DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME[] = "localhost";
const unsigned short DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT = 40104;
const unsigned short DEFAULT_ASSIGNMENT_CLIENT_MONITOR_DTLS_PORT = 40105;
class HifiSockAddr;
@ -168,6 +175,9 @@ public:
return SharedNodePointer();
}
void putLocalPortIntoSharedMemory(const QString key, QObject* parent);
bool getLocalPortFromSharedMemory(const QString key, QSharedMemory* &sharedMem, quint16& localPort);
public slots:
void reset();

View file

@ -62,13 +62,17 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset);
}
qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) {
qint64 NodeList::sendStats(const QJsonObject& statsObject, HifiSockAddr destination) {
QByteArray statsPacket = byteArrayWithPopulatedHeader(PacketTypeNodeJsonStats);
QDataStream statsPacketStream(&statsPacket, QIODevice::Append);
statsPacketStream << statsObject.toVariantMap();
return writeUnverifiedDatagram(statsPacket, _domainHandler.getSockAddr());
return writeUnverifiedDatagram(statsPacket, destination);
}
qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) {
return sendStats(statsObject, _domainHandler.getSockAddr());
}
void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode) {

View file

@ -47,6 +47,7 @@ public:
NodeType_t getOwnerType() const { return _ownerType; }
void setOwnerType(NodeType_t ownerType) { _ownerType = ownerType; }
qint64 sendStats(const QJsonObject& statsObject, HifiSockAddr destination);
qint64 sendStatsToDomainServer(const QJsonObject& statsObject);
int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; }

View file

@ -70,6 +70,8 @@ PacketVersion versionForPacketType(PacketType type) {
return 2;
case PacketTypeOctreeStats:
return 1;
case PacketTypeStopNode:
return 1;
case PacketTypeEntityAddOrEdit:
case PacketTypeEntityData:
return VERSION_MODEL_ENTITIES_SUPPORT_SHAPE_TYPE;
@ -124,6 +126,7 @@ QString nameForPacketType(PacketType type) {
PACKET_TYPE_NAME_LOOKUP(PacketTypeEntityErase);
PACKET_TYPE_NAME_LOOKUP(PacketTypeEntityAddResponse);
PACKET_TYPE_NAME_LOOKUP(PacketTypeOctreeDataNack);
PACKET_TYPE_NAME_LOOKUP(PacketTypeStopNode);
PACKET_TYPE_NAME_LOOKUP(PacketTypeAudioEnvironment);
PACKET_TYPE_NAME_LOOKUP(PacketTypeEntityEditNack);
PACKET_TYPE_NAME_LOOKUP(PacketTypeSignedTransactionPayment);

View file

@ -67,7 +67,7 @@ enum PacketType {
PacketTypeEntityErase,
PacketTypeEntityAddResponse,
PacketTypeOctreeDataNack, // 45
UNUSED_10,
PacketTypeStopNode,
PacketTypeAudioEnvironment,
PacketTypeEntityEditNack,
PacketTypeSignedTransactionPayment,
@ -86,7 +86,7 @@ const QSet<PacketType> NON_VERIFIED_PACKETS = QSet<PacketType>()
<< PacketTypeNodeJsonStats << PacketTypeEntityQuery
<< PacketTypeOctreeDataNack << PacketTypeEntityEditNack
<< PacketTypeIceServerHeartbeat << PacketTypeIceServerHeartbeatResponse
<< PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply;
<< PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply << PacketTypeStopNode;
const int NUM_BYTES_MD5_HASH = 16;
const int NUM_STATIC_HEADER_BYTES = sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;