mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 05:23:33 +02:00
have avatar-mixer report avatar kills to all avatars
This commit is contained in:
parent
a9f1984676
commit
1f95d0c017
10 changed files with 78 additions and 36 deletions
|
@ -30,7 +30,8 @@ const unsigned int AVATAR_DATA_SEND_INTERVAL_USECS = (1 / 60.0) * 1000 * 1000;
|
||||||
AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) :
|
AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) :
|
||||||
ThreadedAssignment(dataBuffer, numBytes)
|
ThreadedAssignment(dataBuffer, numBytes)
|
||||||
{
|
{
|
||||||
|
// make sure we hear about node kills so we can tell the other nodes
|
||||||
|
connect(NodeList::getInstance(), &NodeList::nodeKilled, this, &AvatarMixer::nodeKilled);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* addNodeToBroadcastPacket(unsigned char *currentPosition, Node *nodeToAdd) {
|
unsigned char* addNodeToBroadcastPacket(unsigned char *currentPosition, Node *nodeToAdd) {
|
||||||
|
@ -116,6 +117,21 @@ void broadcastAvatarData() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
|
||||||
|
if (killedNode->getType() == NODE_TYPE_AGENT
|
||||||
|
&& killedNode->getLinkedData()) {
|
||||||
|
// this was an avatar we were sending to other people
|
||||||
|
// send a kill packet for it to our other nodes
|
||||||
|
unsigned char packetData[MAX_PACKET_SIZE];
|
||||||
|
int numHeaderBytes = populateTypeAndVersion(packetData, PACKET_TYPE_KILL_AVATAR);
|
||||||
|
|
||||||
|
QByteArray rfcUUID = killedNode->getUUID().toRfc4122();
|
||||||
|
memcpy(packetData + numHeaderBytes, rfcUUID.constData(), rfcUUID.size());
|
||||||
|
|
||||||
|
NodeList::getInstance()->broadcastToNodes(packetData, numHeaderBytes + NUM_BYTES_RFC4122_UUID, &NODE_TYPE_AGENT, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
@ -136,7 +152,10 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case PACKET_TYPE_KILL_NODE:
|
case PACKET_TYPE_KILL_AVATAR: {
|
||||||
|
nodeList->processKillNode(dataByteArray);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// hand this off to the NodeList
|
// hand this off to the NodeList
|
||||||
nodeList->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
nodeList->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||||
|
|
|
@ -19,6 +19,8 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
/// runs the avatar mixer
|
/// runs the avatar mixer
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
void nodeKilled(SharedNodePointer killedNode);
|
||||||
|
|
||||||
void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr);
|
void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr);
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,7 +89,8 @@ void DatagramProcessor::processDatagrams() {
|
||||||
application->_metavoxels.processData(QByteArray((const char*) incomingPacket, bytesReceived),
|
application->_metavoxels.processData(QByteArray((const char*) incomingPacket, bytesReceived),
|
||||||
senderSockAddr);
|
senderSockAddr);
|
||||||
break;
|
break;
|
||||||
case PACKET_TYPE_BULK_AVATAR_DATA: {
|
case PACKET_TYPE_BULK_AVATAR_DATA:
|
||||||
|
case PACKET_TYPE_KILL_AVATAR: {
|
||||||
// update having heard from the avatar-mixer and record the bytes received
|
// update having heard from the avatar-mixer and record the bytes received
|
||||||
SharedNodePointer avatarMixer = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
SharedNodePointer avatarMixer = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||||
|
|
||||||
|
@ -97,15 +98,21 @@ void DatagramProcessor::processDatagrams() {
|
||||||
avatarMixer->setLastHeardMicrostamp(usecTimestampNow());
|
avatarMixer->setLastHeardMicrostamp(usecTimestampNow());
|
||||||
avatarMixer->recordBytesReceived(bytesReceived);
|
avatarMixer->recordBytesReceived(bytesReceived);
|
||||||
|
|
||||||
|
QByteArray datagram(reinterpret_cast<char*>(incomingPacket), bytesReceived);
|
||||||
|
|
||||||
QMetaObject::invokeMethod(&application->getAvatarManager(), "processAvatarMixerDatagram",
|
if (incomingPacket[0] == PACKET_TYPE_BULK_AVATAR_DATA) {
|
||||||
Q_ARG(const QByteArray&,
|
QMetaObject::invokeMethod(&application->getAvatarManager(), "processAvatarMixerDatagram",
|
||||||
QByteArray(reinterpret_cast<char*>(incomingPacket), bytesReceived)));
|
Q_ARG(const QByteArray&, datagram));
|
||||||
|
} else {
|
||||||
|
// this is an avatar kill, pass it to the application AvatarManager
|
||||||
|
QMetaObject::invokeMethod(&application->getAvatarManager(), "processKillAvatar",
|
||||||
|
Q_ARG(const QByteArray&, datagram));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
|
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_TYPE_DATA_SERVER_GET:
|
case PACKET_TYPE_DATA_SERVER_GET:
|
||||||
case PACKET_TYPE_DATA_SERVER_PUT:
|
case PACKET_TYPE_DATA_SERVER_PUT:
|
||||||
case PACKET_TYPE_DATA_SERVER_SEND:
|
case PACKET_TYPE_DATA_SERVER_SEND:
|
||||||
|
|
|
@ -51,4 +51,19 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram) {
|
||||||
bytesRead += matchingAvatar->parseData(avatarData,
|
bytesRead += matchingAvatar->parseData(avatarData,
|
||||||
datagram.size() - bytesRead);
|
datagram.size() - bytesRead);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarManager::processKillAvatar(const QByteArray& datagram) {
|
||||||
|
// read the node id
|
||||||
|
QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(reinterpret_cast<const unsigned char*>
|
||||||
|
(datagram.data())),
|
||||||
|
NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
|
// kill the avatar with that UUID from our hash, if it exists
|
||||||
|
_hash.remove(nodeUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarManager::clearHash() {
|
||||||
|
// clear the AvatarManager hash - typically happens on the removal of the avatar-mixer
|
||||||
|
_hash.clear();
|
||||||
}
|
}
|
|
@ -20,6 +20,8 @@ public:
|
||||||
AvatarManager(QObject* parent = 0);
|
AvatarManager(QObject* parent = 0);
|
||||||
public slots:
|
public slots:
|
||||||
void processAvatarMixerDatagram(const QByteArray& datagram);
|
void processAvatarMixerDatagram(const QByteArray& datagram);
|
||||||
|
void processKillAvatar(const QByteArray& datagram);
|
||||||
|
void clearHash();
|
||||||
private:
|
private:
|
||||||
QHash<QUuid, Avatar*> _hash;
|
QHash<QUuid, Avatar*> _hash;
|
||||||
};
|
};
|
||||||
|
|
|
@ -472,6 +472,21 @@ void MyAvatar::loadData(QSettings* settings) {
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyAvatar::sendKillAvatar() {
|
||||||
|
unsigned char packet[MAX_PACKET_SIZE];
|
||||||
|
unsigned char* packetPosition = packet;
|
||||||
|
|
||||||
|
packetPosition += populateTypeAndVersion(packetPosition, PACKET_TYPE_KILL_AVATAR);
|
||||||
|
|
||||||
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
QByteArray rfcUUID = nodeList->getOwnerUUID().toRfc4122();
|
||||||
|
memcpy(packetPosition, rfcUUID.constData(), rfcUUID.size());
|
||||||
|
packetPosition += rfcUUID.size();
|
||||||
|
|
||||||
|
nodeList->broadcastToNodes(packet, packetPosition - packet, &NODE_TYPE_AVATAR_MIXER, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
|
void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
|
||||||
// first orbit horizontally
|
// first orbit horizontally
|
||||||
glm::quat orientation = getOrientation();
|
glm::quat orientation = getOrientation();
|
||||||
|
|
|
@ -25,7 +25,7 @@ enum AvatarHandState
|
||||||
class MyAvatar : public Avatar {
|
class MyAvatar : public Avatar {
|
||||||
public:
|
public:
|
||||||
MyAvatar(Node* owningNode = NULL);
|
MyAvatar(Node* owningNode = NULL);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void simulate(float deltaTime, Transmitter* transmitter);
|
void simulate(float deltaTime, Transmitter* transmitter);
|
||||||
void updateFromGyros(bool turnWithHead);
|
void updateFromGyros(bool turnWithHead);
|
||||||
|
@ -62,6 +62,8 @@ public:
|
||||||
void setDriveKeys(int key, float val) { _driveKeys[key] = val; };
|
void setDriveKeys(int key, float val) { _driveKeys[key] = val; };
|
||||||
bool getDriveKeys(int key) { return _driveKeys[key]; };
|
bool getDriveKeys(int key) { return _driveKeys[key]; };
|
||||||
void jump() { _shouldJump = true; };
|
void jump() { _shouldJump = true; };
|
||||||
|
|
||||||
|
void sendKillAvatar();
|
||||||
|
|
||||||
// Set/Get update the thrust that will move the avatar around
|
// Set/Get update the thrust that will move the avatar around
|
||||||
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
||||||
|
|
|
@ -180,10 +180,6 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, unsigned char
|
||||||
processSTUNResponse(packetData, dataBytes);
|
processSTUNResponse(packetData, dataBytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_TYPE_KILL_NODE: {
|
|
||||||
processKillNode(packetData, dataBytes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,30 +412,13 @@ NodeHash::iterator NodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItem
|
||||||
return _nodeHash.erase(nodeItemToKill);
|
return _nodeHash.erase(nodeItemToKill);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::sendKillNode(const char* nodeTypes, int numNodeTypes) {
|
void NodeList::processKillNode(const QByteArray& dataByteArray) {
|
||||||
unsigned char packet[MAX_PACKET_SIZE];
|
|
||||||
unsigned char* packetPosition = packet;
|
|
||||||
|
|
||||||
packetPosition += populateTypeAndVersion(packetPosition, PACKET_TYPE_KILL_NODE);
|
|
||||||
|
|
||||||
QByteArray rfcUUID = _ownerUUID.toRfc4122();
|
|
||||||
memcpy(packetPosition, rfcUUID.constData(), rfcUUID.size());
|
|
||||||
packetPosition += rfcUUID.size();
|
|
||||||
|
|
||||||
broadcastToNodes(packet, packetPosition - packet, nodeTypes, numNodeTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::processKillNode(unsigned char* packetData, size_t dataBytes) {
|
|
||||||
// skip the header
|
|
||||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
|
||||||
packetData += numBytesPacketHeader;
|
|
||||||
dataBytes -= numBytesPacketHeader;
|
|
||||||
|
|
||||||
// read the node id
|
// read the node id
|
||||||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)packetData, NUM_BYTES_RFC4122_UUID));
|
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(reinterpret_cast
|
||||||
|
<const unsigned char*>(dataByteArray.data())),
|
||||||
|
NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
packetData += NUM_BYTES_RFC4122_UUID;
|
|
||||||
dataBytes -= NUM_BYTES_RFC4122_UUID;
|
|
||||||
// kill the node with this UUID, if it exists
|
// kill the node with this UUID, if it exists
|
||||||
killNodeWithUUID(nodeUUID);
|
killNodeWithUUID(nodeUUID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,8 @@ public:
|
||||||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||||
|
|
||||||
void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes);
|
void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes);
|
||||||
|
|
||||||
|
void processKillNode(const QByteArray& datagram);
|
||||||
|
|
||||||
int updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes);
|
int updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes);
|
||||||
|
|
||||||
|
@ -141,7 +143,6 @@ private:
|
||||||
void sendSTUNRequest();
|
void sendSTUNRequest();
|
||||||
void processSTUNResponse(unsigned char* packetData, size_t dataBytes);
|
void processSTUNResponse(unsigned char* packetData, size_t dataBytes);
|
||||||
|
|
||||||
void processKillNode(unsigned char* packetData, size_t dataBytes);
|
|
||||||
NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill);
|
NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill);
|
||||||
|
|
||||||
NodeHash _nodeHash;
|
NodeHash _nodeHash;
|
||||||
|
|
|
@ -18,7 +18,7 @@ const PACKET_TYPE PACKET_TYPE_STUN_RESPONSE = 1;
|
||||||
const PACKET_TYPE PACKET_TYPE_DOMAIN = 'D';
|
const PACKET_TYPE PACKET_TYPE_DOMAIN = 'D';
|
||||||
const PACKET_TYPE PACKET_TYPE_PING = 'P';
|
const PACKET_TYPE PACKET_TYPE_PING = 'P';
|
||||||
const PACKET_TYPE PACKET_TYPE_PING_REPLY = 'R';
|
const PACKET_TYPE PACKET_TYPE_PING_REPLY = 'R';
|
||||||
const PACKET_TYPE PACKET_TYPE_KILL_NODE = 'K';
|
const PACKET_TYPE PACKET_TYPE_KILL_AVATAR = 'K';
|
||||||
const PACKET_TYPE PACKET_TYPE_HEAD_DATA = 'H';
|
const PACKET_TYPE PACKET_TYPE_HEAD_DATA = 'H';
|
||||||
const PACKET_TYPE PACKET_TYPE_INJECT_AUDIO = 'I';
|
const PACKET_TYPE PACKET_TYPE_INJECT_AUDIO = 'I';
|
||||||
const PACKET_TYPE PACKET_TYPE_MIXED_AUDIO = 'A';
|
const PACKET_TYPE PACKET_TYPE_MIXED_AUDIO = 'A';
|
||||||
|
|
Loading…
Reference in a new issue