| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- // ----------------------------------------------------------------------
- // RakNet version 1.0
- // Filename ChatExample.cpp
- // Very basic chat engine example
- // ----------------------------------------------------------------------
- #include "MessageIdentifiers.h"
- #include "RakPeerInterface.h"
- #include "RakNetStatistics.h"
- #include "RakNetTypes.h"
- #include "BitStream.h"
- #include "PacketLogger.h"
- #include <assert.h>
- #include <cstdio>
- #include <cstring>
- #include <stdlib.h>
- #include "RakNetTypes.h"
- #ifdef _WIN32
- #include "Kbhit.h"
- #include "WindowsIncludes.h" // Sleep
- #else
- #include "Kbhit.h"
- #include <unistd.h> // usleep
- #endif
- #include "Gets.h"
- #if LIBCAT_SECURITY==1
- #include "SecureHandshake.h" // Include header for secure handshake
- #endif
- // We copy this from Multiplayer.cpp to keep things all in one file for this example
- unsigned char GetPacketIdentifier(RakNet::Packet *p);
- 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);
- }
- // 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);
- 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;
- }
- // Copied from Multiplayer.cpp
- // If the first byte is ID_TIMESTAMP, then we want the 5th byte
- // Otherwise we want the 1st byte
- unsigned char GetPacketIdentifier(RakNet::Packet *p)
- {
- if (p==0)
- return 255;
- if ((unsigned char)p->data[0] == ID_TIMESTAMP)
- {
- RakAssert(p->length > sizeof(RakNet::MessageID) + sizeof(RakNet::Time));
- return (unsigned char) p->data[sizeof(RakNet::MessageID) + sizeof(RakNet::Time)];
- }
- else
- return (unsigned char) p->data[0];
- }
|