C++

Status
Niet open voor verdere reacties.

rappybas

Gebruiker
Lid geworden
16 mrt 2007
Berichten
47
Hoi, Ik heb zojuist de network engine van RakNet gedownload.
en heb de Chat Example een beetje naar mijn smaak gemaakt.
maar nu weet ik niet waar ik eigenlijk mijn spel moet programmeren.

Ik dacht zelf eerst ergens gewoon in main() maar dan gaf mijn spel errors, terwijl hij apart wel gewoon werkt!

(Ja, ja, ik ben een beginner, maar laat me nou maar spelen en prutsen met online ^.^)
Code:
// ----------------------------------------------------------------------
// RakNet version 1.0
// Filename ChatExample.cpp
// Created by Rakkar Software (rakkar@rakkarsoftware.com) January 24, 2003
// Very basic chat engine example
// ----------------------------------------------------------------------
#include "PacketEnumerations.h"
#include "RakNetworkFactory.h"
#include "RakClientInterface.h"
#include "RakServerInterface.h"
#include "NetworkTypes.h"
#include "BitStream.h"
#include <assert.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

// We copy this from Multiplayer.cpp to keep things all in one file for this example
unsigned char GetPacketIdentifier(Packet *p);

// Holds enumeration data
const int MOTD_MAXIMUM_LENGTH=50; // Characters allocated for the message of the day, used for enumerations
const int SERVER_NAME_MAXIMUM_LENGTH=40; // Characters allocated for the server name

struct EnumerationDataStruct
{
	char MOTD[MOTD_MAXIMUM_LENGTH];  // (Message of the day) Optional, replace with whatever and/or add more fields
	char serverName[SERVER_NAME_MAXIMUM_LENGTH];
};

const int SCDS_MAXIMUM_NAME_LENGTH=40;

struct StaticClientDataStruct
{
	unsigned char typeId;  // ID_SET_CLIENT_DATA
	char name[SCDS_MAXIMUM_NAME_LENGTH];
};

//! Modified by Marlon Hanks
//! begin:
#if ( __GNUC__ >= 3 )
    int main( void )
#else
    void main(void)
#endif
//! end:
{
	// Pointers to the interfaces of our server and client.
	// Note we can easily have both in the same program
	RakClientInterface *client=RakNetworkFactory::GetRakClientInterface();
	RakServerInterface *server=RakNetworkFactory::GetRakServerInterface();

	int i = server->GetNumberOfAddresses();

	// Holds packets
	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
	PlayerID clientID=UNASSIGNED_PLAYER_ID;

	// Crude interface
	puts("Run as (1) Client or (2) Server ?");
	if (getch()=='1')
	{
		// Holds user data
		char ip[30], serverPort[30], clientPort[30];
		StaticClientDataStruct staticClientData;

		// A client
		isServer=false;

		// Get our input
		//puts("Enter the client port to listen on");
		//gets(clientPort);
		puts("Enter your name (up to 40 characters)");
		gets(staticClientData.name);
		// Note this passes by value, because otherwise people could
		// get access to and damage our internal data
		// UNASSIGNED_PLAYER_ID is to specify changing our own data, rather than our copy of another clients data
		client->SetStaticClientData(UNASSIGNED_PLAYER_ID, (char*)&staticClientData, sizeof(StaticClientDataStruct));
		//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 = client->Connect("10.0.0.2", atoi("1337"), atoi("1337"), 0, false);
		
		if (b)
			puts("Attempting connection");
		else
		{
			puts("Bad connection attempt.  Terminating.");
			exit(1);
		}
	}
	else
	{
		// Holds user data
		char portstring[30];
		EnumerationDataStruct enumerationDataStruct;

		// A server
		isServer=true;
		puts("Enter the server port to listen on");
		gets(portstring);
		puts("Enter the server name  (up to 40 characters)");
		gets(enumerationDataStruct.serverName);
		puts("Enter the server message of the day  (up to 50 characters)");
		gets(enumerationDataStruct.MOTD);
		// Note this passes by value, because otherwise people could get access
		// to and damage our internal data
		server->SetStaticServerData((char*)&enumerationDataStruct, sizeof(EnumerationDataStruct));
		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
		bool b = server->Start(2, 0, false, atoi(portstring));
		if (b)
			puts("Server started, waiting for connections.");
		else
		{ 
			puts("Server failed to start.  Terminating.");
			exit(1);
		}
	}

	puts("'quit' to quit. 'stat' to show stats. 'ping' to ping. Type to talk.");
	char message[400];

	// Loop for input
	while (1)
	{
		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);

			// Clear remaining input
			while (kbhit()) getch();

			if (strcmp(message, "quit")==0)
			{
				puts("Quitting.");
				break;
			}

			if (strcmp(message, "stat")==0)
			{
				if (isServer==false)
				{
					printf("Connected\t\t\t%i\nAveragePing\t\t\t%i\nLastPing\t\t\t%i\nLowestPing\t\t\t%i\nPacketlossPercentile\t\t%f\nTransmittedPacketCount\t\t%i\nTransmittedFrameCount\t\t%i\nLostPacketCount\t\t\t%i\nReceivedPacketCount\t\t%i\nBytesSent\t\t\t%i\nBytesReceived\t\t\t%i\nPackets waiting for ack\t\t%i\nBytesSentPerSecond\t\t%i\nBytesReceivedPerSecond\t\t%i\nOutputBufferSize\t\t%i\nConnectionTime\t\t\t%i\n",
						client->IsConnected(),
					client->GetAveragePing(),
					client->GetLastPing(),
					client->GetLowestPing(),
					client->GetPacketlossPercentile(),
					client->GetTransmittedPacketCount(),
					client->GetTransmittedFrameCount(),
					client->GetLostPacketCount(),
					client->GetReceivedPacketCount(),
					client->GetBytesSent(),
					client->GetBytesReceived(),
					client->GetUnacknowledgedSentPacketListSize(),
					client->GetBytesSentPerSecond(),
					client->GetBytesReceivedPerSecond(),
					client->GetMaximumWindowSize(),
					client->GetPacketOutputBufferSize(),
					client->GetConnectionTime());
				}
				else
				{
					printf("AveragePing\t\t\t%i\nLastPing\t\t\t%i\nLowestPing\t\t\t%i\nPacketlossPercentile\t\t%f\nTransmittedPacketCount\t\t%i\nTransmittedFrameCount\t\t%i\nLostPacketCount\t\t\t%i\nReceivedPacketCount\t\t%i\nBytesSent\t\t\t%i\nBytesReceived\t\t\t%i\nPackets waiting for ack\t\t%i\nBytesSentPerSecond\t\t%i\nBytesReceivedPerSecond\t\t%i\nOutputBufferSize\t\t%i\nConnectionTime\t\t\t%i\n",
						server->GetAveragePing(clientID),
						server->GetLastPing(clientID),
						server->GetLowestPing(clientID),
						server->GetPacketlossPercentile(),
						server->GetTransmittedPacketCount(),
						server->GetTransmittedFrameCount(),
						server->GetLostPacketCount(),
						server->GetReceivedPacketCount(),
						server->GetBytesSent(),
						server->GetBytesReceived(),
						server->GetUnacknowledgedSentPacketListSize(),
						server->GetBytesSentPerSecond(),
						server->GetBytesReceivedPerSecond(),
						server->GetMaximumWindowSize(),
						server->GetPacketOutputBufferSize(),
						server->GetConnectionTime(clientID));
				}

				continue;
			}

			if (strcmp(message, "ping")==0)
			{
				if (isServer)
				{
					if (server->GetConnectedPlayers()>0)
					server->PingPlayer(clientID);
				}
				else
				{
					if (client->IsConnected())
						client->PingServer();
				}

				continue;
			}


			// Message now holds what we want to broadcast
			if (isServer)
			{
				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 cilents
				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_PLAYER_ID means don't exclude anyone from the broadcast
				// true means broadcast the message to everyone connected
				server->Send(message2, strlen(message2)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_PLAYER_ID, true, true);
			}
			else
			{
				// 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, strlen(message)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0);
			}
		}

		// Get a packet from either the server or the client
		if (isServer)
		{
			p = server->Receive();
		}
		else
		{
			p = client->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_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_CONNECTION_LOST\n");
				break;
			case ID_REMOTE_EXISTING_CONNECTION: // Server telling you of an existing connection that was there before you connected
				printf("ID_REMOTE_EXISTING_CONNECTION\n");
				break;
			case ID_NEW_INCOMING_CONNECTION:
				 // Somebody connected.  We have their IP now
				printf("ID_NEW_INCOMING_CONNECTION\n");
				clientID=p->playerId; // Record the player ID of the client
				break;

			case ID_RECEIVED_STATIC_DATA:
				 // Got static data
				printf("ID_RECEIVED_STATIC_DATA\n");
				if (isServer==true)
					printf("%s has connected\n", ((StaticClientDataStruct*)(server->GetStaticClientData(p->playerId))->GetData())->name);
				else
				{
					printf("Server name: %s\n", ((EnumerationDataStruct*)(client->GetStaticServerData())->GetData())->serverName);
					printf("Server MOTD: %s\n", ((EnumerationDataStruct*)(client->GetStaticServerData())->GetData())->MOTD);
				}

				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_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;

			case ID_CONNECTION_REQUEST_ACCEPTED:
				// This tells the client they have connected
				printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
				break;

			case ID_CONNECTION_RESUMPTION:
				// Client reconnected before getting disconnected
				printf("ID_CONNECTION_RESUMPTION\n");
				break;

			default:
				if (isServer) 
				{
					// The server knows the static data of all clients, so we can prefix the message
					// With the name data
					printf("%s: %s\n", ((StaticClientDataStruct*)(server->GetStaticClientData(p->playerId))->GetData())->name, 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: %s", ((StaticClientDataStruct*)(server->GetStaticClientData(p->playerId))->GetData())->name, p->data);
					server->Send(message, strlen(message)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->playerId, true, true);
				}
				else
				{
					// It's a client, so just show the message
					printf("%s\n", p->data);
				}
				break;
		}

		// We're done with the packet
		if (isServer)
			server->DeallocatePacket(p);
		else
			client->DeallocatePacket(p);
	}

	// We're done with the network
	RakNetworkFactory::DestroyRakServerInterface(server);
	RakNetworkFactory::DestroyRakClientInterface(client);
}

// 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(Packet *p)
{
	if (p==0)
		return 255;

	if ((unsigned char)p->data[0] == ID_TIMESTAMP)
	{
		assert(p->length > sizeof(unsigned char) + sizeof(unsigned long));
		return (unsigned char) p->data[sizeof(unsigned char) + sizeof(unsigned long)];
	}
	else
		return (unsigned char) p->data[0];
}
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan