mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 18:42:33 +02:00
Merge remote-tracking branch 'origin'
This commit is contained in:
commit
fff4bac53d
6 changed files with 175 additions and 70 deletions
|
@ -27,6 +27,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <map>
|
||||
#include "AgentList.h"
|
||||
#include "SharedUtil.h"
|
||||
|
||||
|
@ -42,6 +43,15 @@ const int LOGOFF_CHECK_INTERVAL = 5000;
|
|||
int lastActiveCount = 0;
|
||||
AgentList agentList(DOMAIN_LISTEN_PORT);
|
||||
|
||||
unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) {
|
||||
*currentPosition++ = agentToAdd->getType();
|
||||
|
||||
currentPosition += packSocket(currentPosition, agentToAdd->getPublicSocket());
|
||||
currentPosition += packSocket(currentPosition, agentToAdd->getLocalSocket());
|
||||
|
||||
// return the new unsigned char * for broadcast packet
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
|
@ -60,8 +70,10 @@ int main(int argc, const char * argv[])
|
|||
|
||||
agentList.startSilentAgentRemovalThread();
|
||||
|
||||
std::map<char, Agent *> newestSoloAgents;
|
||||
|
||||
while (true) {
|
||||
if (agentList.getAgentSocket()->receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) {
|
||||
if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) {
|
||||
agentType = packetData[0];
|
||||
unpackSocket(&packetData[1], (sockaddr *)&agentLocalAddress);
|
||||
|
||||
|
@ -70,23 +82,35 @@ int main(int argc, const char * argv[])
|
|||
currentBufferPos = broadcastPacket + 1;
|
||||
startPointer = currentBufferPos;
|
||||
|
||||
for(std::vector<Agent>::iterator agent = agentList.agents.begin(); agent != agentList.agents.end(); agent++) {
|
||||
for(std::vector<Agent>::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) {
|
||||
|
||||
if (DEBUG_TO_SELF || !agent->matches((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType)) {
|
||||
*currentBufferPos++ = agent->type;
|
||||
|
||||
currentBufferPos += packSocket(currentBufferPos, agent->publicSocket);
|
||||
currentBufferPos += packSocket(currentBufferPos, agent->localSocket);
|
||||
if (strchr(SOLO_AGENT_TYPES_STRING, (int) agent->getType()) == NULL) {
|
||||
// this is an agent of which there can be multiple, just add them to the packet
|
||||
currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent));
|
||||
} else {
|
||||
// solo agent, we need to only send newest
|
||||
if (newestSoloAgents[agent->getType()] == NULL ||
|
||||
newestSoloAgents[agent->getType()]->getFirstRecvTimeUsecs() < agent->getFirstRecvTimeUsecs()) {
|
||||
// we have to set the newer solo agent to add it to the broadcast later
|
||||
newestSoloAgents[agent->getType()] = &(*agent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// this is the agent, just update last receive to now
|
||||
agent->lastRecvTimeUsecs = usecTimestampNow();
|
||||
agent->setLastRecvTimeUsecs(usecTimestampNow());
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
for (std::map<char, Agent *>::iterator agentIterator = newestSoloAgents.begin();
|
||||
agentIterator != newestSoloAgents.end();
|
||||
agentIterator++) {
|
||||
// this is the newest alive solo agent, add them to the packet
|
||||
currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, agentIterator->second);
|
||||
}
|
||||
|
||||
if ((packetBytesWithoutLeadingChar = (currentBufferPos - startPointer))) {
|
||||
agentList.getAgentSocket()->send((sockaddr *)&agentPublicAddress, broadcastPacket, packetBytesWithoutLeadingChar + 1);
|
||||
agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, broadcastPacket, packetBytesWithoutLeadingChar + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ void Timer(int extra)
|
|||
output[0] = 'I';
|
||||
packSocket(output + 1, localAddress, htons(AGENT_SOCKET_LISTEN_PORT));
|
||||
|
||||
agentList.getAgentSocket()->send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
||||
agentList.getAgentSocket().send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
||||
|
||||
// Ping the agents we can see
|
||||
agentList.pingAgents();
|
||||
|
@ -570,9 +570,9 @@ void display(void)
|
|||
if (display_field) field.render();
|
||||
|
||||
// Render heads of other agents
|
||||
for(std::vector<Agent>::iterator agent = agentList.agents.begin(); agent != agentList.agents.end(); agent++) {
|
||||
if (agent->linkedData != NULL) {
|
||||
Head *agentHead = (Head *)agent->linkedData;
|
||||
for(std::vector<Agent>::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL) {
|
||||
Head *agentHead = (Head *)agent->getLinkedData();
|
||||
glPushMatrix();
|
||||
glm::vec3 pos = agentHead->getPos();
|
||||
glTranslatef(-pos.x, -pos.y, -pos.z);
|
||||
|
@ -583,7 +583,7 @@ void display(void)
|
|||
|
||||
if (!display_head) balls.render();
|
||||
|
||||
// Render the world box
|
||||
// Render the world box
|
||||
if (!display_head && stats_on) render_world_box();
|
||||
|
||||
// Render my own head
|
||||
|
@ -659,7 +659,7 @@ void display(void)
|
|||
|
||||
// Draw number of nearby people always
|
||||
char agents[100];
|
||||
sprintf(agents, "Agents nearby: %ld\n", agentList.agents.size());
|
||||
sprintf(agents, "Agents nearby: %ld\n", agentList.getAgents().size());
|
||||
drawtext(WIDTH-200,20, 0.10, 0, 1.0, 0, agents, 1, 1, 0);
|
||||
|
||||
glPopMatrix();
|
||||
|
@ -744,7 +744,7 @@ void *networkReceive(void *args)
|
|||
char *incomingPacket = new char[MAX_PACKET_SIZE];
|
||||
|
||||
while (!stopNetworkReceiveThread) {
|
||||
if (agentList.getAgentSocket()->receive(&senderAddress, incomingPacket, &bytesReceived)) {
|
||||
if (agentList.getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
|
||||
packetcount++;
|
||||
bytescount += bytesReceived;
|
||||
|
||||
|
@ -851,8 +851,8 @@ void mouseoverFunc( int x, int y)
|
|||
}
|
||||
|
||||
void attachNewHeadToAgent(Agent *newAgent) {
|
||||
if (newAgent->linkedData == NULL) {
|
||||
newAgent->linkedData = new Head();
|
||||
if (newAgent->getLinkedData() == NULL) {
|
||||
newAgent->setLinkedData(new Head());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agent
|
|||
memcpy(localSocket, agentLocalSocket, sizeof(sockaddr));
|
||||
|
||||
type = agentType;
|
||||
|
||||
firstRecvTimeUsecs = usecTimestampNow();
|
||||
lastRecvTimeUsecs = usecTimestampNow();
|
||||
|
||||
activeSocket = NULL;
|
||||
|
@ -43,6 +45,7 @@ Agent::Agent(const Agent &otherAgent) {
|
|||
activeSocket = NULL;
|
||||
}
|
||||
|
||||
firstRecvTimeUsecs = otherAgent.firstRecvTimeUsecs;
|
||||
lastRecvTimeUsecs = otherAgent.lastRecvTimeUsecs;
|
||||
type = otherAgent.type;
|
||||
|
||||
|
@ -55,6 +58,75 @@ Agent& Agent::operator=(Agent otherAgent) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Agent::~Agent() {
|
||||
delete publicSocket;
|
||||
delete localSocket;
|
||||
delete linkedData;
|
||||
}
|
||||
|
||||
char Agent::getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
void Agent::setType(char newType) {
|
||||
type = newType;
|
||||
}
|
||||
|
||||
double Agent::getFirstRecvTimeUsecs() {
|
||||
return firstRecvTimeUsecs;
|
||||
}
|
||||
|
||||
void Agent::setFirstRecvTimeUsecs(double newTimeUsecs) {
|
||||
firstRecvTimeUsecs = newTimeUsecs;
|
||||
}
|
||||
|
||||
double Agent::getLastRecvTimeUsecs() {
|
||||
return lastRecvTimeUsecs;
|
||||
}
|
||||
|
||||
void Agent::setLastRecvTimeUsecs(double newTimeUsecs) {
|
||||
lastRecvTimeUsecs = newTimeUsecs;
|
||||
}
|
||||
|
||||
sockaddr* Agent::getPublicSocket() {
|
||||
return publicSocket;
|
||||
}
|
||||
|
||||
void Agent::setPublicSocket(sockaddr *newSocket) {
|
||||
publicSocket = newSocket;
|
||||
}
|
||||
|
||||
sockaddr* Agent::getLocalSocket() {
|
||||
return localSocket;
|
||||
}
|
||||
|
||||
void Agent::setLocalSocket(sockaddr *newSocket) {
|
||||
publicSocket = newSocket;
|
||||
}
|
||||
|
||||
sockaddr* Agent::getActiveSocket() {
|
||||
return activeSocket;
|
||||
}
|
||||
|
||||
void Agent::activateLocalSocket() {
|
||||
activeSocket = localSocket;
|
||||
}
|
||||
|
||||
void Agent::activatePublicSocket() {
|
||||
activeSocket = publicSocket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AgentData* Agent::getLinkedData() {
|
||||
return linkedData;
|
||||
}
|
||||
|
||||
void Agent::setLinkedData(AgentData *newData) {
|
||||
linkedData = newData;
|
||||
}
|
||||
|
||||
|
||||
bool Agent::operator==(const Agent& otherAgent) {
|
||||
return matches(otherAgent.publicSocket, otherAgent.localSocket, otherAgent.type);
|
||||
}
|
||||
|
@ -68,12 +140,6 @@ void Agent::swap(Agent &first, Agent &second) {
|
|||
swap(first.linkedData, second.linkedData);
|
||||
}
|
||||
|
||||
Agent::~Agent() {
|
||||
delete publicSocket;
|
||||
delete localSocket;
|
||||
delete linkedData;
|
||||
}
|
||||
|
||||
bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType) {
|
||||
// checks if two agent objects are the same agent (same type + local + public address)
|
||||
return type == otherAgentType
|
||||
|
|
|
@ -18,23 +18,35 @@ class Agent {
|
|||
Agent();
|
||||
Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType);
|
||||
Agent(const Agent &otherAgent);
|
||||
~Agent();
|
||||
Agent& operator=(Agent otherAgent);
|
||||
bool operator==(const Agent& otherAgent);
|
||||
~Agent();
|
||||
|
||||
|
||||
bool matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType);
|
||||
|
||||
sockaddr *publicSocket, *localSocket, *activeSocket;
|
||||
char type;
|
||||
timeval pingStarted;
|
||||
int pingMsecs;
|
||||
double lastRecvTimeUsecs;
|
||||
bool isSelf;
|
||||
AgentData *linkedData;
|
||||
char getType();
|
||||
void setType(char newType);
|
||||
double getFirstRecvTimeUsecs();
|
||||
void setFirstRecvTimeUsecs(double newTimeUsecs);
|
||||
double getLastRecvTimeUsecs();
|
||||
void setLastRecvTimeUsecs(double newTimeUsecs);
|
||||
sockaddr* getPublicSocket();
|
||||
void setPublicSocket(sockaddr *newSocket);
|
||||
sockaddr* getLocalSocket();
|
||||
void setLocalSocket(sockaddr *newSocket);
|
||||
sockaddr* getActiveSocket();
|
||||
void activatePublicSocket();
|
||||
void activateLocalSocket();
|
||||
AgentData* getLinkedData();
|
||||
void setLinkedData(AgentData *newData);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Agent* agent);
|
||||
private:
|
||||
void swap(Agent &first, Agent &second);
|
||||
sockaddr *publicSocket, *localSocket, *activeSocket;
|
||||
char type;
|
||||
double firstRecvTimeUsecs;
|
||||
double lastRecvTimeUsecs;
|
||||
AgentData *linkedData;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Agent* agent);
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <pthread.h>
|
||||
#include "SharedUtil.h"
|
||||
|
||||
const char * SOLO_AGENT_TYPES_STRING = "M";
|
||||
|
||||
bool stopAgentRemovalThread = false;
|
||||
pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
@ -28,8 +30,12 @@ AgentList::~AgentList() {
|
|||
stopSilentAgentRemovalThread();
|
||||
}
|
||||
|
||||
UDPSocket * AgentList::getAgentSocket() {
|
||||
return &agentSocket;
|
||||
std::vector<Agent>& AgentList::getAgents() {
|
||||
return agents;
|
||||
}
|
||||
|
||||
UDPSocket& AgentList::getAgentSocket() {
|
||||
return agentSocket;
|
||||
}
|
||||
|
||||
void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes) {
|
||||
|
@ -69,22 +75,22 @@ void AgentList::updateAgentWithData(sockaddr *senderAddress, void *packetData, s
|
|||
if (agentIndex != -1) {
|
||||
Agent *matchingAgent = &agents[agentIndex];
|
||||
|
||||
matchingAgent->lastRecvTimeUsecs = usecTimestampNow();
|
||||
matchingAgent->setLastRecvTimeUsecs(usecTimestampNow());
|
||||
|
||||
if (matchingAgent->linkedData == NULL) {
|
||||
if (matchingAgent->getLinkedData() == NULL) {
|
||||
if (linkedDataCreateCallback != NULL) {
|
||||
linkedDataCreateCallback(matchingAgent);
|
||||
}
|
||||
}
|
||||
|
||||
matchingAgent->linkedData->parseData(packetData, dataBytes);
|
||||
matchingAgent->getLinkedData()->parseData(packetData, dataBytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int AgentList::indexOfMatchingAgent(sockaddr *senderAddress) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
if (agent->activeSocket != NULL && socketMatch(agent->activeSocket, senderAddress)) {
|
||||
if (agent->getActiveSocket() != NULL && socketMatch(agent->getActiveSocket(), senderAddress)) {
|
||||
return agent - agents.begin();
|
||||
}
|
||||
}
|
||||
|
@ -134,10 +140,10 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
|
|||
if (socketMatch(publicSocket, localSocket)) {
|
||||
// likely debugging scenario with DS + agent on local network
|
||||
// set the agent active right away
|
||||
newAgent.activeSocket = newAgent.localSocket;
|
||||
newAgent.activatePublicSocket();
|
||||
}
|
||||
|
||||
if (newAgent.type == 'M' && audioMixerSocketUpdate != NULL) {
|
||||
if (newAgent.getType() == 'M' && audioMixerSocketUpdate != NULL) {
|
||||
// this is an audio mixer
|
||||
// for now that means we need to tell the audio class
|
||||
// to use the local socket information the domain server gave us
|
||||
|
@ -154,10 +160,10 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
|
|||
return true;
|
||||
} else {
|
||||
|
||||
if (agent->type == 'M') {
|
||||
if (agent->getType() == 'M') {
|
||||
// until the Audio class also uses our agentList, we need to update
|
||||
// the lastRecvTimeUsecs for the audio mixer so it doesn't get killed and re-added continously
|
||||
agent->lastRecvTimeUsecs = usecTimestampNow();
|
||||
agent->setLastRecvTimeUsecs(usecTimestampNow());
|
||||
}
|
||||
|
||||
// we had this agent already, do nothing for now
|
||||
|
@ -169,9 +175,9 @@ void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes) {
|
|||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
// for now assume we only want to send to other interface clients
|
||||
// until the Audio class uses the AgentList
|
||||
if (agent->activeSocket != NULL && agent->type == 'I') {
|
||||
if (agent->getActiveSocket() != NULL && agent->getType() == 'I') {
|
||||
// we know which socket is good for this agent, send there
|
||||
agentSocket.send(agent->activeSocket, broadcastData, dataBytes);
|
||||
agentSocket.send(agent->getActiveSocket(), broadcastData, dataBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,15 +186,15 @@ void AgentList::pingAgents() {
|
|||
char payload[] = "P";
|
||||
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
if (agent->type == 'I') {
|
||||
if (agent->activeSocket != NULL) {
|
||||
if (agent->getType() == 'I') {
|
||||
if (agent->getActiveSocket() != NULL) {
|
||||
// we know which socket is good for this agent, send there
|
||||
agentSocket.send(agent->activeSocket, payload, 1);
|
||||
agentSocket.send(agent->getActiveSocket(), payload, 1);
|
||||
} else {
|
||||
// ping both of the sockets for the agent so we can figure out
|
||||
// which socket we can use
|
||||
agentSocket.send(agent->publicSocket, payload, 1);
|
||||
agentSocket.send(agent->localSocket, payload, 1);
|
||||
agentSocket.send(agent->getPublicSocket(), payload, 1);
|
||||
agentSocket.send(agent->getLocalSocket(), payload, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,19 +203,12 @@ void AgentList::pingAgents() {
|
|||
void AgentList::handlePingReply(sockaddr *agentAddress) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
// check both the public and local addresses for each agent to see if we find a match
|
||||
// prioritize the private address so that we prune erroneous local matches
|
||||
sockaddr *matchedSocket = NULL;
|
||||
|
||||
if (socketMatch(agent->publicSocket, agentAddress)) {
|
||||
matchedSocket = agent->publicSocket;
|
||||
} else if (socketMatch(agent->localSocket, agentAddress)) {
|
||||
matchedSocket = agent->localSocket;
|
||||
}
|
||||
|
||||
if (matchedSocket != NULL) {
|
||||
// matched agent, stop checking
|
||||
// update the agent's ping
|
||||
agent->activeSocket = matchedSocket;
|
||||
// prioritize the private address so that we prune erroneous local matches
|
||||
if (socketMatch(agent->getPublicSocket(), agentAddress)) {
|
||||
agent->activatePublicSocket();
|
||||
break;
|
||||
} else if (socketMatch(agent->getLocalSocket(), agentAddress)) {
|
||||
agent->activateLocalSocket();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +222,7 @@ void *removeSilentAgents(void *args) {
|
|||
checkTimeUSecs = usecTimestampNow();
|
||||
|
||||
for(std::vector<Agent>::iterator agent = agents->begin(); agent != agents->end();) {
|
||||
if ((checkTimeUSecs - agent->lastRecvTimeUsecs) > AGENT_SILENCE_THRESHOLD_USECS) {
|
||||
if ((checkTimeUSecs - agent->getLastRecvTimeUsecs()) > AGENT_SILENCE_THRESHOLD_USECS) {
|
||||
std::cout << "Killing agent " << &(*agent) << "\n";
|
||||
pthread_mutex_lock(&vectorChangeMutex);
|
||||
agent = agents->erase(agent);
|
||||
|
|
|
@ -16,17 +16,19 @@
|
|||
|
||||
const unsigned short AGENT_SOCKET_LISTEN_PORT = 40103;
|
||||
const int AGENT_SILENCE_THRESHOLD_USECS = 2 * 1000000;
|
||||
extern const char *SOLO_AGENT_TYPES_STRING;
|
||||
|
||||
class AgentList {
|
||||
public:
|
||||
AgentList();
|
||||
AgentList(int socketListenPort);
|
||||
~AgentList();
|
||||
std::vector<Agent> agents;
|
||||
|
||||
void(*linkedDataCreateCallback)(Agent *);
|
||||
void(*audioMixerSocketUpdate)(in_addr_t, in_port_t);
|
||||
|
||||
UDPSocket* getAgentSocket();
|
||||
|
||||
std::vector<Agent>& getAgents();
|
||||
UDPSocket& getAgentSocket();
|
||||
|
||||
int updateList(unsigned char *packetData, size_t dataBytes);
|
||||
bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType);
|
||||
|
@ -37,11 +39,13 @@ class AgentList {
|
|||
void startSilentAgentRemovalThread();
|
||||
void stopSilentAgentRemovalThread();
|
||||
private:
|
||||
UDPSocket agentSocket;
|
||||
std::vector<Agent> agents;
|
||||
pthread_t removeSilentAgentsThread;
|
||||
|
||||
int indexOfMatchingAgent(sockaddr *senderAddress);
|
||||
void updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes);
|
||||
void handlePingReply(sockaddr *agentAddress);
|
||||
UDPSocket agentSocket;
|
||||
pthread_t removeSilentAgentsThread;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AgentList__) */
|
||||
|
|
Loading…
Reference in a new issue