Merge branch 'master' of https://github.com/worklist/hifi into bug_fixes

This commit is contained in:
ZappoMan 2013-07-15 17:58:45 -07:00
commit e4b7ba7428
11 changed files with 198 additions and 81 deletions

View file

@ -697,8 +697,7 @@ int main(int argc, const char * argv[])
::wantLocalDomain = cmdOptionExists(argc, argv,local);
if (::wantLocalDomain) {
printf("Local Domain MODE!\n");
int ip = getLocalAddress();
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
nodeList->setDomainIPToLocalhost();
}
nodeList->linkedDataCreateCallback = NULL; // do we need a callback?

View file

@ -70,16 +70,15 @@ bool wantLocalDomain = false;
int main(int argc, const char* argv[]) {
setvbuf(stdout, NULL, _IOLBF, 0);
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT);
// Handle Local Domain testing with the --local command line
const char* local = "--local";
::wantLocalDomain = cmdOptionExists(argc, argv,local);
if (::wantLocalDomain) {
printf("Local Domain MODE!\n");
int ip = getLocalAddress();
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
}
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT);
nodeList->setDomainIPToLocalhost();
}
ssize_t receivedBytes = 0;

View file

@ -60,8 +60,7 @@ int main(int argc, const char* argv[]) {
const char* local = "--local";
if (cmdOptionExists(argc, argv, local)) {
printf("Local Domain MODE!\n");
int ip = getLocalAddress();
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
nodeList->setDomainIPToLocalhost();
}
nodeList->linkedDataCreateCallback = attachAvatarDataToNode;

View file

@ -227,14 +227,14 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
const char* domainIP = getCmdOption(argc, constArgv, "--domain");
if (domainIP) {
strcpy(DOMAIN_IP, domainIP);
NodeList::getInstance()->setDomainIP(domainIP);
}
// Handle Local Domain testing with the --local command line
if (cmdOptionExists(argc, constArgv, "--local")) {
printLog("Local Domain MODE!\n");
int ip = getLocalAddress();
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
NodeList::getInstance()->setDomainIPToLocalhost();
}
// Check to see if the user passed in a command line option for loading a local
@ -1101,8 +1101,14 @@ void Application::editPreferences() {
QFormLayout* form = new QFormLayout();
layout->addLayout(form, 1);
const int QLINE_MINIMUM_WIDTH = 400;
QLineEdit* domainServerHostname = new QLineEdit(QString(NodeList::getInstance()->getDomainHostname()));
domainServerHostname->setMinimumWidth(QLINE_MINIMUM_WIDTH);
form->addRow("Domain server:", domainServerHostname);
QLineEdit* avatarURL = new QLineEdit(_myAvatar.getVoxels()->getVoxelURL().toString());
avatarURL->setMinimumWidth(400);
avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
form->addRow("Avatar URL:", avatarURL);
QSpinBox* horizontalFieldOfView = new QSpinBox();
@ -1133,9 +1139,33 @@ void Application::editPreferences() {
if (dialog.exec() != QDialog::Accepted) {
return;
}
const char* newHostname = domainServerHostname->text().toLocal8Bit().data();
// check if the domain server hostname is new
if (memcmp(NodeList::getInstance()->getDomainHostname(), newHostname, sizeof(&newHostname)) != 0) {
// if so we need to clear the nodelist and delete the local voxels
Node *voxelServer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_VOXEL_SERVER);
if (voxelServer) {
voxelServer->lock();
}
_voxels.killLocalVoxels();
if (voxelServer) {
voxelServer->unlock();
}
NodeList::getInstance()->clear();
NodeList::getInstance()->setDomainHostname(newHostname);
}
QUrl url(avatarURL->text());
_myAvatar.getVoxels()->setVoxelURL(url);
sendAvatarVoxelURLMessage(url);
_headCameraPitchYawScale = headCameraPitchYawScale->value();
_myAvatar.setLeanScale(leanScale->value());
_audioJitterBufferSamples = audioJitterBufferSamples->value();
@ -1214,6 +1244,12 @@ void Application::setRenderWarnings(bool renderWarnings) {
_voxels.setRenderPipelineWarnings(renderWarnings);
}
void Application::setRenderVoxels(bool voxelRender) {
if (!voxelRender) {
doKillLocalVoxels();
}
}
void Application::doKillLocalVoxels() {
_wantToKillLocalVoxels = true;
}
@ -1617,9 +1653,8 @@ void Application::initMenu() {
optionsMenu->addAction("Go Home", this, SLOT(goHome()));
QMenu* renderMenu = menuBar->addMenu("Render");
(_renderVoxels = renderMenu->addAction("Voxels"))->setCheckable(true);
(_renderVoxels = renderMenu->addAction("Voxels", this, SLOT(setRenderVoxels(bool)), Qt::SHIFT | Qt::Key_V))->setCheckable(true);
_renderVoxels->setChecked(true);
_renderVoxels->setShortcut(Qt::SHIFT | Qt::Key_V);
(_renderVoxelTextures = renderMenu->addAction("Voxel Textures"))->setCheckable(true);
(_renderStarsOn = renderMenu->addAction("Stars"))->setCheckable(true);
_renderStarsOn->setChecked(true);
@ -2020,8 +2055,8 @@ void Application::update(float deltaTime) {
//loop through all the other avatars and simulate them...
NodeList* nodeList = NodeList::getInstance();
nodeList->lock();
for(NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
node->lock();
if (node->getLinkedData() != NULL) {
Avatar *avatar = (Avatar *)node->getLinkedData();
if (!avatar->isInitialized()) {
@ -2030,8 +2065,8 @@ void Application::update(float deltaTime) {
avatar->simulate(deltaTime, NULL);
avatar->setMouseRay(mouseRayOrigin, mouseRayDirection);
}
node->unlock();
}
nodeList->unlock();
// Simulate myself
if (_gravityUse->isChecked()) {
@ -2520,8 +2555,10 @@ void Application::displaySide(Camera& whichCamera) {
if (_renderAvatarsOn->isChecked()) {
// Render avatars of other nodes
NodeList* nodeList = NodeList::getInstance();
nodeList->lock();
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
node->lock();
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
Avatar *avatar = (Avatar *)node->getLinkedData();
if (!avatar->isInitialized()) {
@ -2530,8 +2567,9 @@ void Application::displaySide(Camera& whichCamera) {
avatar->render(false, _renderAvatarBalls->isChecked());
avatar->setDisplayingLookatVectors(_renderLookatOn->isChecked());
}
node->unlock();
}
nodeList->unlock();
// Render my own Avatar
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
@ -3280,7 +3318,7 @@ void* Application::networkReceive(void* args) {
if (app->_wantToKillLocalVoxels) {
app->_voxels.killLocalVoxels();
app->_wantToKillLocalVoxels = false;
}
}
if (NodeList::getInstance()->getNodeSocket()->receive(&senderAddress, app->_incomingPacket, &bytesReceived)) {
app->_packetCount++;
@ -3301,11 +3339,23 @@ void* Application::networkReceive(void* args) {
case PACKET_TYPE_VOXEL_DATA_MONOCHROME:
case PACKET_TYPE_Z_COMMAND:
case PACKET_TYPE_ERASE_VOXEL:
app->_voxels.parseData(app->_incomingPacket, bytesReceived);
break;
case PACKET_TYPE_ENVIRONMENT_DATA:
app->_environment.parseData(&senderAddress, app->_incomingPacket, bytesReceived);
case PACKET_TYPE_ENVIRONMENT_DATA: {
if (app->_renderVoxels->isChecked()) {
Node* voxelServer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_VOXEL_SERVER);
if (voxelServer) {
voxelServer->lock();
if (app->_incomingPacket[0] == PACKET_TYPE_ENVIRONMENT_DATA) {
app->_environment.parseData(&senderAddress, app->_incomingPacket, bytesReceived);
} else {
app->_voxels.parseData(app->_incomingPacket, bytesReceived);
}
voxelServer->unlock();
}
}
break;
}
case PACKET_TYPE_BULK_AVATAR_DATA:
NodeList::getInstance()->processBulkNodeData(&senderAddress,
app->_incomingPacket,

View file

@ -128,6 +128,7 @@ private slots:
void cycleFrustumRenderMode();
void setRenderWarnings(bool renderWarnings);
void setRenderVoxels(bool renderVoxels);
void doKillLocalVoxels();
void doRandomizeVoxelColors();
void doFalseRandomizeVoxelColors();

View file

@ -96,6 +96,10 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o
Node* audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
if (audioMixer) {
audioMixer->lock();
sockaddr_in audioSocket = *(sockaddr_in*) audioMixer->getActiveSocket();
audioMixer->unlock();
glm::vec3 headPosition = interfaceAvatar->getHeadJointPosition();
glm::quat headOrientation = interfaceAvatar->getHead().getOrientation();
@ -122,12 +126,13 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o
// copy the audio data to the last BUFFER_LENGTH_BYTES bytes of the data packet
memcpy(currentPacketPtr, inputLeft, BUFFER_LENGTH_BYTES_PER_CHANNEL);
nodeList->getNodeSocket()->send(audioMixer->getActiveSocket(),
dataPacket,
BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes);
nodeList->getNodeSocket()->send((sockaddr*) &audioSocket,
dataPacket,
BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes);
interface->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO)
.updateValue(BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes);
interface->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO).updateValue(BUFFER_LENGTH_BYTES_PER_CHANNEL
+ leadingBytes);
}
}

View file

@ -53,6 +53,8 @@ Node::Node(sockaddr* publicSocket, sockaddr* localSocket, char type, uint16_t no
} else {
_localSocket = NULL;
}
pthread_mutex_init(&_mutex, 0);
}
Node::~Node() {
@ -60,6 +62,8 @@ Node::~Node() {
delete _localSocket;
delete _linkedData;
delete _bytesReceivedMovingAverage;
pthread_mutex_destroy(&_mutex);
}
// Names of Node Types

View file

@ -65,6 +65,9 @@ public:
int getPingMs() const { return _pingMs; };
void setPingMs(int pingMs) { _pingMs = pingMs; };
void lock() { pthread_mutex_lock(&_mutex); }
void unlock() { pthread_mutex_unlock(&_mutex); }
static void printLog(Node const&);
private:
@ -83,6 +86,7 @@ private:
NodeData* _linkedData;
bool _isAlive;
int _pingMs;
pthread_mutex_t _mutex;
};

View file

@ -29,9 +29,9 @@ const char SOLO_NODE_TYPES[3] = {
NODE_TYPE_VOXEL_SERVER
};
char DOMAIN_HOSTNAME[] = "highfidelity.below92.com";
char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup
const int DOMAINSERVER_PORT = 40102;
const char DEFAULT_DOMAIN_HOSTNAME[MAX_HOSTNAME_BYTES] = "root.highfidelity.io";
const char DEFAULT_DOMAIN_IP[INET_ADDRSTRLEN] = ""; // IP Address will be re-set by lookup on startup
const int DEFAULT_DOMAINSERVER_PORT = 40102;
bool silentNodeThreadStopFlag = false;
bool pingUnknownNodeThreadStopFlag = false;
@ -63,17 +63,37 @@ NodeList::NodeList(char newOwnerType, unsigned int newSocketListenPort) :
_ownerType(newOwnerType),
_nodeTypesOfInterest(NULL),
_ownerID(UNKNOWN_NODE_ID),
_lastNodeID(0) {
pthread_mutex_init(&mutex, 0);
_lastNodeID(0)
{
memcpy(_domainHostname, DEFAULT_DOMAIN_HOSTNAME, sizeof(DEFAULT_DOMAIN_HOSTNAME));
memcpy(_domainIP, DEFAULT_DOMAIN_IP, sizeof(DEFAULT_DOMAIN_IP));
}
NodeList::~NodeList() {
delete _nodeTypesOfInterest;
clear();
// stop the spawned threads, if they were started
stopSilentNodeRemovalThread();
}
void NodeList::setDomainHostname(const char* domainHostname) {
memset(_domainHostname, 0, sizeof(_domainHostname));
memcpy(_domainHostname, domainHostname, strlen(domainHostname));
pthread_mutex_destroy(&mutex);
// reset the domain IP so the hostname is checked again
setDomainIP("");
}
void NodeList::setDomainIP(const char* domainIP) {
memset(_domainIP, 0, sizeof(_domainIP));
memcpy(_domainIP, domainIP, strlen(domainIP));
}
void NodeList::setDomainIPToLocalhost() {
int ip = getLocalAddress();
sprintf(_domainIP, "%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
}
void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) {
@ -92,7 +112,14 @@ void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) {
void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetData, size_t dataBytes) {
switch (packetData[0]) {
case PACKET_TYPE_DOMAIN: {
processDomainServerList(packetData, dataBytes);
// only process the DS if this is our current domain server
sockaddr_in domainServerSocket = *(sockaddr_in*) senderAddress;
const char* domainSenderIP = inet_ntoa(domainServerSocket.sin_addr);
if (memcmp(domainSenderIP, _domainIP, strlen(domainSenderIP)) == 0) {
processDomainServerList(packetData, dataBytes);
}
break;
}
case PACKET_TYPE_PING: {
@ -110,7 +137,6 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat
}
void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes) {
lock();
// find the avatar mixer in our node list and update the lastRecvTime from it
Node* bulkSendNode = nodeWithAddress(senderAddress);
@ -118,38 +144,37 @@ void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packe
if (bulkSendNode) {
bulkSendNode->setLastHeardMicrostamp(usecTimestampNow());
bulkSendNode->recordBytesReceived(numTotalBytes);
}
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
unsigned char *startPosition = packetData;
unsigned char *currentPosition = startPosition + numBytesPacketHeader;
unsigned char packetHolder[numTotalBytes];
// we've already verified packet version for the bulk packet, so all head data in the packet is also up to date
populateTypeAndVersion(packetHolder, PACKET_TYPE_HEAD_DATA);
uint16_t nodeID = -1;
while ((currentPosition - startPosition) < numTotalBytes) {
unpackNodeId(currentPosition, &nodeID);
memcpy(packetHolder + numBytesPacketHeader,
currentPosition,
numTotalBytes - (currentPosition - startPosition));
Node* matchingNode = nodeWithID(nodeID);
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
if (!matchingNode) {
// we're missing this node, we need to add it to the list
matchingNode = addOrUpdateNode(NULL, NULL, NODE_TYPE_AGENT, nodeID);
unsigned char* startPosition = packetData;
unsigned char* currentPosition = startPosition + numBytesPacketHeader;
unsigned char packetHolder[numTotalBytes];
// we've already verified packet version for the bulk packet, so all head data in the packet is also up to date
populateTypeAndVersion(packetHolder, PACKET_TYPE_HEAD_DATA);
uint16_t nodeID = -1;
while ((currentPosition - startPosition) < numTotalBytes) {
unpackNodeId(currentPosition, &nodeID);
memcpy(packetHolder + numBytesPacketHeader,
currentPosition,
numTotalBytes - (currentPosition - startPosition));
Node* matchingNode = nodeWithID(nodeID);
if (!matchingNode) {
// we're missing this node, we need to add it to the list
matchingNode = addOrUpdateNode(NULL, NULL, NODE_TYPE_AGENT, nodeID);
}
currentPosition += updateNodeWithData(matchingNode,
packetHolder,
numTotalBytes - (currentPosition - startPosition));
}
currentPosition += updateNodeWithData(matchingNode,
packetHolder,
numTotalBytes - (currentPosition - startPosition));
}
unlock();
}
}
int NodeList::updateNodeWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) {
@ -164,6 +189,8 @@ int NodeList::updateNodeWithData(sockaddr *senderAddress, unsigned char *packetD
}
int NodeList::updateNodeWithData(Node *node, unsigned char *packetData, int dataBytes) {
node->lock();
node->setLastHeardMicrostamp(usecTimestampNow());
if (node->getActiveSocket()) {
@ -174,7 +201,11 @@ int NodeList::updateNodeWithData(Node *node, unsigned char *packetData, int data
linkedDataCreateCallback(node);
}
return node->getLinkedData()->parseData(packetData, dataBytes);
int numParsedBytes = node->getLinkedData()->parseData(packetData, dataBytes);
node->unlock();
return numParsedBytes;
}
Node* NodeList::nodeWithAddress(sockaddr *senderAddress) {
@ -209,6 +240,21 @@ int NodeList::getNumAliveNodes() const {
return numAliveNodes;
}
void NodeList::clear() {
// delete all of the nodes in the list, set the pointers back to NULL and the number of nodes to 0
for (int i = 0; i < _numNodes; i++) {
Node** nodeBucket = _nodeBuckets[i / NODES_PER_BUCKET];
Node* node = nodeBucket[i % NODES_PER_BUCKET];
node->lock();
delete node;
node = NULL;
}
_numNodes = 0;
}
void NodeList::setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest) {
delete _nodeTypesOfInterest;
@ -221,18 +267,19 @@ void NodeList::sendDomainServerCheckIn() {
static bool printedDomainServerIP = false;
// Lookup the IP address of the domain server if we need to
if (atoi(DOMAIN_IP) == 0) {
if (atoi(_domainIP) == 0) {
printf("Looking up %s\n", _domainHostname);
struct hostent* pHostInfo;
if ((pHostInfo = gethostbyname(DOMAIN_HOSTNAME)) != NULL) {
if ((pHostInfo = gethostbyname(_domainHostname)) != NULL) {
sockaddr_in tempAddress;
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
printLog("Domain Server: %s \n", DOMAIN_HOSTNAME);
strcpy(_domainIP, inet_ntoa(tempAddress.sin_addr));
printLog("Domain Server: %s \n", _domainHostname);
} else {
printLog("Failed domain server lookup\n");
}
} else if (!printedDomainServerIP) {
printLog("Domain Server IP: %s\n", DOMAIN_IP);
printLog("Domain Server IP: %s\n", _domainIP);
printedDomainServerIP = true;
}
@ -279,7 +326,7 @@ void NodeList::sendDomainServerCheckIn() {
checkInPacketSize = packetPosition - checkInPacket;
}
_nodeSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, checkInPacket, checkInPacketSize);
_nodeSocket.send(_domainIP, DEFAULT_DOMAINSERVER_PORT, checkInPacket, checkInPacketSize);
}
int NodeList::processDomainServerList(unsigned char* packetData, size_t dataBytes) {

View file

@ -9,8 +9,10 @@
#ifndef __hifi__NodeList__
#define __hifi__NodeList__
#include <netinet/in.h>
#include <stdint.h>
#include <iterator>
#include <unistd.h>
#include "Node.h"
#include "UDPSocket.h"
@ -30,9 +32,11 @@ const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000;
extern const char SOLO_NODE_TYPES[3];
extern char DOMAIN_HOSTNAME[];
extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startup
extern const int DOMAINSERVER_PORT;
const int MAX_HOSTNAME_BYTES = 255;
extern const char DEFAULT_DOMAIN_HOSTNAME[MAX_HOSTNAME_BYTES];
extern const char DEFAULT_DOMAIN_IP[INET_ADDRSTRLEN]; // IP Address will be re-set by lookup on startup
extern const int DEFAULT_DOMAINSERVER_PORT;
const int UNKNOWN_NODE_ID = -1;
@ -48,6 +52,12 @@ public:
NodeListIterator begin() const;
NodeListIterator end() const;
const char* getDomainHostname() const { return _domainHostname; };
void setDomainHostname(const char* domainHostname);
void setDomainIP(const char* domainIP);
void setDomainIPToLocalhost();
char getOwnerType() const { return _ownerType; }
uint16_t getLastNodeID() const { return _lastNodeID; }
@ -65,8 +75,7 @@ public:
int size() { return _numNodes; }
int getNumAliveNodes() const;
void lock() { pthread_mutex_lock(&mutex); }
void unlock() { pthread_mutex_unlock(&mutex); }
void clear();
void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest);
void sendDomainServerCheckIn();
@ -101,6 +110,8 @@ private:
void addNodeToList(Node* newNode);
char _domainHostname[MAX_HOSTNAME_BYTES];
char _domainIP[INET_ADDRSTRLEN];
Node** _nodeBuckets[MAX_NUM_NODES / NODES_PER_BUCKET];
int _numNodes;
UDPSocket _nodeSocket;
@ -111,7 +122,6 @@ private:
uint16_t _lastNodeID;
pthread_t removeSilentNodesThread;
pthread_t checkInWithDomainServerThread;
pthread_mutex_t mutex;
void handlePingReply(sockaddr *nodeAddress);
void timePingReply(sockaddr *nodeAddress, unsigned char *packetData);

View file

@ -386,8 +386,7 @@ int main(int argc, const char * argv[]) {
::wantLocalDomain = cmdOptionExists(argc, argv,local);
if (::wantLocalDomain) {
printf("Local Domain MODE!\n");
int ip = getLocalAddress();
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
nodeList->setDomainIPToLocalhost();
}
nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;