/// \file /// \brief \b [Depreciated] Maps packet IDs to functions. I use this in the samples, but you shouldn't use it yourself. /// /// This file is part of RakNet Copyright 2003 Kevin Jenkins. /// /// Usage of RakNet is subject to the appropriate license agreement. /// Creative Commons Licensees are subject to the /// license found at /// http://creativecommons.org/licenses/by-nc/2.5/ /// Single application licensees are subject to the license found at /// http://www.rakkarsoft.com/SingleApplicationLicense.html /// Custom license users are subject to the terms therein. /// GPL license users are subject to the GNU General Public /// License as published by the Free /// Software Foundation; either version 2 of the License, or (at your /// option) any later version. #ifndef __MULTIPLAYER_H #define __MULTIPLAYER_H struct Packet; #define _DO_PRINTF #include "Export.h" // #pragma deprecated(Multiplayer) /// \brief Maps packet IDs to functions /// /// \depreciated This will eventually be replaced with the plugin-system. /// \sa PacketEnumerations.h template class RAK_DLL_EXPORT Multiplayer { public: /// Default Constructor Multiplayer(); /// Destructor virtual ~Multiplayer(); /// Call every update cycle to read packets from RakNet and parse them down to the appropriate function. virtual void ProcessPackets( InterfaceType *interfaceType ); protected: virtual void ReceiveRemoteDisconnectionNotification( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveRemoteConnectionLost( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveRemoteNewIncomingConnection( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveRemoteExistingConnection( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveRemoteStaticData( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveConnectionBanned( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveConnectionRequestAccepted( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveNewIncomingConnection( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveConnectionAttemptFailed( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveConnectionResumption( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveNoFreeIncomingConnections( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveDisconnectionNotification( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveConnectionLost( Packet *packet, InterfaceType *interfaceType ); virtual void ReceivedStaticData( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveInvalidPassword( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveModifiedPacket( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveVoicePacket( Packet *packet, InterfaceType *interfaceType ); virtual void ReceivePong( Packet *packet, InterfaceType *interfaceType ); virtual void ReceiveAdvertisedSystem( Packet *packet, InterfaceType *interfaceType ); virtual void ProcessUnhandledPacket( Packet *packet, unsigned char packetIdentifier, InterfaceType *interfaceType ); // static unsigned char GetPacketIdentifier( Packet *packet ); private: }; // If you don't want to use distributed network objects, delete this include //#include "DistributedNetworkObjectManager.h" #include "PacketEnumerations.h" #include "NetworkTypes.h" #include #include #include "GetTime.h" #ifdef _DO_PRINTF #include #endif template Multiplayer::Multiplayer() { } template Multiplayer::~Multiplayer() {} template void Multiplayer::ProcessPackets( InterfaceType *interfaceType ) { Packet * p; unsigned char packetIdentifier; p = interfaceType->Receive(); while ( p ) { if ( ( unsigned char ) p->data[ 0 ] == ID_TIMESTAMP ) { if ( p->length > sizeof( unsigned char ) + sizeof( unsigned int ) ) packetIdentifier = ( unsigned char ) p->data[ sizeof( unsigned char ) + sizeof( unsigned int ) ]; else break; } else packetIdentifier = ( unsigned char ) p->data[ 0 ]; // Check if this is a native packet switch ( packetIdentifier ) { case ID_REMOTE_DISCONNECTION_NOTIFICATION: ReceiveRemoteDisconnectionNotification( p, interfaceType ); break; case ID_REMOTE_CONNECTION_LOST: ReceiveRemoteConnectionLost( p, interfaceType ); break; case ID_REMOTE_NEW_INCOMING_CONNECTION: ReceiveRemoteNewIncomingConnection( p, interfaceType ); break; case ID_REMOTE_EXISTING_CONNECTION: ReceiveRemoteExistingConnection( p, interfaceType ); break; case ID_REMOTE_STATIC_DATA: ReceiveRemoteStaticData( p, interfaceType ); break; case ID_CONNECTION_BANNED: ReceiveConnectionBanned( p, interfaceType ); break; case ID_CONNECTION_REQUEST_ACCEPTED: ReceiveConnectionRequestAccepted( p, interfaceType ); break; case ID_NEW_INCOMING_CONNECTION: ReceiveNewIncomingConnection( p, interfaceType ); break; case ID_CONNECTION_ATTEMPT_FAILED: ReceiveConnectionAttemptFailed( p, interfaceType ); break; case ID_NO_FREE_INCOMING_CONNECTIONS: ReceiveNoFreeIncomingConnections( p, interfaceType ); break; case ID_DISCONNECTION_NOTIFICATION: ReceiveDisconnectionNotification( p, interfaceType ); break; case ID_CONNECTION_LOST: ReceiveConnectionLost( p, interfaceType ); break; case ID_RECEIVED_STATIC_DATA: ReceivedStaticData( p, interfaceType ); break; case ID_INVALID_PASSWORD: ReceiveInvalidPassword( p, interfaceType ); break; case ID_MODIFIED_PACKET: ReceiveModifiedPacket( p, interfaceType ); break; case ID_PONG: ReceivePong( p, interfaceType ); break; case ID_ADVERTISE_SYSTEM: ReceiveAdvertisedSystem( p, interfaceType ); break; default: // If not a native packet send it to ProcessUnhandledPacket which should have been written by the user ProcessUnhandledPacket( p, packetIdentifier, interfaceType ); break; } interfaceType->DeallocatePacket( p ); p = interfaceType->Receive(); } } template void Multiplayer::ProcessUnhandledPacket( Packet *p, unsigned char packetIdentifier, InterfaceType *interfaceType ) { // This class should have been overrided to handle user defined packets #ifdef _DO_PRINTF // Uncomment this to show output as integers /* int i; static unsigned messageNumber=0; // Raw output (nonstring) printf("Multiplayer::ProcessUnhandledPacket (%i) (%i): ", messageNumber++, p->length); for (i=0; i < p->length; i++) printf("%i ",p->data[i]); printf("\n"); */ // Uncomment this to show output as a string // Raw output (string) printf( "(%i) %s\n", p->data[0], p->data ); #endif } template void Multiplayer::ReceiveRemoteDisconnectionNotification( Packet *packet, InterfaceType *interfaceType ) { // Another system has disconnected. Client only. #ifdef _DO_PRINTF printf( "ID_REMOTE_DISCONNECTION_NOTIFICATION from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_REMOTE_DISCONNECTION_NOTIFICATION,interfaceType); } template void Multiplayer::ReceiveRemoteConnectionLost( Packet *packet, InterfaceType *interfaceType ) { // Another system has been dropped by the server. Client only. #ifdef _DO_PRINTF printf( "ID_REMOTE_CONNECTION_LOST from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_REMOTE_CONNECTION_LOST,interfaceType); } template void Multiplayer::ReceiveRemoteNewIncomingConnection( Packet *packet, InterfaceType *interfaceType ) { // Another system has connected. Client only. #ifdef _DO_PRINTF printf( "ID_REMOTE_NEW_INCOMING_CONNECTION from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_REMOTE_NEW_INCOMING_CONNECTION,interfaceType); } template void Multiplayer::ReceiveRemoteExistingConnection( Packet *packet, InterfaceType *interfaceType ) { // We just connected to the server and are getting a list of players already connected // Note due to thread timing you might get both this and ID_REMOTE_NEW_INCOMING_CONNECTION when first connecting. // Client only. #ifdef _DO_PRINTF printf( "ID_REMOTE_EXISTING_CONNECTION from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_REMOTE_EXISTING_CONNECTION,interfaceType); } template void Multiplayer::ReceiveRemoteStaticData( Packet *packet, InterfaceType *interfaceType ) { // A client got the remote static data for another system // Client only. #ifdef _DO_PRINTF printf( "ID_REMOTE_STATIC_DATA from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_REMOTE_EXISTING_CONNECTION,interfaceType); } template void Multiplayer::ReceiveConnectionBanned( Packet *packet, InterfaceType *interfaceType ) { // We are banned from connecting to the system specified in packet->playerId // Peer or client #ifdef _DO_PRINTF printf( "ID_CONNECTION_BANNED from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_REMOTE_EXISTING_CONNECTION,interfaceType); } template void Multiplayer::ReceiveConnectionRequestAccepted( Packet *packet, InterfaceType *interfaceType ) { // Our request to connect to another system has been accepted. Client only. #ifdef _DO_PRINTF printf( "ID_CONNECTION_REQUEST_ACCEPTED from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_CONNECTION_REQUEST_ACCEPTED,interfaceType); } template void Multiplayer::ReceiveNewIncomingConnection( Packet *packet, InterfaceType *interfaceType ) { // Another system has requested to connect to us, which we have accepted. Server or peer only. #ifdef _DO_PRINTF printf( "ID_NEW_INCOMING_CONNECTION from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_NEW_INCOMING_CONNECTION,interfaceType); // This will send all existing distributed objects to the new player #ifdef __DISTRIBUTED_NETWORK_OBJECT_MANAGER_H DistributedNetworkObjectManager::Instance() ->SendAllDistributedObjects( packet->playerId ); #endif } template void Multiplayer::ReceiveConnectionAttemptFailed( Packet *packet, InterfaceType *interfaceType ) { // Another system has requested to connect to us, which we have accepted. Server or peer only. #ifdef _DO_PRINTF printf( "ID_CONNECTION_ATTEMPT_FAILED from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_NEW_INCOMING_CONNECTION,interfaceType); } template void Multiplayer::ReceiveConnectionResumption( Packet *packet, InterfaceType *interfaceType ) { // Someone who was already connected to us connected again. Server or peer only. #ifdef _DO_PRINTF printf( "ID_CONNECTION_RESUMPTION from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_CONNECTION_RESUMPTION,interfaceType); } template void Multiplayer::ReceiveNoFreeIncomingConnections( Packet *packet, InterfaceType *interfaceType ) { // The system we connected to has no free slots to connect to // Set free slots by calling SetMaximumIncomingConnections // Client or peer only. #ifdef _DO_PRINTF printf( "ID_NO_FREE_INCOMING_CONNECTIONS from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_NO_FREE_INCOMING_CONNECTIONS,interfaceType); } template void Multiplayer::ReceiveDisconnectionNotification( Packet *packet, InterfaceType *interfaceType ) { // A remote system terminated the connection. packet->playerId specifies which remote system #ifdef _DO_PRINTF printf( "ID_DISCONNECTION_NOTIFICATION from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_DISCONNECTION_NOTIFICATION,interfaceType); } template void Multiplayer::ReceiveConnectionLost( Packet *packet, InterfaceType *interfaceType ) { // The network cannot send reliable packets so has terminated the connection. packet->playerId specifies which remote system #ifdef _DO_PRINTF printf( "ID_CONNECTION_LOST from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_CONNECTION_LOST,interfaceType); } template void Multiplayer::ReceivedStaticData( Packet *packet, InterfaceType *interfaceType ) { // Another system has just sent their static data to us (which we recorded automatically) #ifdef _DO_PRINTF printf( "ID_RECEIVED_STATIC_DATA from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_RECEIVED_STATIC_DATA,interfaceType); } template void Multiplayer::ReceiveInvalidPassword( Packet *packet, InterfaceType *interfaceType ) { // Our connection to another system was refused because the passwords do not match #ifdef _DO_PRINTF printf( "ID_INVALID_PASSWORD from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_INVALID_PASSWORD,interfaceType); } template void Multiplayer::ReceiveModifiedPacket( Packet *packet, InterfaceType *interfaceType ) { // The network layer has detected packet tampering // This does NOT automatically close the connection #ifdef _DO_PRINTF printf( "ID_MODIFIED_PACKET from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_MODIFIED_PACKET,interfaceType); } template void Multiplayer::ReceiveVoicePacket( Packet *packet, InterfaceType *interfaceType ) { // We got a voice packet #ifdef _DO_PRINTF printf( "ID_VOICE_PACKET from PlayerID:%u:%u on %p.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // ProcessUnhandledPacket(packet, ID_VOICE_PACKET,interfaceType); } template void Multiplayer::ReceivePong( Packet *packet, InterfaceType *interfaceType ) { // Peer or client. Response from a ping for an unconnected system. #ifdef _DO_PRINTF RakNetTime time, dataLength; memcpy( ( char* ) & time, packet->data + sizeof( unsigned char ), sizeof( unsigned int ) ); dataLength = packet->length - sizeof( unsigned char ) - sizeof( unsigned int ); printf( "ID_PONG from PlayerID:%u:%u on %p.\nPing is %i\nData is %i bytes long.\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType, time, dataLength ); if ( dataLength > 0 ) printf( "Data is %s\n", packet->data + sizeof( unsigned char ) + sizeof( unsigned int ) ); #endif // ProcessUnhandledPacket(packet, ID_PONG,interfaceType); } template void Multiplayer::ReceiveAdvertisedSystem( Packet *packet, InterfaceType *interfaceType ) { // Got a packet from another RakNet system indicating that it exists. // Currently this is used for the master server for the server to indicate its external // IP to a client as well as open the NAT #ifdef _DO_PRINTF printf( "ID_ADVERTISED_SYSTEM from PlayerID:%u:%u on %p.\nIf you are running a client connecting to a server behind a NAT, you should\ncall Disconnect and connect to the to the IP specified by packet->playerId instead\n", packet->playerId.binaryAddress, packet->playerId.port, interfaceType ); #endif // When you get this packet, you should disconnect if you are not already connected. Then connect // To the IP / port given by packet->playerID. You can translate a PlayerID to an IP with PlayerIDToDottedIP } #endif