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. NatPunchthroughClient natPunchthroughClient; char port[256]; rakPeer = RakNetworkFactory::GetRakPeerInterface(); printf("Enter local port (enter for default): "); gets(port); if (port[0]==0) strcpy(port, "60000"); SocketDescriptor socketDescriptor(atoi(port),0); rakPeer->Startup(4, 30, &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 SystemAddress facilitator; if (useNatPunchthrough) { printf("My GUID is %s\n", rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS).ToString()); printf("Enter IP of facilitator (enter for default): "); gets(facilitatorIP); if (facilitatorIP[0]==0) strcpy(facilitatorIP, "94.198.81.195"); facilitator.SetBinaryAddress(facilitatorIP); facilitator.port=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"); } 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) { RakNetGUID destination; printf("Enter GUID of destination: "); char guidStr[256]; while (1) { gets(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); if (ip[0]==0) strcpy(ip, "127.0.0.1"); printf("Enter port of remote system: "); gets(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]; 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) { 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) { 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) { 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) { 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.port,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); RakNetworkFactory::DestroyRakPeerInterface(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; }
_CONSOLE_2_SetSystemProcessParams #endif int main(void) { // Pointers to the interfaces of our server and client. // Note we can easily have both in the same program RakPeerInterface *server=RakNetworkFactory::GetRakPeerInterface(); RakNetStatistics *rss; //server->InitializeSecurity(0,0,0,0); int i = server->GetNumberOfAddresses(); server->SetIncomingPassword("Rumpelstiltskin", (int)strlen("Rumpelstiltskin")); // Holds packets Packet* p; // GetPacketIdentifier returns this unsigned char packetIdentifier; // Record the first client that connects to us so we can pass it to the ping function SystemAddress clientID=UNASSIGNED_SYSTEM_ADDRESS; // Holds user data char portstring[30]; printf("This is a sample implementation of a text based chat server.\n"); printf("Connect to the project 'Chat Example Client'.\n"); printf("Difficulty: Beginner\n\n"); // A server // puts("Enter the server port to listen on"); // gets(portstring); // if (portstring[0]==0) strcpy(portstring, "10000"); puts("Starting server."); // Starting the server is very simple. 2 players allowed. // 0 means we don't care about a connectionValidationInteger, and false // for low priority threads SocketDescriptor socketDescriptor(atoi(portstring),0); bool b = server->Startup(32, 30, &socketDescriptor, 1 ); server->SetMaximumIncomingConnections(2); if (b) puts("Server started, waiting for connections."); else { puts("Server failed to start. Terminating."); exit(1); } server->SetOccasionalPing(true); printf("My IP is %s\n", server->GetLocalIP(0)); puts("'quit' to quit. 'stat' to show stats. 'ping' to ping.\n'ban' to ban an IP from connecting.\n'kick to kick the first connected player.\nType to talk."); char message[2048]; // Loop for input while (1) { // This sleep keeps RakNet responsive RakSleep(30); #ifdef _WIN32 if (kbhit()) { // Notice what is not here: something to keep our network running. It's // fine to block on gets or anything we want // Because the network engine was painstakingly written using threads. gets(message); if (strcmp(message, "quit")==0) { puts("Quitting."); break; } if (strcmp(message, "stat")==0) { rss=server->GetStatistics(server->GetSystemAddressFromIndex(0)); StatisticsToString(rss, message, 2); printf("%s", message); printf("Ping %i\n", server->GetAveragePing(server->GetSystemAddressFromIndex(0))); continue; } if (strcmp(message, "ping")==0) { server->Ping(clientID); continue; } if (strcmp(message, "kick")==0) { server->CloseConnection(clientID, true, 0); continue; } if (strcmp(message, "ban")==0) { printf("Enter IP to ban. You can use * as a wildcard\n"); gets(message); server->AddToBanList(message); printf("IP %s added to ban list.\n", message); continue; } // Message now holds what we want to broadcast char message2[420]; // Append Server: to the message so clients know that it ORIGINATED from the server // All messages to all clients come from the server either directly or by being // relayed from other clients message2[0]=0; strcpy(message2, "Server: "); strcat(message2, message); // message2 is the data to send // strlen(message2)+1 is to send the null terminator // HIGH_PRIORITY doesn't actually matter here because we don't use any other priority // RELIABLE_ORDERED means make sure the message arrives in the right order // We arbitrarily pick 0 for the ordering stream // UNASSIGNED_SYSTEM_ADDRESS means don't exclude anyone from the broadcast // true means broadcast the message to everyone connected server->Send(message2, (const int) strlen(message2)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true); } #endif // Get a packet from either the server or the client p = server->Receive(); if (p==0) continue; // Didn't get any packets // We got a packet, get the identifier with our handy function packetIdentifier = GetPacketIdentifier(p); // Check if this is a network message packet switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION\n"); break; case ID_NEW_INCOMING_CONNECTION: // Somebody connected. We have their IP now printf("ID_NEW_INCOMING_CONNECTION from %s\n", p->systemAddress.ToString()); clientID=p->systemAddress; // Record the player ID of the client break; case ID_MODIFIED_PACKET: // Cheater! printf("ID_MODIFIED_PACKET\n"); break; case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated printf("ID_CONNECTION_LOST\n"); break; default: // The server knows the static data of all clients, so we can prefix the message // With the name data printf("%s\n", p->data); // Relay the message. We prefix the name for other clients. This demonstrates // That messages can be changed on the server before being broadcast // Sending is the same as before sprintf(message, "%s", p->data); server->Send(message, (const int) strlen(message)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); break; } // We're done with the packet server->DeallocatePacket(p); } server->Shutdown(300); // We're done with the network RakNetworkFactory::DestroyRakPeerInterface(server); return 0; }
int main(void) { FMOD_RESULT result; unsigned int version; /* Create a System object and initialize. */ result = FMOD::System_Create(&fmodSystem); RakAssert(result>=0); result = fmodSystem->getVersion(&version); RakAssert(result>=0); if (version < FMOD_VERSION) { printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION); return -1; } // result = fmodSystem->init(100, FMOD_INIT_NORMAL, (void *)&extradriverdata); result = fmodSystem->init(100, FMOD_INIT_NORMAL, 0); RakAssert(result>=0); // ERRCHECK(result); 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("Difficulty: Advanced\n\n"); mute=false; bool quit; char ch; char port[256]; rakPeer = RakNet::RakPeerInterface::GetInstance(); #if defined(INTERACTIVE) printf("Enter local port: "); Gets(port, sizeof(port)); if (port[0]==0) #endif strcpy(port, "60000"); RakNet::SocketDescriptor socketDescriptor(atoi(port),0); rakPeer->Startup(4, &socketDescriptor, 1); rakPeer->SetMaximumIncomingConnections(4); rakPeer->AttachPlugin(&rakVoice); rakVoice.Init(SAMPLE_RATE, FRAMES_PER_BUFFER*sizeof(SAMPLE)); // Initialize our connection with FMOD if (!RakNet::FMODVoiceAdapter::Instance()->SetupAdapter(fmodSystem, &rakVoice)){ printf("An error occurred while initializing FMOD sounds.\n"); exit(-1); } RakNet::Packet *p; quit=false; #if defined(INTERACTIVE) printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n"); printf("(+/-)encoder complexity. (N)oise filter on/off. (V)AD on/off. (B)vbr on/off.\n"); #else rakPeer->Connect("1.1.1.1", 60000, 0,0); #endif PrintParameters(); while (!quit) { #if defined(INTERACTIVE) if (kbhit()) { ch=getch(); if (ch=='+'){ // Increase encoder complexity int v = rakVoice.GetEncoderComplexity(); if (v<10) rakVoice.SetEncoderComplexity(v+1); PrintParameters(); } else if (ch=='-'){ // Decrease encoder complexity int v = rakVoice.GetEncoderComplexity(); if (v>0) rakVoice.SetEncoderComplexity(v-1); PrintParameters(); } else if (ch=='n'){ // Turn on/off noise filter rakVoice.SetNoiseFilter(!rakVoice.IsNoiseFilterActive()); PrintParameters(); } else if (ch=='v') { // Turn on/off Voice detection rakVoice.SetVAD(!rakVoice.IsVADActive()); PrintParameters(); } else if (ch=='b') { // Turn on/off VBR rakVoice.SetVBR(!rakVoice.IsVBRActive()); PrintParameters(); } else if (ch=='y') { quit=true; } else if (ch=='c') { char ip[256]; printf("\nEnter IP of remote system: "); Gets(ip, sizeof(ip)); if (ip[0]==0) strcpy(ip, "127.0.0.1"); printf("\nEnter 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; RakNet::FMODVoiceAdapter::Instance()->SetMute(mute); if (mute) printf("\nNow muted.\n"); else printf("\nNo longer muted.\n"); } else if (ch=='d') { rakPeer->Shutdown(100,0); } 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; } #endif p=rakPeer->Receive(); while (p) { if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { printf("\nID_CONNECTION_REQUEST_ACCEPTED from %s\n", p->systemAddress.ToString()); rakVoice.RequestVoiceChannel(p->guid); } else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REQUEST) { printf("\nOpen Channel request from %s\n", p->systemAddress.ToString()); } else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REPLY) { printf("\nGot new channel from %s\n", p->systemAddress.ToString()); } rakPeer->DeallocatePacket(p); p=rakPeer->Receive(); } fmodSystem->update(); // Update or connection with FMOD RakNet::FMODVoiceAdapter::Instance()->Update(); // LogStats(); RakSleep(20); } // Release any FMOD resources we used, and shutdown FMOD itself RakNet::FMODVoiceAdapter::Instance()->Release(); fmodSystem->release(); rakPeer->Shutdown(300); rakPeer->DetachPlugin(&rakVoice); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; }
_CONSOLE_2_SetSystemProcessParams #endif int main(void) { // Pointers to the interfaces of our server and client. // Note we can easily have both in the same program RakNet::RakPeerInterface *server=RakNet::RakPeerInterface::GetInstance(); RakNet::RakNetStatistics *rss; server->SetIncomingPassword("Rumpelstiltskin", (int)strlen("Rumpelstiltskin")); server->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS); // RakNet::PacketLogger packetLogger; // server->AttachPlugin(&packetLogger); #if LIBCAT_SECURITY==1 cat::EasyHandshake handshake; char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES]; char private_key[cat::EasyHandshake::PRIVATE_KEY_BYTES]; handshake.GenerateServerKey(public_key, private_key); server->InitializeSecurity(public_key, private_key, false); FILE *fp = fopen("publicKey.dat","wb"); fwrite(public_key,sizeof(public_key),1,fp); fclose(fp); #endif // Holds packets RakNet::Packet* p; // GetPacketIdentifier returns this unsigned char packetIdentifier; // Record the first client that connects to us so we can pass it to the ping function RakNet::SystemAddress clientID=RakNet::UNASSIGNED_SYSTEM_ADDRESS; // Holds user data char portstring[30]; printf("This is a sample implementation of a text based chat server.\n"); printf("Connect to the project 'Chat Example Client'.\n"); printf("Difficulty: Beginner\n\n"); // A server puts("Enter the server port to listen on"); Gets(portstring,sizeof(portstring)); if (portstring[0]==0) strcpy(portstring, "1234"); puts("Starting server."); // Starting the server is very simple. 2 players allowed. // 0 means we don't care about a connectionValidationInteger, and false // for low priority threads // I am creating two socketDesciptors, to create two sockets. One using IPV6 and the other IPV4 RakNet::SocketDescriptor socketDescriptors[2]; socketDescriptors[0].port=atoi(portstring); socketDescriptors[0].socketFamily=AF_INET; // Test out IPV4 socketDescriptors[1].port=atoi(portstring); socketDescriptors[1].socketFamily=AF_INET6; // Test out IPV6 bool b = server->Startup(4, socketDescriptors, 2 )==RakNet::RAKNET_STARTED; server->SetMaximumIncomingConnections(4); if (!b) { printf("Failed to start dual IPV4 and IPV6 ports. Trying IPV4 only.\n"); // Try again, but leave out IPV6 b = server->Startup(4, socketDescriptors, 1 )==RakNet::RAKNET_STARTED; if (!b) { puts("Server failed to start. Terminating."); exit(1); } } server->SetOccasionalPing(true); server->SetUnreliableTimeout(1000); DataStructures::List< RakNet::RakNetSocket2* > sockets; server->GetSockets(sockets); printf("Socket addresses used by RakNet:\n"); for (unsigned int i=0; i < sockets.Size(); i++) { printf("%i. %s\n", i+1, sockets[i]->GetBoundAddress().ToString(true)); } printf("\nMy IP addresses:\n"); for (unsigned int i=0; i < server->GetNumberOfAddresses(); i++) { RakNet::SystemAddress sa = server->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS, i); printf("%i. %s (LAN=%i)\n", i+1, sa.ToString(false), sa.IsLANAddress()); } printf("\nMy GUID is %s\n", server->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString()); puts("'quit' to quit. 'stat' to show stats. 'ping' to ping.\n'pingip' to ping an ip address\n'ban' to ban an IP from connecting.\n'kick to kick the first connected player.\nType to talk."); char message[2048]; // Loop for input while (1) { // This sleep keeps RakNet responsive RakSleep(30); if (kbhit()) { // Notice what is not here: something to keep our network running. It's // fine to block on gets or anything we want // Because the network engine was painstakingly written using threads. Gets(message,sizeof(message)); if (strcmp(message, "quit")==0) { puts("Quitting."); break; } if (strcmp(message, "stat")==0) { rss=server->GetStatistics(server->GetSystemAddressFromIndex(0)); StatisticsToString(rss, message, 2); printf("%s", message); printf("Ping %i\n", server->GetAveragePing(server->GetSystemAddressFromIndex(0))); continue; } if (strcmp(message, "ping")==0) { server->Ping(clientID); continue; } if (strcmp(message, "pingip")==0) { printf("Enter IP: "); Gets(message,sizeof(message)); printf("Enter port: "); Gets(portstring,sizeof(portstring)); if (portstring[0]==0) strcpy(portstring, "1234"); server->Ping(message, atoi(portstring), false); continue; } if (strcmp(message, "kick")==0) { server->CloseConnection(clientID, true, 0); continue; } if (strcmp(message, "getconnectionlist")==0) { RakNet::SystemAddress systems[10]; unsigned short numConnections=10; server->GetConnectionList((RakNet::SystemAddress*) &systems, &numConnections); for (int i=0; i < numConnections; i++) { printf("%i. %s\n", i+1, systems[i].ToString(true)); } continue; } if (strcmp(message, "ban")==0) { printf("Enter IP to ban. You can use * as a wildcard\n"); Gets(message,sizeof(message)); server->AddToBanList(message); printf("IP %s added to ban list.\n", message); continue; } // Message now holds what we want to broadcast char message2[2048]; // Append Server: to the message so clients know that it ORIGINATED from the server // All messages to all clients come from the server either directly or by being // relayed from other clients message2[0]=0; const static char prefix[] = "Server: "; strncpy(message2, prefix, sizeof(message2)); strncat(message2, message, sizeof(message2) - strlen(prefix) - 1); // message2 is the data to send // strlen(message2)+1 is to send the null terminator // HIGH_PRIORITY doesn't actually matter here because we don't use any other priority // RELIABLE_ORDERED means make sure the message arrives in the right order // We arbitrarily pick 0 for the ordering stream // RakNet::UNASSIGNED_SYSTEM_ADDRESS means don't exclude anyone from the broadcast // true means broadcast the message to everyone connected server->Send(message2, (const int) strlen(message2)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } // Get a packet from either the server or the client for (p=server->Receive(); p; server->DeallocatePacket(p), p=server->Receive()) { // We got a packet, get the identifier with our handy function packetIdentifier = GetPacketIdentifier(p); // Check if this is a network message packet switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));; 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()); clientID=p->systemAddress; // Record the player ID of the client printf("Remote internal IDs:\n"); for (int index=0; index < MAXIMUM_NUMBER_OF_INTERNAL_IDS; index++) { RakNet::SystemAddress internalId = server->GetInternalID(p->systemAddress, index); if (internalId!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("%i. %s\n", index+1, internalId.ToString(true)); } } break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_CONNECTED_PING: case ID_UNCONNECTED_PING: printf("Ping from %s\n", p->systemAddress.ToString(true)); break; case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated printf("ID_CONNECTION_LOST from %s\n", p->systemAddress.ToString(true));; break; default: // The server knows the static data of all clients, so we can prefix the message // With the name data printf("%s\n", p->data); // Relay the message. We prefix the name for other clients. This demonstrates // That messages can be changed on the server before being broadcast // Sending is the same as before sprintf(message, "%s", p->data); server->Send(message, (const int) strlen(message)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); break; } } } server->Shutdown(300); // We're done with the network RakNet::RakPeerInterface::DestroyInstance(server); return 0; }
int main(void) { RakNet::RakNetStatistics *rss; // Pointers to the interfaces of our server and client. // Note we can easily have both in the same program RakNet::RakPeerInterface *client=RakNet::RakPeerInterface::GetInstance(); // client->InitializeSecurity(0,0,0,0); //RakNet::PacketLogger packetLogger; //client->AttachPlugin(&packetLogger); // Holds packets RakNet::Packet* p; // GetPacketIdentifier returns this unsigned char packetIdentifier; // Just so we can remember where the packet came from bool isServer; // Record the first client that connects to us so we can pass it to the ping function RakNet::SystemAddress clientID=RakNet::UNASSIGNED_SYSTEM_ADDRESS; // Crude interface // Holds user data char ip[64], serverPort[30], clientPort[30]; // A client isServer=false; printf("This is a sample implementation of a text based chat client.\n"); printf("Connect to the project 'Chat Example Server'.\n"); printf("Difficulty: Beginner\n\n"); // Get our input puts("Enter the client port to listen on"); Gets(clientPort,sizeof(clientPort)); if (clientPort[0]==0) strcpy(clientPort, "0"); puts("Enter IP to connect to"); Gets(ip, sizeof(ip)); client->AllowConnectionResponseIPMigration(false); if (ip[0]==0) strcpy(ip, "127.0.0.1"); // strcpy(ip, "natpunch.jenkinssoftware.com"); puts("Enter the port to connect to"); Gets(serverPort,sizeof(serverPort)); if (serverPort[0]==0) strcpy(serverPort, "1234"); // Connecting the client is very simple. 0 means we don't care about // a connectionValidationInteger, and false for low priority threads RakNet::SocketDescriptor socketDescriptor(atoi(clientPort),0); socketDescriptor.socketFamily=AF_INET; client->Startup(8,&socketDescriptor, 1); client->SetOccasionalPing(true); #if LIBCAT_SECURITY==1 char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES]; FILE *fp = fopen("publicKey.dat","rb"); fread(public_key,sizeof(public_key),1,fp); fclose(fp); #endif #if LIBCAT_SECURITY==1 RakNet::PublicKey pk; pk.remoteServerPublicKey=public_key; pk.publicKeyMode=RakNet::PKM_USE_KNOWN_PUBLIC_KEY; bool b = client->Connect(ip, atoi(serverPort), "Rumpelstiltskin", (int) strlen("Rumpelstiltskin"), &pk)==RakNet::CONNECTION_ATTEMPT_STARTED; #else RakNet::ConnectionAttemptResult car = client->Connect(ip, atoi(serverPort), "Rumpelstiltskin", (int) strlen("Rumpelstiltskin")); RakAssert(car==RakNet::CONNECTION_ATTEMPT_STARTED); #endif printf("\nMy IP addresses:\n"); unsigned int i; for (i=0; i < client->GetNumberOfAddresses(); i++) { printf("%i. %s\n", i+1, client->GetLocalIP(i)); } printf("My GUID is %s\n", client->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString()); puts("'quit' to quit. 'stat' to show stats. 'ping' to ping.\n'disconnect' to disconnect. 'connect' to reconnnect. Type to talk."); char message[2048]; // Loop for input while (1) { // This sleep keeps RakNet responsive #ifdef _WIN32 Sleep(30); #else usleep(30 * 1000); #endif if (kbhit()) { // Notice what is not here: something to keep our network running. It's // fine to block on Gets or anything we want // Because the network engine was painstakingly written using threads. Gets(message,sizeof(message)); if (strcmp(message, "quit")==0) { puts("Quitting."); break; } if (strcmp(message, "stat")==0) { rss=client->GetStatistics(client->GetSystemAddressFromIndex(0)); StatisticsToString(rss, message, 2); printf("%s", message); printf("Ping=%i\n", client->GetAveragePing(client->GetSystemAddressFromIndex(0))); continue; } if (strcmp(message, "disconnect")==0) { printf("Enter index to disconnect: "); char str[32]; Gets(str, sizeof(str)); if (str[0]==0) strcpy(str,"0"); int index = atoi(str); client->CloseConnection(client->GetSystemAddressFromIndex(index),false); printf("Disconnecting.\n"); continue; } if (strcmp(message, "shutdown")==0) { client->Shutdown(100); printf("Shutdown.\n"); continue; } if (strcmp(message, "startup")==0) { bool b = client->Startup(8,&socketDescriptor, 1)==RakNet::RAKNET_STARTED; if (b) printf("Started.\n"); else printf("Startup failed.\n"); continue; } if (strcmp(message, "connect")==0) { printf("Enter server ip: "); Gets(ip, sizeof(ip)); if (ip[0]==0) strcpy(ip, "127.0.0.1"); printf("Enter server port: "); Gets(serverPort,sizeof(serverPort)); if (serverPort[0]==0) strcpy(serverPort, "1234"); #if LIBCAT_SECURITY==1 bool b = client->Connect(ip, atoi(serverPort), "Rumpelstiltskin", (int) strlen("Rumpelstiltskin"), &pk)==RakNet::CONNECTION_ATTEMPT_STARTED; #else bool b = client->Connect(ip, atoi(serverPort), "Rumpelstiltskin", (int) strlen("Rumpelstiltskin"))==RakNet::CONNECTION_ATTEMPT_STARTED; #endif if (b) puts("Attempting connection"); else { puts("Bad connection attempt. Terminating."); exit(1); } continue; } if (strcmp(message, "ping")==0) { if (client->GetSystemAddressFromIndex(0)!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) client->Ping(client->GetSystemAddressFromIndex(0)); continue; } if (strcmp(message, "getlastping")==0) { if (client->GetSystemAddressFromIndex(0)!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) printf("Last ping is %i\n", client->GetLastPing(client->GetSystemAddressFromIndex(0))); continue; } /* // message is the data to send // strlen(message)+1 is to send the null terminator // HIGH_PRIORITY doesn't actually matter here because we don't use any other priority // RELIABLE_ORDERED means make sure the message arrives in the right order client->Send(message, (int) strlen(message)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); */ /* //给主机发送数据 RakNet::BitStream bsOut; bsOut.Write((RakNet::MessageID)(ID_USER_PACKET_ENUM)); bsOut.Write((unsigned int)1); struct temp{ int a; int b; char c[50]; }; temp t = {0}; t.a = 1; t.b = 2; //t.c = "O(∩_∩)O哈哈~hello!"; strcpy(t.c, "O(∩_∩)O哈哈~hello!"); bsOut.WriteBits((unsigned char*)&t, 8 * sizeof temp); client->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,RakNet::UNASSIGNED_SYSTEM_ADDRESS,true); */ /* struct temp{ int a; int b; char c[50]; }; temp t = {0}; t.a = 1; t.b = 2; //t.c = "O(∩_∩)O哈哈~hello!"; strcpy(t.c, "O(∩_∩)O哈哈~hello!"); char * pBuffer = new char[sizeof(RakNet::MessageID) + sizeof(unsigned int) + sizeof(t)]; pBuffer[0] = (RakNet::MessageID)(ID_USER_PACKET_ENUM); *((unsigned int *)(pBuffer + 1)) = 1; memcpy(pBuffer + sizeof(RakNet::MessageID) + sizeof(unsigned int), &t, sizeof(t) ); //bsOut.WriteBits((unsigned char*)&t, 8 * sizeof temp); client->Send(pBuffer, sizeof(RakNet::MessageID) + sizeof(unsigned int) + sizeof(t), HIGH_PRIORITY,RELIABLE_ORDERED,0,RakNet::UNASSIGNED_SYSTEM_ADDRESS,true); delete[] pBuffer; */ /* Person person; person.set_id(8888); person.set_name("Kobe"); person.set_email("*****@*****.**"); int len = person.ByteSize(); char *buffer = new char[sizeof(RakNet::MessageID) + sizeof(unsigned int) + len]; buffer[0] = (RakNet::MessageID)(ID_USER_PACKET_ENUM); *((unsigned int *)(buffer + 1)) = 1; person.SerializeToArray(buffer + sizeof(RakNet::MessageID) + sizeof(unsigned int), len); Person p2; p2.ParseFromArray(buffer + sizeof(RakNet::MessageID) + sizeof(unsigned int), len); */ GS_C_Register_Or_Login st; st.set_account("test"); st.set_password("123456"); st.set_partner(1); st.set_type(1); int len = st.ByteSize(); char *buffer = new char[sizeof(RakNet::MessageID) + sizeof(unsigned int) + len]; buffer[0] = (RakNet::MessageID)(ID_USER_PACKET_ENUM); *((unsigned int *)(buffer + 1)) = 1; st.SerializeToArray(buffer + sizeof(RakNet::MessageID) + sizeof(unsigned int), len); client->Send(buffer, sizeof(RakNet::MessageID) + sizeof(unsigned int) + len, HIGH_PRIORITY,RELIABLE_ORDERED,0,RakNet::UNASSIGNED_SYSTEM_ADDRESS,true); delete[] buffer; } // Get a packet from either the server or the client for (p=client->Receive(); p; client->DeallocatePacket(p), p=client->Receive()) { // We got a packet, get the identifier with our handy function packetIdentifier = GetPacketIdentifier(p); // Check if this is a network message packet switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION\n"); break; case ID_ALREADY_CONNECTED: // Connection lost normally printf("ID_ALREADY_CONNECTED with guid %" PRINTF_64_BIT_MODIFIER "u\n", p->guid); break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_REMOTE_DISCONNECTION_NOTIFICATION: // Server telling the clients of another client disconnecting gracefully. You can manually broadcast this in a peer to peer enviroment if you want. printf("ID_REMOTE_DISCONNECTION_NOTIFICATION\n"); break; case ID_REMOTE_CONNECTION_LOST: // Server telling the clients of another client disconnecting forcefully. You can manually broadcast this in a peer to peer enviroment if you want. printf("ID_REMOTE_CONNECTION_LOST\n"); break; case ID_REMOTE_NEW_INCOMING_CONNECTION: // Server telling the clients of another client connecting. You can manually broadcast this in a peer to peer enviroment if you want. printf("ID_REMOTE_NEW_INCOMING_CONNECTION\n"); break; case ID_CONNECTION_BANNED: // Banned from this server printf("We are banned from this server.\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: printf("Connection attempt failed\n"); break; case ID_NO_FREE_INCOMING_CONNECTIONS: // Sorry, the server is full. I don't do anything here but // A real app should tell the user printf("ID_NO_FREE_INCOMING_CONNECTIONS\n"); break; case ID_INVALID_PASSWORD: printf("ID_INVALID_PASSWORD\n"); break; case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated printf("ID_CONNECTION_LOST\n"); break; case ID_CONNECTION_REQUEST_ACCEPTED: // This tells the client they have connected printf("ID_CONNECTION_REQUEST_ACCEPTED to %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); printf("My external address is %s\n", client->GetExternalID(p->systemAddress).ToString(true)); break; case ID_CONNECTED_PING: case ID_UNCONNECTED_PING: printf("Ping from %s\n", p->systemAddress.ToString(true)); break; default: /* // It's a client, so just show the message printf("%s\n", p->data); */ RakNet::RakString rs; RakNet::BitStream bsIn( p->data, p->length, false ); bsIn.IgnoreBytes(sizeof(RakNet::MessageID));//系统消息域 bsIn.IgnoreBytes(sizeof(unsigned int));//游戏消息ID bsIn.Read(rs); //提取字符串 //std::istringstream input_str(rs.C_String()); //存入字符串流 //std::string timeStr; //input_str >> timeStr; //提取想要的变量 printf("%s say : %s \r\n", p->systemAddress.ToString(), rs.C_String()); break; } } } // Be nice and let the server know we quit. client->Shutdown(300); // We're done with the network RakNet::RakPeerInterface::DestroyInstance(client); return 0; }
int ReliableOrderedConvertedTest::RunTest(DataStructures::List<RakNet::RakString> params,bool isVerbose,bool noPauses) { RakPeerInterface *sender, *receiver; unsigned int packetNumberSender[32],packetNumberReceiver[32], receivedPacketNumberReceiver, receivedTimeReceiver; char str[256]; char ip[32]; RakNetTime sendInterval, nextSend, currentTime, quitTime; unsigned short remotePort, localPort; unsigned char streamNumberSender,streamNumberReceiver; RakNet::BitStream bitStream; Packet *packet; bool doSend=false; for (int i=0; i < 32; i++) { packetNumberSender[i]=0; packetNumberReceiver[i]=0; } /* if (argc==2) { fp = fopen(argv[1],"wt"); SetMalloc_Ex(LoggedMalloc); SetRealloc_Ex(LoggedRealloc); SetFree_Ex(LoggedFree); } else */ fp=0; destroyList.Clear(false,__FILE__,__LINE__); sender =RakNetworkFactory::GetRakPeerInterface(); destroyList.Push( sender ,__FILE__,__LINE__); //sender->ApplyNetworkSimulator(.02, 100, 50); /* if (str[0]==0) sendInterval=30; else sendInterval=atoi(str);*///possible future params sendInterval=30; /* printf("Enter remote IP: "); gets(ip); if (ip[0]==0)*/ strcpy(ip, "127.0.0.1"); /* printf("Enter remote port: "); gets(str); if (str[0]==0)*/ strcpy(str, "60000"); remotePort=atoi(str); /* printf("Enter local port: "); gets(str); if (str[0]==0)*/ strcpy(str, "0"); localPort=atoi(str); if (isVerbose) printf("Connecting...\n"); SocketDescriptor tmp(localPort,0); sender->Startup(1, 30, &tmp, 1); sender->Connect(ip, remotePort, 0, 0); receiver =RakNetworkFactory::GetRakPeerInterface(); destroyList.Push( receiver ,__FILE__,__LINE__); /* printf("Enter local port: "); gets(str); if (str[0]==0)*/ strcpy(str, "60000"); localPort=atoi(str); if (isVerbose) printf("Waiting for connections...\n"); SocketDescriptor tmp2(localPort,0); receiver->Startup(32, 30, &tmp2, 1); receiver->SetMaximumIncomingConnections(32); // if (sender) // sender->ApplyNetworkSimulator(128000, 50, 100); // if (receiver) // receiver->ApplyNetworkSimulator(128000, 50, 100); /*printf("How long to run this test for, in seconds?\n"); gets(str); if (str[0]==0)*/ strcpy(str, "12"); currentTime = RakNet::GetTime(); quitTime = atoi(str) * 1000 + currentTime; nextSend=currentTime; while (currentTime < quitTime) //while (1) { packet = sender->Receive(); while (packet) { // PARSE TYPES switch(packet->data[0]) { case ID_CONNECTION_REQUEST_ACCEPTED: if (isVerbose) printf("ID_CONNECTION_REQUEST_ACCEPTED\n"); doSend=true; nextSend=currentTime; break; case ID_NO_FREE_INCOMING_CONNECTIONS: if (isVerbose) printf("ID_NO_FREE_INCOMING_CONNECTIONS\n"); break; case ID_DISCONNECTION_NOTIFICATION: if (isVerbose) printf("ID_DISCONNECTION_NOTIFICATION\n"); break; case ID_CONNECTION_LOST: if (isVerbose) printf("ID_CONNECTION_LOST\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: if (isVerbose) printf("Connection attempt failed\n"); break; } sender->DeallocatePacket(packet); packet = sender->Receive(); } while (doSend && currentTime > nextSend) { streamNumberSender=0; // streamNumber = randomMT() % 32; // Do the send bitStream.Reset(); bitStream.Write((unsigned char) (ID_USER_PACKET_ENUM+1)); bitStream.Write(packetNumberSender[streamNumberSender]++); bitStream.Write(streamNumberSender); bitStream.Write(currentTime); char *pad; int padLength = (randomMT() % 5000) + 1; pad = new char [padLength]; bitStream.Write(pad, padLength); delete [] pad; // Send on a random priority with a random stream // if (sender->Send(&bitStream, HIGH_PRIORITY, (PacketReliability) (RELIABLE + (randomMT() %2)) ,streamNumber, UNASSIGNED_SYSTEM_ADDRESS, true)==false) if (sender->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED ,streamNumberSender, UNASSIGNED_SYSTEM_ADDRESS, true)==false) packetNumberSender[streamNumberSender]--; // Didn't finish connecting yet? RakNetStatistics *rssSender; rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0)); if (isVerbose) printf("Snd: %i.\n", packetNumberSender[streamNumberSender]); nextSend+=sendInterval; // Test halting // if (rand()%20==0) // nextSend+=1000; } packet = receiver->Receive(); while (packet) { switch(packet->data[0]) { case ID_NEW_INCOMING_CONNECTION: if (isVerbose) printf("ID_NEW_INCOMING_CONNECTION\n"); break; case ID_DISCONNECTION_NOTIFICATION: if (isVerbose) printf("ID_DISCONNECTION_NOTIFICATION\n"); break; case ID_CONNECTION_LOST: if (isVerbose) printf("ID_CONNECTION_LOST\n"); break; case ID_USER_PACKET_ENUM+1: bitStream.Reset(); bitStream.Write((char*)packet->data, packet->length); bitStream.IgnoreBits(8); // Ignore ID_USER_PACKET_ENUM+1 bitStream.Read(receivedPacketNumberReceiver); bitStream.Read(streamNumberReceiver); bitStream.Read(receivedTimeReceiver); if (receivedPacketNumberReceiver!=packetNumberReceiver[streamNumberReceiver]) { //WARNING: If you modify the below code make sure the whole string remains in bounds, sprintf will NOT do it for you. //The error string is 512 in length //Note: Removed buffer checking because chance is insignificant, left code if wanted in future. Needs limits.h ISO C standard. /* int maxIntWorkingCopy= INT_MAX; int maxIntCharLen =0; while (maxIntWorkingCopy>0) {maxIntCharLen++; maxIntWorkingCopy/=10; } if (strlen(lastError)>maxIntCharLen* 3 +27)//512 should be a good len for now {*/ sprintf(lastError,"Expecting %i got %i (channel %i).",packetNumberReceiver[streamNumberReceiver], receivedPacketNumberReceiver, streamNumberReceiver); /* } else { sprintf(lastError,"Did not get what was expected. More details can be given if the error string buffer size is increased."); }*/ if (isVerbose) { RakNetStatistics *rssSender,*rssReceiver; char message[2048]; rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0)); rssReceiver=receiver->GetStatistics(receiver->GetSystemAddressFromIndex(0)); StatisticsToString(rssSender, message, 2); printf("Server stats %s\n", message); StatisticsToString(rssReceiver, message, 2); printf("Client stats%s", message); DebugTools::ShowError(lastError,!noPauses && isVerbose,__LINE__,__FILE__); } return 1; } else if (isVerbose) { printf("Got %i.Channel %i.Len %i.", packetNumberReceiver[streamNumberReceiver], streamNumberReceiver, packet->length); printf("Sent=%u Received=%u Diff=%i.\n", receivedTimeReceiver, currentTime, (int)currentTime - (int) receivedTimeReceiver); } packetNumberReceiver[streamNumberReceiver]++; break; } receiver->DeallocatePacket(packet); packet = receiver->Receive(); } RakSleep(0); currentTime=RakNet::GetTime(); } if (isVerbose) { RakNetStatistics *rssSender,*rssReceiver; char message[2048]; rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0)); rssReceiver=receiver->GetStatistics(receiver->GetSystemAddressFromIndex(0)); StatisticsToString(rssSender, message, 2); printf("Server stats %s\n", message); StatisticsToString(rssReceiver, message, 2); printf("Client stats%s", message); } if (fp) fclose(fp); return 0; }
int main(void) { int i; char ch; RakVoiceMultiplayer<RakPeerInterface> rakVoiceMultiplayer; rakPeer = RakNetworkFactory::GetRakPeerInterface(); rakVoice = RakVoiceFactory::GetRakVoiceInterface(); // Crude interface // Holds user data char ip[30], serverPort[30], clientPort[30]; bool b; char c; // A client isServer=false; // Get our input puts("Enter the local listening port"); gets(clientPort); b=rakPeer->Initialize(8, atoi(clientPort), 0); if (b) puts("Starting RakPeer"); else { puts("Failed to start RakPeer. Terminating."); exit(1); } rakPeer->SetMaximumIncomingConnections(8); rakVoice->Init(SAMPLE_RATE, 8, rakPeer); // Set the number of bytes we read and write at a time rakVoice->SetBlockSize(BLOCK_SIZE); assert(160==rakVoice->GetFrameSize()); PaError err; PortAudioStream *stream; err = Pa_Initialize(); if( err != paNoError ) goto error; muted=false; /* Record some audio. -------------------------------------------- */ err = Pa_OpenStream( &stream, Pa_GetDefaultInputDeviceID(), SAMPLES_PER_FRAME, SAMPLE_TYPE, NULL, Pa_GetDefaultOutputDeviceID(), SAMPLES_PER_FRAME, 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("Now recording!!\n"); fflush(stdout); puts("Hit 'm' to toggle mute (default off).\nHit 'c' to connect to another system.\nHit 's' to show network statistics.\nHit 'p' to get the connected player list.\nHit 'q' to quit."); ch=0; while( ch!='q') { if (kbhit()) { ch=getch(); if (ch=='m') { muted=!muted; if (muted) puts("Microphone muted."); else puts("Microphone no longer muted."); ch=0; } else if (ch=='c') { puts("Enter IP to connect to"); gets(ip); puts("Enter the port to connect to"); gets(serverPort); // Connecting the client is very simple. 0 means we don't care about // a connectionValidationInteger, and false for low priority threads bool b = rakPeer->Connect(ip, atoi(serverPort), 0, 0); if (b==false) puts("Connection call failed"); else puts("Connection call complete"); c=0; } else if (ch=='p') { PlayerID remoteSystems[8]; unsigned short numberOfSystems; numberOfSystems=8; rakPeer->GetConnectionList(remoteSystems, &numberOfSystems); if (numberOfSystems>0) { printf("Connected players:\n"); for (i=0; i < numberOfSystems; i++) printf("%i. %s:%i\n", i+1, rakPeer->PlayerIDToDottedIP(remoteSystems[i]), remoteSystems[i].port); } else printf("Nobody connected.\n"); ch=0; } else if (ch=='s') { char buffer[2048]; StatisticsToString(rakPeer->GetStatistics(rakPeer->GetPlayerIDFromIndex(0)),buffer,1); printf("%s",buffer); ch=0; } } rakVoiceMultiplayer.ProcessPackets(rakPeer); Pa_Sleep(30); } err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; rakVoice->Deinit(); RakVoiceFactory::DestroyRakVoiceInterface(rakVoice); RakNetworkFactory::DestroyRakPeerInterface(rakPeer); printf("Full duplex sound test complete.\n" ); fflush(stdout); 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; }