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 ^.^)
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];
}