Exemple #1
0
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();
}
Exemple #5
0
/// 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);;
	}	
}
Exemple #6
0
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;
}