mirror of
https://github.com/overte-org/overte.git
synced 2025-06-18 12:20:28 +02:00
183 lines
8.3 KiB
C++
183 lines
8.3 KiB
C++
//
|
|
// PacketReceiver.cpp
|
|
// interface/src
|
|
//
|
|
// Created by Stephen Birarda on 1/23/2014.
|
|
// Update by Ryan Huffman on 7/8/2015.
|
|
// Copyright 2014 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 <QtCore/QWeakPointer>
|
|
|
|
#include <AccountManager.h>
|
|
#include <PerfStat.h>
|
|
|
|
#include "Application.h"
|
|
#include "avatar/AvatarManager.h"
|
|
#include "AudioClient.h"
|
|
#include "Menu.h"
|
|
#include "InterfaceLogging.h"
|
|
|
|
#include "PacketReceiver.h"
|
|
|
|
PacketReceiver::PacketReceiver(QObject* parent) :
|
|
QObject(parent),
|
|
_packetListenerMap()
|
|
{
|
|
|
|
}
|
|
|
|
void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, QString methodName) {
|
|
packetListenerLock.lock();
|
|
if (packetListenerMap.contains(type)) {
|
|
qDebug() << "Warning: Registering a packet listener for packet type " << type
|
|
<< " that will remove a previously registered listener";
|
|
}
|
|
packetListenerMap[type] = QPair<QObject*, QString>(object, methodName);
|
|
packetListenerLock.unlock();
|
|
}
|
|
|
|
void PacketReceiver::processDatagrams() {
|
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
|
"PacketReceiver::processDatagrams()");
|
|
|
|
if (_isShuttingDown) {
|
|
return; // bail early... we're shutting down.
|
|
}
|
|
|
|
HifiSockAddr senderSockAddr;
|
|
|
|
static QByteArray incomingPacket;
|
|
|
|
Application* application = Application::getInstance();
|
|
auto nodeList = DependencyManager::get<NodeList>();
|
|
|
|
while (DependencyManager::get<NodeList>()->getNodeSocket().hasPendingDatagrams()) {
|
|
incomingPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
|
|
nodeList->readDatagram(incomingPacket, senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
|
|
|
_inPacketCount++;
|
|
_inByteCount += incomingPacket.size();
|
|
|
|
if (nodeList->packetVersionAndHashMatch(incomingPacket)) {
|
|
|
|
PacketType::Value incomingType = packetTypeForPacket(incomingPacket);
|
|
// only process this packet if we have a match on the packet version
|
|
switch (incomingType) {
|
|
case PacketType::AudioEnvironment:
|
|
case PacketType::AudioStreamStats:
|
|
case PacketType::MixedAudio:
|
|
case PacketType::SilentAudioFrame: {
|
|
if (incomingType == PacketType::AudioStreamStats) {
|
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "parseAudioStreamStatsPacket",
|
|
Qt::QueuedConnection,
|
|
Q_ARG(QByteArray, incomingPacket));
|
|
} else if (incomingType == PacketType::AudioEnvironment) {
|
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "parseAudioEnvironmentData",
|
|
Qt::QueuedConnection,
|
|
Q_ARG(QByteArray, incomingPacket));
|
|
} else {
|
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "addReceivedAudioToStream",
|
|
Qt::QueuedConnection,
|
|
Q_ARG(QByteArray, incomingPacket));
|
|
}
|
|
|
|
// update having heard from the audio-mixer and record the bytes received
|
|
SharedNodePointer audioMixer = nodeList->sendingNodeForPacket(incomingPacket);
|
|
|
|
if (audioMixer) {
|
|
audioMixer->setLastHeardMicrostamp(usecTimestampNow());
|
|
}
|
|
|
|
break;
|
|
}
|
|
case PacketType::EntityData:
|
|
case PacketType::EntityErase:
|
|
case PacketType::OctreeStats:
|
|
case PacketType::EnvironmentData: {
|
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
|
"Application::networkReceive()... _octreeProcessor.queueReceivedPacket()");
|
|
SharedNodePointer matchedNode = DependencyManager::get<NodeList>()->sendingNodeForPacket(incomingPacket);
|
|
|
|
if (matchedNode) {
|
|
// add this packet to our list of octree packets and process them on the octree data processing
|
|
application->_octreeProcessor.queueReceivedPacket(matchedNode, incomingPacket);
|
|
}
|
|
break;
|
|
}
|
|
case PacketType::BulkAvatarData:
|
|
case PacketType::KillAvatar:
|
|
case PacketType::AvatarIdentity:
|
|
case PacketType::AvatarBillboard: {
|
|
// update having heard from the avatar-mixer and record the bytes received
|
|
SharedNodePointer avatarMixer = nodeList->sendingNodeForPacket(incomingPacket);
|
|
|
|
if (avatarMixer) {
|
|
avatarMixer->setLastHeardMicrostamp(usecTimestampNow());
|
|
|
|
QMetaObject::invokeMethod(DependencyManager::get<AvatarManager>().data(), "processAvatarMixerDatagram",
|
|
Q_ARG(const QByteArray&, incomingPacket),
|
|
Q_ARG(const QWeakPointer<Node>&, avatarMixer));
|
|
}
|
|
break;
|
|
}
|
|
case PacketType::NoisyMute:
|
|
case PacketType::MuteEnvironment: {
|
|
bool mute = !DependencyManager::get<AudioClient>()->isMuted();
|
|
|
|
if (incomingType == PacketType::MuteEnvironment) {
|
|
glm::vec3 position;
|
|
float radius;
|
|
|
|
int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::MuteEnvironment);
|
|
memcpy(&position, incomingPacket.constData() + headerSize, sizeof(glm::vec3));
|
|
memcpy(&radius, incomingPacket.constData() + headerSize + sizeof(glm::vec3), sizeof(float));
|
|
float distance = glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(),
|
|
position);
|
|
|
|
mute = mute && (distance < radius);
|
|
}
|
|
|
|
if (mute) {
|
|
DependencyManager::get<AudioClient>()->toggleMute();
|
|
if (incomingType == PacketType::MuteEnvironment) {
|
|
AudioScriptingInterface::getInstance().environmentMuted();
|
|
} else {
|
|
AudioScriptingInterface::getInstance().mutedByMixer();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PacketType::EntityEditNack:
|
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) {
|
|
application->_entityEditSender.processNackPacket(incomingPacket);
|
|
}
|
|
break;
|
|
default:
|
|
//nodeList->processNodeData(senderSockAddr, incomingPacket);
|
|
|
|
packetListenerLock.lock();
|
|
auto& listener = packetListenerMap[incomingType];
|
|
packetListenerLock.unlock();
|
|
|
|
if (packetListenerMap.contains(incomingType)) {
|
|
auto& listener = packetListenerMap[incomingType];
|
|
NLPacket packet;
|
|
bool success = QMetaObject::invokeMethod(listener.first, listener.second,
|
|
Q_ARG(std::unique_ptr<NLPacket>, packet),
|
|
Q_ARG(HifiSockAddr, senderSockAddr));
|
|
if (!success) {
|
|
qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first.name() << "::" << listener.second;
|
|
}
|
|
} else {
|
|
QDebug() << "No listener found for packet type: " << incomingType;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|