void UpdateServersList() { serverList.clear(); const DataStructures::Table *games = phpDirectoryServer2->GetLastDownloadedTable(); //char str[256]; //games->PrintColumnHeaders(str, 255, ':'); std::cout << str << std::endl; //__GAME_PORT:__GAME_NAME:__SYSTEM_ADDRESS:__SEC_AFTER_EPOCH_SINCE_LAST_UPDATE int gamePortIndex = games->ColumnIndex("__GAME_PORT"); int gameNameIndex = games->ColumnIndex("__GAME_NAME"); int gameSystemAdressIndex = games->ColumnIndex("__SYSTEM_ADDRESS"); int gameTimestampIndex = games->ColumnIndex("__SEC_AFTER_EPOCH_SINCE_LAST_UPDATE"); int gameGUIDIndex = games->ColumnIndex("GUID"); for (unsigned i = 0; i < games->GetRowCount(); ++i) { //80:Foo:192.168.1.8:1284635693 //TODO: Data validation. Or should we trust the phpDirectServer2 to dp it for us? DataStructures::Table::Row* row = games->GetRowByIndex(i,NULL); RakNet::SystemAddress address = RakNet::SystemAddress(row->cells[gameSystemAdressIndex]->c,(unsigned short)row->cells[gamePortIndex]->i); RakNet::RakNetGUID guid; if(!guid.FromString(row->cells[gameGUIDIndex]->c)) std::cout << "Invalid GUID: " << row->cells[gameGUIDIndex]->c << std::endl; ServerInfo serverInfo = ServerInfo(row->cells[gameNameIndex]->c,address,guid); //games->PrintRow(str, 255, ':', false, row); std::cout << str << std::endl; serverList.push_back(serverInfo); } //std::cout << "Updated server list" << std::endl; }
int UserPool::AddToUserPool(char *username, RakNet::RakNetGUID guid) { for (int i = 0; i < sizeof(playerData); i++) { if (playerData[i].used == false) { playerData[i].playerid = i; playerData[i].playerusername = username; playerData[i].playerguid = guid; playerData[i].used = true; printf("%s - %s\n", playerData[i].playerguid.ToString(), guid.ToString()); return i; } } return -1; }
void Server::update(running_machine *machine) { for( map<RakNet::RakNetGUID,vector< string > >::iterator it = unknownPeerInputs.begin(); it != unknownPeerInputs.end(); ) { cout << "GOT UNKNOWN PEER INPUT\n"; if(peerIDs.find(it->first)!=peerIDs.end()) { int ID = peerIDs[it->first]; for(int a=0;a<it->second.size();a++) { peerInputs[ID].push_back(it->second[a]); } map<RakNet::RakNetGUID,vector< string > >::iterator itold = it; it++; unknownPeerInputs.erase(itold); } else { it++; } } //cout << "SERVER TIME: " << RakNet::GetTimeMS()/1000.0f/60.0f << endl; //printf("Updating server\n"); RakNet::Packet *p; for (p=rakInterface->Receive(); p; rakInterface->DeallocatePacket(p), p=rakInterface->Receive()) { // We got a packet, get the identifier with our handy function unsigned char packetIdentifier = GetPacketIdentifier(p); //printf("GOT PACKET %d\n",int(packetIdentifier)); // Check if this is a network message packet switch (packetIdentifier) { case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true)); removePeer(p->guid,machine); break; case ID_NEW_INCOMING_CONNECTION: // Somebody connected. We have their IP now printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); if(syncHappend) { //Sorry, too late //rakInterface->CloseConnection(p->systemAddress,true); } break; case ID_CLIENT_INFO: cout << "GOT ID_CLIENT_INFO\n"; //This client is requesting candidacy, set their info { char buf[4096]; strcpy(buf,(char*)(p->data+1)); candidateNames[p->systemAddress] = buf; } //Find a session index for the player { char buf[4096]; buf[0] = ID_SETTINGS; memcpy(buf+1,&secondsBetweenSync,sizeof(int)); strcpy(buf+1+sizeof(int),username.c_str()); rakInterface->Send( buf, 1+sizeof(int)+username.length()+1, HIGH_PRIORITY, RELIABLE_ORDERED, ORDERING_CHANNEL_SYNC, p->guid, false ); } if(acceptedPeers.size()>=maxPeerID-1) { //Sorry, no room rakInterface->CloseConnection(p->systemAddress,true); } else if(acceptedPeers.size()) { printf("Asking other peers to accept %s\n",p->systemAddress.ToString()); waitingForAcceptFrom[p->systemAddress] = std::vector<RakNet::RakNetGUID>(); for(int a=0; a<acceptedPeers.size(); a++) { RakNet::RakNetGUID guid = acceptedPeers[a]; waitingForAcceptFrom[p->systemAddress].push_back(guid); cout << "SENDING ADVERTIZE TO " << guid.ToString() << endl; char buf[4096]; buf[0] = ID_ADVERTISE_SYSTEM; strcpy(buf+1,p->systemAddress.ToString(true)); rakInterface->Send(buf,1+strlen(p->systemAddress.ToString(true))+1,HIGH_PRIORITY,RELIABLE_ORDERED,ORDERING_CHANNEL_SYNC,guid,false); } printf("Asking other peers to accept\n"); } else { //First client, automatically accept acceptPeer(p->systemAddress,machine); } break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_ACCEPT_NEW_HOST: { printf("Accepting new host\n"); RakNet::SystemAddress saToAccept; saToAccept.SetBinaryAddress(((char*)p->data)+1); for(int a=0; a<waitingForAcceptFrom[saToAccept].size(); a++) { if(waitingForAcceptFrom[saToAccept][a]==p->guid) { waitingForAcceptFrom[saToAccept].erase(waitingForAcceptFrom[saToAccept].begin()+a); break; } } if(waitingForAcceptFrom[saToAccept].empty()) { cout << "Accepting: " << saToAccept.ToString() << endl; waitingForAcceptFrom.erase(waitingForAcceptFrom.find(saToAccept)); acceptPeer(saToAccept,machine); } } break; case ID_REJECT_NEW_HOST: { RakNet::SystemAddress saToReject; saToReject.SetBinaryAddress(((char*)p->data)+1); printf("Rejecting new client\n"); cout << p->guid.ToString() << " REJECTS " << saToReject.ToString() << endl; if(waitingForAcceptFrom.find(saToReject)==waitingForAcceptFrom.end()) printf("Could not find waitingForAcceptFrom for this GUID, weird"); else waitingForAcceptFrom.erase(waitingForAcceptFrom.find(saToReject)); rakInterface->CloseConnection(saToReject,true); } break; case ID_CLIENT_INPUTS: if(peerIDs.find(p->guid)==peerIDs.end() || peerInputs.find(peerIDs[p->guid])==peerInputs.end()) { cout << __FILE__ << ":" << __LINE__ << " OOPS!!!!\n"; } //cout << "GOT CLIENT INPUTS\n"; peerInputs[peerIDs[p->guid]].push_back(string((char*)GetPacketData(p),(int)GetPacketSize(p))); break; default: printf("UNEXPECTED PACKET ID: %d\n",int(packetIdentifier)); break; } } }
int main(void) { int i; for (i=0; i < NUM_PEERS; i++) rakPeer[i]=RakNet::RakPeerInterface::GetInstance(); printf("This project tests and demonstrates the team balancer mesh plugin.\n"); printf("It uses FullyConnectedMesh2 to test in a peer to peer enviroment"); printf("Difficulty: Intermediate\n\n"); int peerIndex; // Initialize the message handlers for (peerIndex=0; peerIndex < NUM_PEERS; peerIndex++) { // fullyConnectedMeshPlugin[peerIndex].Startup(0,0); rakPeer[peerIndex]->AttachPlugin(&fullyConnectedMeshPlugin[peerIndex]); // The fully connected mesh relies on the connection graph plugin also being attached rakPeer[peerIndex]->AttachPlugin(&connectionGraphPlugin[peerIndex]); rakPeer[peerIndex]->AttachPlugin(&teamBalancerPlugin[peerIndex]); rakPeer[peerIndex]->SetMaximumIncomingConnections(NUM_PEERS); } // Initialize the peers for (peerIndex=0; peerIndex < NUM_PEERS; peerIndex++) { RakNet::SocketDescriptor socketDescriptor(60000+peerIndex,0); rakPeer[peerIndex]->Startup(NUM_PEERS, &socketDescriptor, 1); } // Give the threads time to properly start RakSleep(200); printf("Peers initialized. "); printf("Connecting each peer to the prior peer\n"); // Connect each peer to the prior peer for (peerIndex=1; peerIndex < NUM_PEERS; peerIndex++) { rakPeer[peerIndex]->Connect("127.0.0.1", 60000+peerIndex-1, 0, 0); } RakSleep(200); RakNet::RakNetGUID hostGuid = fullyConnectedMeshPlugin[0].GetHostSystem(); printf("Host is %s\n", hostGuid.ToString()); unsigned int hostIndex; for (peerIndex=0; peerIndex < NUM_PEERS; peerIndex++) { if (hostGuid==rakPeer[peerIndex]->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS)) hostIndex=peerIndex; teamBalancerPlugin[peerIndex].SetTeamSizeLimit(0, NUM_PEERS/2); teamBalancerPlugin[peerIndex].SetTeamSizeLimit(1, NUM_PEERS/2); RakAssert(teamBalancerPlugin[peerIndex].GetMyTeam(UNASSIGNED_NETWORK_ID)==UNASSIGNED_TEAM_ID); } int team0,team1; // system 0 requests team 0 teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==0); // system 1 requests team 0 - check both on team 0 teamBalancerPlugin[1].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); GetTeams(team0,team1); RakAssert(team0==2); RakAssert(team1==0); // system 1 requests team 1 - check evenly balanced teamBalancerPlugin[1].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 1); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==1); // system 0 requests team 1 - check both on team 1 teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 1); Wait(); GetTeams(team0,team1); RakAssert(team0==0); RakAssert(team1==2); // host sets autobalances team - check evenly balanced teamBalancerPlugin[hostIndex].SetForceEvenTeams(true); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==1); // system 1 requests opposite team - check evenly balanced teamBalancerPlugin[1].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, ! teamBalancerPlugin[1].GetMyTeam(UNASSIGNED_NETWORK_ID)); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==1); RakNet::TeamId team1OldTeam = teamBalancerPlugin[1].GetMyTeam(UNASSIGNED_NETWORK_ID); // system 0 requests opposite team - check evenly balanced and swapped teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, ! teamBalancerPlugin[0].GetMyTeam(UNASSIGNED_NETWORK_ID)); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==1); RakAssert(teamBalancerPlugin[1].GetMyTeam(UNASSIGNED_NETWORK_ID)!=team1OldTeam); // system 2 requests team 0 - check that two systems on team 0, one system on team 1 teamBalancerPlugin[2].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); GetTeams(team0,team1); RakAssert(team0==2); RakAssert(team1==1); // system 3 requests team 0 - check that two systems on team 0, two systems on team 1 teamBalancerPlugin[3].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); GetTeams(team0,team1); RakAssert(team0==2); RakAssert(team1==2); // Unset autobalance teams - check that two systems on team 0, two systems on team 1 teamBalancerPlugin[hostIndex].SetForceEvenTeams(false); // All systems set team 0, check same as before. RakNet::TeamId t0=teamBalancerPlugin[0].GetMyTeam(UNASSIGNED_NETWORK_ID); RakNet::TeamId t1=teamBalancerPlugin[1].GetMyTeam(UNASSIGNED_NETWORK_ID); RakNet::TeamId t2=teamBalancerPlugin[2].GetMyTeam(UNASSIGNED_NETWORK_ID); RakNet::TeamId t3=teamBalancerPlugin[3].GetMyTeam(UNASSIGNED_NETWORK_ID); teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); teamBalancerPlugin[1].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); teamBalancerPlugin[2].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); teamBalancerPlugin[3].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); RakAssert(t0==teamBalancerPlugin[0].GetMyTeam(UNASSIGNED_NETWORK_ID)); RakAssert(t1==teamBalancerPlugin[1].GetMyTeam(UNASSIGNED_NETWORK_ID)); RakAssert(t2==teamBalancerPlugin[2].GetMyTeam(UNASSIGNED_NETWORK_ID)); RakAssert(t3==teamBalancerPlugin[3].GetMyTeam(UNASSIGNED_NETWORK_ID)); // All systems unset their teams teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, UNASSIGNED_TEAM_ID); teamBalancerPlugin[1].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, UNASSIGNED_TEAM_ID); teamBalancerPlugin[2].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, UNASSIGNED_TEAM_ID); teamBalancerPlugin[3].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, UNASSIGNED_TEAM_ID); Wait(); GetTeams(team0,team1); RakAssert(team0==0); RakAssert(team1==0); // system 0 requests team 0 - check teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==0); // system 0 requests team 1 - check teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 1); Wait(); GetTeams(team0,team1); RakAssert(team0==0); RakAssert(team1==1); // system 0 requests team 0 - check teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==0); // Set autobalance teams teamBalancerPlugin[hostIndex].SetForceEvenTeams(true); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==0); // system 1 requests team 0 - check evenly balanced teamBalancerPlugin[1].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==1); // Lock teams teamBalancerPlugin[hostIndex].SetLockTeams(true); // System 1 requests team 1 - would normally swap, but teams are locked teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 1); Wait(); // Unset autobalance teams - check evenly balanced teamBalancerPlugin[hostIndex].SetForceEvenTeams(false); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==1); t0=teamBalancerPlugin[0].GetMyTeam(UNASSIGNED_NETWORK_ID); t1=teamBalancerPlugin[1].GetMyTeam(UNASSIGNED_NETWORK_ID); // Unlock teams - check swapped teamBalancerPlugin[hostIndex].SetLockTeams(false); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==1); RakAssert(t0!=teamBalancerPlugin[0].GetMyTeam(UNASSIGNED_NETWORK_ID)); RakAssert(t1!=teamBalancerPlugin[1].GetMyTeam(UNASSIGNED_NETWORK_ID)); // Lock teams teamBalancerPlugin[hostIndex].SetLockTeams(true); // system 0 requests team 0 - check evenly balanced teamBalancerPlugin[0].RequestSpecificTeam(UNASSIGNED_NETWORK_ID, 0); Wait(); GetTeams(team0,team1); RakAssert(team0==1); RakAssert(team1==1); // Unlock teams - check both on team 0 teamBalancerPlugin[hostIndex].SetLockTeams(false); Wait(); GetTeams(team0,team1); RakAssert(team0==2); RakAssert(team1==0); for (i=0; i < NUM_PEERS; i++) RakNet::RakPeerInterface::DestroyInstance(rakPeer[i]); return 1; }
void Player::setGUID(RakNet::RakNetGUID playerGUID) { stringGUID = playerGUID.ToString(); }
/// RakNet stuff void CDemo::UpdateRakNet(void) { RakNet::SystemAddress facilitatorSystemAddress(DEFAULT_NAT_PUNCHTHROUGH_FACILITATOR_IP, DEFAULT_NAT_PUNCHTHROUGH_FACILITATOR_PORT); RakNet::Packet *packet; RakNet::TimeMS curTime = RakNet::GetTimeMS(); RakNet::RakString targetName; for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive()) { if (strcmp(packet->systemAddress.ToString(false),DEFAULT_NAT_PUNCHTHROUGH_FACILITATOR_IP)==0) { targetName="NATPunchthroughServer"; } else { targetName=packet->systemAddress.ToString(true); } switch (packet->data[0]) { case ID_IP_RECENTLY_CONNECTED: { PushMessage(RakNet::RakString("This IP address recently connected from ") + targetName + RakNet::RakString(".")); if (packet->systemAddress==facilitatorSystemAddress) PushMessage("Multiplayer will not work without the NAT punchthrough server!"); } break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: { PushMessage(RakNet::RakString("Incompatible protocol version from ") + targetName + RakNet::RakString(".")); if (packet->systemAddress==facilitatorSystemAddress) PushMessage("Multiplayer will not work without the NAT punchthrough server!"); } break; case ID_DISCONNECTION_NOTIFICATION: { PushMessage(RakNet::RakString("Disconnected from ") + targetName + RakNet::RakString(".")); if (packet->systemAddress==facilitatorSystemAddress) isConnectedToNATPunchthroughServer=false; } break; case ID_CONNECTION_LOST: { PushMessage(RakNet::RakString("Connection to ") + targetName + RakNet::RakString(" lost.")); if (packet->systemAddress==facilitatorSystemAddress) isConnectedToNATPunchthroughServer=false; } break; case ID_NO_FREE_INCOMING_CONNECTIONS: { PushMessage(RakNet::RakString("No free incoming connections to ") + targetName + RakNet::RakString(".")); if (packet->systemAddress==facilitatorSystemAddress) PushMessage("Multiplayer will not work without the NAT punchthrough server!"); } break; case ID_NEW_INCOMING_CONNECTION: { if (fullyConnectedMesh2->IsHostSystem()) { PushMessage(RakNet::RakString("Sending player list to new connection")); fullyConnectedMesh2->StartVerifiedJoin(packet->guid); } } break; case ID_FCM2_VERIFIED_JOIN_START: { DataStructures::List<RakNet::SystemAddress> addresses; DataStructures::List<RakNet::RakNetGUID> guids; fullyConnectedMesh2->GetVerifiedJoinRequiredProcessingList(packet->guid, addresses, guids); for (unsigned int i=0; i < guids.Size(); i++) natPunchthroughClient->OpenNAT(guids[i], facilitatorSystemAddress); } break; case ID_FCM2_VERIFIED_JOIN_FAILED: { PushMessage(RakNet::RakString("Failed to join game session")); } break; case ID_FCM2_VERIFIED_JOIN_CAPABLE: { fullyConnectedMesh2->RespondOnVerifiedJoinCapable(packet, true, 0); } break; case ID_FCM2_VERIFIED_JOIN_ACCEPTED: { DataStructures::List<RakNet::RakNetGUID> systemsAccepted; bool thisSystemAccepted; fullyConnectedMesh2->GetVerifiedJoinAcceptedAdditionalData(packet, &thisSystemAccepted, systemsAccepted, 0); if (thisSystemAccepted) PushMessage("Game join request accepted\n"); else PushMessage(RakNet::RakString("System %s joined the mesh\n", systemsAccepted[0].ToString())); // DataStructures::List<RakNetGUID> participantList; // fullyConnectedMesh2->GetParticipantList(participantList); for (unsigned int i=0; i < systemsAccepted.Size(); i++) replicaManager3->PushConnection(replicaManager3->AllocConnection(rakPeer->GetSystemAddressFromGuid(systemsAccepted[i]), systemsAccepted[i])); } break; case ID_CONNECTION_REQUEST_ACCEPTED: { PushMessage(RakNet::RakString("Connection request to ") + targetName + RakNet::RakString(" accepted.")); if (packet->systemAddress==facilitatorSystemAddress) { isConnectedToNATPunchthroughServer=true; // Open UPNP. struct UPNPDev * devlist = 0; devlist = upnpDiscover(1000, 0, 0, 0); if (devlist) { char lanaddr[64]; /* my ip address on the LAN */ struct UPNPUrls urls; struct IGDdatas data; if (UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))==1) { // External port is the port people will be connecting to us on. This is our port as seen by the directory server // Internal port is the port RakNet was internally started on char eport[32], iport[32]; natPunchthroughClient->GetUPNPPortMappings(eport, iport, facilitatorSystemAddress); int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, eport, iport, lanaddr, 0, "UDP", 0); if(r==UPNPCOMMAND_SUCCESS) { // UPNP done } } } // Query cloud for other running game instances RakNet::CloudQuery cloudQuery; cloudQuery.keys.Push(RakNet::CloudKey("IrrlichtDemo",0),_FILE_AND_LINE_); cloudClient->Get(&cloudQuery, packet->guid); } } break; case ID_FCM2_NEW_HOST: { if (packet->guid==rakPeer->GetMyGUID()) { // Original host dropped. I am the new session host. Upload to the cloud so new players join this system. RakNet::CloudKey cloudKey("IrrlichtDemo",0); cloudClient->Post(&cloudKey, 0, 0, rakPeer->GetGuidFromSystemAddress(facilitatorSystemAddress)); } } break; case ID_CLOUD_GET_RESPONSE: { RakNet::CloudQueryResult cloudQueryResult; cloudClient->OnGetReponse(&cloudQueryResult, packet); if (cloudQueryResult.rowsReturned.Size()>0) { PushMessage(RakNet::RakString("NAT punch to existing game instance")); natPunchthroughClient->OpenNAT(cloudQueryResult.rowsReturned[0]->clientGUID, facilitatorSystemAddress); } else { PushMessage(RakNet::RakString("Publishing new game instance")); // Start as a new game instance because no other games are running RakNet::CloudKey cloudKey("IrrlichtDemo",0); cloudClient->Post(&cloudKey, 0, 0, packet->guid); } cloudClient->DeallocateWithDefaultAllocator(&cloudQueryResult); } break; case ID_CONNECTION_ATTEMPT_FAILED: { PushMessage(RakNet::RakString("Connection attempt to ") + targetName + RakNet::RakString(" failed.")); if (packet->systemAddress==facilitatorSystemAddress) PushMessage("Multiplayer will not work without the NAT punchthrough server!"); } break; case ID_NAT_TARGET_NOT_CONNECTED: { RakNet::RakNetGUID recipientGuid; RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(sizeof(RakNet::MessageID)); bs.Read(recipientGuid); targetName=recipientGuid.ToString(); PushMessage(RakNet::RakString("NAT target ") + targetName + RakNet::RakString(" not connected.")); } break; case ID_NAT_TARGET_UNRESPONSIVE: { RakNet::RakNetGUID recipientGuid; RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(sizeof(RakNet::MessageID)); bs.Read(recipientGuid); targetName=recipientGuid.ToString(); PushMessage(RakNet::RakString("NAT target ") + targetName + RakNet::RakString(" unresponsive.")); } break; case ID_NAT_CONNECTION_TO_TARGET_LOST: { RakNet::RakNetGUID recipientGuid; RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(sizeof(RakNet::MessageID)); bs.Read(recipientGuid); targetName=recipientGuid.ToString(); PushMessage(RakNet::RakString("NAT target connection to ") + targetName + RakNet::RakString(" lost.")); } break; case ID_NAT_ALREADY_IN_PROGRESS: { RakNet::RakNetGUID recipientGuid; RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(sizeof(RakNet::MessageID)); bs.Read(recipientGuid); targetName=recipientGuid.ToString(); PushMessage(RakNet::RakString("NAT punchthrough to ") + targetName + RakNet::RakString(" in progress (skipping).")); } break; case ID_NAT_PUNCHTHROUGH_SUCCEEDED: { if (packet->data[1]==1) { PushMessage(RakNet::RakString("Connecting to existing game instance")); RakNet::ConnectionAttemptResult car = rakPeer->Connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort(), 0, 0); RakAssert(car==RakNet::CONNECTION_ATTEMPT_STARTED); } } break; case ID_ADVERTISE_SYSTEM: if (packet->guid!=rakPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS)) { char hostIP[32]; packet->systemAddress.ToString(false,hostIP); RakNet::ConnectionAttemptResult car = rakPeer->Connect(hostIP,packet->systemAddress.GetPort(),0,0); RakAssert(car==RakNet::CONNECTION_ATTEMPT_STARTED); } break; } } // Call the Update function for networked game objects added to BaseIrrlichtReplica once the game is ready if (currentScene>=1) { unsigned int idx; for (idx=0; idx < replicaManager3->GetReplicaCount(); idx++) ((BaseIrrlichtReplica*)(replicaManager3->GetReplicaAtIndex(idx)))->Update(curTime);; } }
int main(void) { PortAudioStream *stream; PaError err; mute=false; bool quit; char ch; printf("A sample on how to use RakVoice. You need a microphone for this sample.\n"); printf("RakVoice relies on Speex for voice encoding and decoding.\n"); printf("See DependentExtensions/RakVoice/speex-1.1.12 for speex projects.\n"); printf("For windows, I had to define HAVE_CONFIG_H, include win32/config.h,\n"); printf("and include the files under libspeex, except those that start with test.\n"); printf("PortAudio is also included and is used to read and write audio data. You\n"); printf("can substitute whatever you want if you do not want to use portaudio.\n"); printf("Difficulty: Advanced\n\n"); // Since voice is peer to peer, we give the option to use the nat punchthrough client if desired. RakNet::NatPunchthroughClient natPunchthroughClient; char port[256]; rakPeer = RakNet::RakPeerInterface::GetInstance(); printf("Enter local port (enter for default): "); Gets(port, sizeof(port)); if (port[0]==0) strcpy(port, "60000"); RakNet::SocketDescriptor socketDescriptor(atoi(port),0); rakPeer->Startup(4, &socketDescriptor, 1); rakPeer->SetMaximumIncomingConnections(4); rakPeer->AttachPlugin(&rakVoice); rakPeer->AttachPlugin(&natPunchthroughClient); rakVoice.Init(SAMPLE_RATE, FRAMES_PER_BUFFER*sizeof(SAMPLE)); err = Pa_Initialize(); if( err != paNoError ) goto error; err = Pa_OpenStream( &stream, Pa_GetDefaultInputDeviceID(), 1, // Num channels, whatever that means PA_SAMPLE_TYPE, NULL, Pa_GetDefaultOutputDeviceID(), 1, // Num channels PA_SAMPLE_TYPE, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ 0, /* paDitherOff, // flags */ PACallback, 0 ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Support NAT punchthrough? (y/n)? "); bool useNatPunchthrough; useNatPunchthrough=(getche()=='y'); printf("\n"); char facilitatorIP[256]; {//Linux fix. Won't compile without it. Because of the goto error above, the scope is ambigious. Make it a block to define that it will not be used after the jump. //Doesn't change current logic RakNet::SystemAddress facilitator; if (useNatPunchthrough) { printf("My GUID is %s\n", rakPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString()); printf("Enter IP of facilitator (enter for default): "); Gets(facilitatorIP,sizeof(facilitatorIP)); if (facilitatorIP[0]==0) strcpy(facilitatorIP, "natpunch.jenkinssoftware.com"); facilitator.FromString(facilitatorIP); facilitator.SetPortHostOrder(NAT_PUNCHTHROUGH_FACILITATOR_PORT); rakPeer->Connect(facilitatorIP, NAT_PUNCHTHROUGH_FACILITATOR_PORT, 0, 0); printf("Connecting to facilitator...\n"); } else { printf("Not supporting NAT punchthrough.\n"); } RakNet::Packet *p; quit=false; if (useNatPunchthrough==false) printf("(Q)uit. (C)onnect. (D)isconnect. C(l)ose voice channels. (M)ute. ' ' for stats.\n"); while (!quit) { if (kbhit()) { ch=getch(); if (ch=='y') { quit=true; } else if (ch=='c') { if (useNatPunchthrough) { RakNet::RakNetGUID destination; printf("Enter GUID of destination: "); char guidStr[256]; while (1) { Gets(guidStr,sizeof(guidStr)); if (!destination.FromString(guidStr)) printf("Invalid GUID format. Try again.\nEnter GUID of destination: "); else break; } printf("Starting NAT punch. Please wait...\n"); natPunchthroughClient.OpenNAT(destination,facilitator); } else { char ip[256]; printf("Enter IP of remote system: "); Gets(ip, sizeof(ip)); if (ip[0]==0) strcpy(ip, "127.0.0.1"); printf("Enter port of remote system: "); Gets(port, sizeof(port)); if (port[0]==0) strcpy(port, "60000"); rakPeer->Connect(ip, atoi(port), 0,0); } } else if (ch=='m') { mute=!mute; if (mute) printf("Now muted.\n"); else printf("No longer muted.\n"); } else if (ch=='d') { rakPeer->Shutdown(100,0); } else if (ch=='l') { rakVoice.CloseAllChannels(); } else if (ch==' ') { char message[2048]; RakNet::RakNetStatistics *rss=rakPeer->GetStatistics(rakPeer->GetSystemAddressFromIndex(0)); StatisticsToString(rss, message, 2); printf("%s", message); } else if (ch=='q') quit=true; ch=0; } p=rakPeer->Receive(); while (p) { if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { if (p->systemAddress==facilitator) { printf("Connection to facilitator completed\n"); printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n"); } else { printf("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", p->systemAddress.ToString()); rakVoice.RequestVoiceChannel(p->guid); } } else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED) { if (p->systemAddress==facilitator) { printf("Connection to facilitator failed. Using direct connections\n"); useNatPunchthrough=false; printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n"); } else { printf("ID_CONNECTION_ATTEMPT_FAILED\n"); } } else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REQUEST || p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REPLY) { printf("Got new channel from %s\n", p->systemAddress.ToString()); } else if (p->data[0]==ID_NAT_TARGET_NOT_CONNECTED) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_TARGET_NOT_CONNECTED for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_TARGET_UNRESPONSIVE) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_TARGET_UNRESPONSIVE for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_CONNECTION_TO_TARGET_LOST for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_ALREADY_IN_PROGRESS) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_ALREADY_IN_PROGRESS for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_PUNCHTHROUGH_FAILED) { printf("ID_NAT_PUNCHTHROUGH_FAILED for %s\n", p->guid.ToString()); } else if (p->data[0]==ID_NAT_PUNCHTHROUGH_SUCCEEDED) { printf("ID_NAT_PUNCHTHROUGH_SUCCEEDED for %s. Connecting...\n", p->guid.ToString()); rakPeer->Connect(p->systemAddress.ToString(false),p->systemAddress.GetPort(),0,0); } else if (p->data[0]==ID_ALREADY_CONNECTED) { printf("ID_ALREADY_CONNECTED\n"); } else if (p->data[0]==ID_RAKVOICE_CLOSE_CHANNEL) { printf("ID_RAKVOICE_CLOSE_CHANNEL\n"); } else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION) { printf("ID_DISCONNECTION_NOTIFICATION\n"); } else if (p->data[0]==ID_NEW_INCOMING_CONNECTION) { printf("ID_NEW_INCOMING_CONNECTION\n"); } else { printf("Unknown packet ID %i\n", p->data[0]); } rakPeer->DeallocatePacket(p); p=rakPeer->Receive(); } Pa_Sleep( 30 ); } } err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); rakPeer->Shutdown(300); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; error: Pa_Terminate(); fprintf( stderr, "An error occured while using the portaudio stream\n" ); fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); return -1; }