Example #1
0
void AvatarMixer::run() {
    // change the logging target name while AvatarMixer is running
    Logging::setTargetName(AVATAR_MIXER_LOGGING_NAME);
    
    NodeList* nodeList = NodeList::getInstance();
    nodeList->setOwnerType(NODE_TYPE_AVATAR_MIXER);
    
    nodeList->setNodeTypesOfInterest(&NODE_TYPE_AGENT, 1);
    
    nodeList->linkedDataCreateCallback = attachAvatarDataToNode;
    
    nodeList->startSilentNodeRemovalThread();
    
    sockaddr nodeAddress = {};
    ssize_t receivedBytes = 0;
    
    unsigned char packetData[MAX_PACKET_SIZE];
    
    QUuid nodeUUID;
    Node* avatarNode = NULL;
    
    timeval lastDomainServerCheckIn = {};
    
    while (true) {
        
        if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
            break;
        }
        
        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn();
        }
        
        nodeList->possiblyPingInactiveNodes();
        
        if (nodeList->getNodeSocket()->receive(&nodeAddress, packetData, &receivedBytes) &&
            packetVersionMatch(packetData)) {
            switch (packetData[0]) {
                case PACKET_TYPE_HEAD_DATA:
                    nodeUUID = QUuid::fromRfc4122(QByteArray((char*) packetData + numBytesForPacketHeader(packetData),
                                                                   NUM_BYTES_RFC4122_UUID));
                    
                    // add or update the node in our list
                    avatarNode = nodeList->nodeWithUUID(nodeUUID);
                    
                    if (avatarNode) {
                        // parse positional data from an node
                        nodeList->updateNodeWithData(avatarNode, &nodeAddress, packetData, receivedBytes);
                    } else {
                        break;
                    }
                case PACKET_TYPE_INJECT_AUDIO:
                    broadcastAvatarData(nodeList, nodeUUID, &nodeAddress);
                    break;
                case PACKET_TYPE_AVATAR_URLS:
                case PACKET_TYPE_AVATAR_FACE_VIDEO:
                    nodeUUID = QUuid::fromRfc4122(QByteArray((char*) packetData + numBytesForPacketHeader(packetData),
                                                             NUM_BYTES_RFC4122_UUID));
                    // let everyone else know about the update
                    for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
                        if (node->getActiveSocket() && node->getUUID() != nodeUUID) {
                            nodeList->getNodeSocket()->send(node->getActiveSocket(), packetData, receivedBytes);
                        }
                    }
                    break;
                default:
                    // hand this off to the NodeList
                    nodeList->processNodeData(&nodeAddress, packetData, receivedBytes);
                    break;
            }
        }
    }
    
    nodeList->stopSilentNodeRemovalThread();
}
Example #2
0
int main(int argc, const char* argv[]) {

    NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT);
    setvbuf(stdout, NULL, _IOLBF, 0);
    
    // Handle Local Domain testing with the --local command line
    const char* local = "--local";
    if (cmdOptionExists(argc, argv, local)) {
        printf("Local Domain MODE!\n");
        nodeList->setDomainIPToLocalhost();
    }
    
    nodeList->linkedDataCreateCallback = attachAvatarDataToNode;
    
    nodeList->startSilentNodeRemovalThread();
    
    sockaddr* nodeAddress = new sockaddr;
    ssize_t receivedBytes = 0;
    
    unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
    
    
    uint16_t nodeID = 0;
    Node* avatarNode = NULL;
    
    timeval lastDomainServerCheckIn = {};
    // we only need to hear back about avatar nodes from the DS
    NodeList::getInstance()->setNodeTypesOfInterest(&NODE_TYPE_AGENT, 1);
    
    while (true) {
        
        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn();
        }
        
        if (nodeList->getNodeSocket()->receive(nodeAddress, packetData, &receivedBytes) &&
            packetVersionMatch(packetData)) {
            switch (packetData[0]) {
                case PACKET_TYPE_HEAD_DATA:
                    // grab the node ID from the packet
                    unpackNodeId(packetData + numBytesForPacketHeader(packetData), &nodeID);
                    
                    // add or update the node in our list
                    avatarNode = nodeList->addOrUpdateNode(nodeAddress, nodeAddress, NODE_TYPE_AGENT, nodeID);
                    
                    // parse positional data from an node
                    nodeList->updateNodeWithData(avatarNode, packetData, receivedBytes);
                case PACKET_TYPE_INJECT_AUDIO:
                    broadcastAvatarData(nodeList, nodeAddress);
                    break;
                case PACKET_TYPE_AVATAR_VOXEL_URL:
                case PACKET_TYPE_AVATAR_FACE_VIDEO:
                    // grab the node ID from the packet
                    unpackNodeId(packetData + numBytesForPacketHeader(packetData), &nodeID);
                    
                    // let everyone else know about the update
                    for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
                        if (node->getActiveSocket() && node->getNodeID() != nodeID) {
                            nodeList->getNodeSocket()->send(node->getActiveSocket(), packetData, receivedBytes);
                        }
                    }
                    break;
                case PACKET_TYPE_DOMAIN:
                    // ignore the DS packet, for now nodes are added only when they communicate directly with us
                    break;
                default:
                    // hand this off to the NodeList
                    nodeList->processNodeData(nodeAddress, packetData, receivedBytes);
                    break;
            }
        }
    }
    
    nodeList->stopSilentNodeRemovalThread();
    
    return 0;
}
Example #3
0
void AvatarMixer::run() {
    // change the logging target name while AvatarMixer is running
    Logging::setTargetName(AVATAR_MIXER_LOGGING_NAME);
    
    NodeList* nodeList = NodeList::getInstance();
    nodeList->setOwnerType(NODE_TYPE_AVATAR_MIXER);
    
    nodeList->linkedDataCreateCallback = attachAvatarDataToNode;
    
    nodeList->startSilentNodeRemovalThread();
    
    sockaddr* nodeAddress = new sockaddr;
    ssize_t receivedBytes = 0;
    
    unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
    
    uint16_t nodeID = 0;
    Node* avatarNode = NULL;
    
    timeval lastDomainServerCheckIn = {};
    // we only need to hear back about avatar nodes from the DS
    nodeList->setNodeTypesOfInterest(&NODE_TYPE_AGENT, 1);
    
    while (true) {
        
        if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
            break;
        }
        
        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn();
        }
        
        if (nodeList->getNodeSocket()->receive(nodeAddress, packetData, &receivedBytes) &&
            packetVersionMatch(packetData)) {
            switch (packetData[0]) {
                case PACKET_TYPE_HEAD_DATA:
                    // grab the node ID from the packet
                    unpackNodeId(packetData + numBytesForPacketHeader(packetData), &nodeID);
                    
                    // add or update the node in our list
                    avatarNode = nodeList->addOrUpdateNode(nodeAddress, nodeAddress, NODE_TYPE_AGENT, nodeID);
                    
                    // parse positional data from an node
                    nodeList->updateNodeWithData(avatarNode, packetData, receivedBytes);
                case PACKET_TYPE_INJECT_AUDIO:
                    broadcastAvatarData(nodeList, nodeAddress);
                    break;
                case PACKET_TYPE_AVATAR_VOXEL_URL:
                case PACKET_TYPE_AVATAR_FACE_VIDEO:
                    // grab the node ID from the packet
                    unpackNodeId(packetData + numBytesForPacketHeader(packetData), &nodeID);
                    
                    // let everyone else know about the update
                    for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
                        if (node->getActiveSocket() && node->getNodeID() != nodeID) {
                            nodeList->getNodeSocket()->send(node->getActiveSocket(), packetData, receivedBytes);
                        }
                    }
                    break;
                default:
                    // hand this off to the NodeList
                    nodeList->processNodeData(nodeAddress, packetData, receivedBytes);
                    break;
            }
        }
    }
    
    nodeList->stopSilentNodeRemovalThread();
}