//===========================================================================// // File: l4net.hh // // Project: MUNGA Brick: Network Manager // // Contents: Interface specification for network brick // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 03/02/95 GAC Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// #pragma once #include "l4host.h" #include "..\munga\network.h" #include "..\munga\hostmgr.h" //WinSock support :ADB 01/06/07 //#include "..\munga\netnub.h" #define NETNUB_TCP_OPEN 3 // Opens a TCP stream to another computer #define NETNUB_TCP_LISTEN 4 // Queue's a TCP listen that we can accept a connection on #define MULTIPLE_SEND_PACKET_MAX 10 #define MAX_RECEIVE_DATA_SIZE 1600 #include #include class NotationFile; class L4NetworkManager__ReceiveEggFileMessage; class L4NetworkManager__AcknowledgeEggFileMessage; class L4NetworkManager__HostConnectedMessage; class L4NetworkManager__HostDisconnectedMessage; class NetNub { friend int Netnub_Open_File( const char* filename, int access, unsigned int model ); friend int Netnub_Write_File( int handle, void *buffer, size_t length ); friend int Netnub_Close_File(int handle); public: //WinSock support :ADB 01/06/07 //static void SendCommand(); }; //extern Netcom_Ptr // Net_Common_Ptr; //~~~~~~~~~~~~~~~~~~~~~ MessageQueue__SendRequest ~~~~~~~~~~~~~~~~~~~~~~~~~~ class MessageQueue__SendRequest: public Plug { friend class HostMessageBuffer__MessageQueue; friend class L4NetworkManager__MessageBuffer; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private methods // private: MessageQueue__SendRequest( NetworkClient::ClientID client_ID, Receiver::Message *message ); ~MessageQueue__SendRequest(); Logical TestInstance() const; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private data // private: NetworkClient::ClientID clientID; Receiver::Message *messageToSend; }; //~~~~~~~~~~~~~~~~~~~ HostMessageBuffer__MessageQueue ~~~~~~~~~~~~~~~~~~~~~~ class HostMessageBuffer__MessageQueue: public Node { friend class L4NetworkManager__MessageBuffer; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private methods // private: HostMessageBuffer__MessageQueue(HostID host_ID); ~HostMessageBuffer__MessageQueue(); Logical TestInstance() const; void AddSendRequest( NetworkClient::ClientID client_ID, Receiver::Message *message ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private data // private: HostID hostID; typedef MessageQueue__SendRequest SendRequest; ChainOf sendRequestSocket; }; //~~~~~~~~~~~~~~~~~~ L4NetworkManager__MessageBuffer ~~~~~~~~~~~~~~~~~~~~~~~ class L4NetworkManager__MessageBuffer: public Node { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Public methods // public: L4NetworkManager__MessageBuffer(L4NetworkManager *network_manager); ~L4NetworkManager__MessageBuffer(); Logical TestInstance() const; Logical IsEmpty(); void AddSendRequest( HostID host_ID, NetworkClient::ClientID client_ID, Receiver::Message *message ); void AttemptToSend(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private data // private: L4NetworkManager *networkManager; typedef HostMessageBuffer__MessageQueue MessageQueue; TableOf messageQueueSocket; IteratorPosition currentQueueIndex; CollectionSize bufferSize; #ifdef LAB_ONLY CollectionSize messageCount, maxBufferSize; #endif }; inline Logical L4NetworkManager__MessageBuffer::IsEmpty() { Check(this); return (bufferSize == 0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~ l4Network manager~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class L4NetworkManager: public NetworkManager { friend class L4NetworkManager__MessageBuffer; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Constructor, Destructor, Testing // public: L4NetworkManager(); ~L4NetworkManager(); static Logical TestClass(); Logical TestInstance() const; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Network message methods // public: void Send( Message *what, ClientID to, HostID host_ID); void ExclusiveBroadcast( Message *what, ClientID to); void StartConnecting(Mission *mission); Logical Shutdown(); Logical CheckBuffers(NetworkPacket *packet); void RemovePacket(NetworkPacket *packet); Logical ExecuteBackground(); void Marker(char *marker_text); void Mode(NetworkMode myMode); void CreateConsoleHost(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Network maintenance support // public: int netPlayerCount; enum NetworkState { NormalState, ConsoleOnly }; enum NetworkStartupMode { SlaveMode, MasterMode }; bool CheckSocket(SOCKET socket, SOCKADDR_IN *remoteEndpoint); bool ResolveAddress(CString host_name, SOCKADDR_IN *address); //WinSock support :ADB 01/06/07 NetworkAddress* GetMyAddress(); //WinSock support :ADB 01/06/07 SOCKET OpenConnection( int connection_type, // NETNUB_TCP_LISTEN or NETNUB_TCP_OPEN int local_port, int remote_port, int internet_address); void CloseConnection(SOCKET socket_ptr); // socket address from netnub (to close) Logical GetNextMungaPacket( NetworkPacket *network_packet, HostManager::RemoteHostIterator* all_iterator); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Shared Data support // public: static Derivation *GetClassDerivations(); static SharedData DefaultData; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Message Support // public: // // Message IDs // enum { AcknowledgeEggFileMessageID = NetworkManager::NextMessageID, HostConnectedMessageID, HostDisconnectedMessageID, NextMessageID }; // // Message types // typedef L4NetworkManager__AcknowledgeEggFileMessage AcknowledgeEggFileMessage; typedef L4NetworkManager__HostConnectedMessage HostConnectedMessage; typedef L4NetworkManager__HostDisconnectedMessage HostDisconnectedMessage; // // Message table // static const HandlerEntry MessageHandlerEntries[]; //static MessageHandlerSet MessageHandlers; static MessageHandlerSet& GetMessageHandlers(); void ReceiveEggFileMessageHandler( ReceiveEggFileMessage *EggMessage); void AcknowledgeEggFileMessageHandler( AcknowledgeEggFileMessage *AcknowledgeEgg); void HostConnectedMessageHandler( HostConnectedMessage *HostConnected); void HostDisconnectedMessageHandler( HostDisconnectedMessage *ConsoleDisconnect); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private methods // private: typedef ChainOf DroppedMessageHostSocket; typedef ChainIteratorOf DroppedMessageHostIterator; Logical SendMessageToNetnub( Message *message, ClientID client_ID, HostID host_ID ); void SendBatchedMessageToNetnub( Message *message, ClientID client, DroppedMessageHostSocket *dropped_message_host_socket ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private Data // private: int numberOfMungaHostsConnected, numberOfConsoleHostsConnected, remoteHostCount; NetworkStartupMode networkStartupMode; Logical eggAcknowledged; NetworkState currentNetworkState; L4Host *myConsoleHost; HostID nextOpenHostID; IteratorPosition lastHostIteratorPosition; typedef L4NetworkManager__MessageBuffer MessageBuffer; MessageBuffer messageBuffer; //WinSock Support WSADATA* wsaData; //hostent* thisHost; addrinfo* thisHost; SOCKET gameListenerSocket; SOCKET consoleListenerSocket; }; //~~~~~~~~~~~~~~~~~~~~~~ L4NetworkManager inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // L4NetworkManager__AcknowledgeEggFileMessage // This message is sent back to the console to acknowledge receipt of the // egg, it indicates this computer has established all it's connections and // the console can procede with the next host // class L4NetworkManager__AcknowledgeEggFileMessage: public NetworkManager::Message { public: L4NetworkManager__AcknowledgeEggFileMessage(): NetworkManager::Message( L4NetworkManager::AcknowledgeEggFileMessageID, sizeof(L4NetworkManager__AcknowledgeEggFileMessage) ){} }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // L4NetworkManager__HostConnectedMessage // This message is generated internally by CheckBuffers and indicates that // a host has connected up to us. This is an INTERNAL message only and is // not ment to be sent on the network. class L4NetworkManager__HostConnectedMessage : public NetworkManager::Message { public: L4NetworkManager__HostConnectedMessage(HostID host_id, const SOCKADDR_IN &network_address, unsigned long stream_pointer) : NetworkManager::Message(L4NetworkManager::HostConnectedMessageID, sizeof(L4NetworkManager__HostConnectedMessage)), hostID(host_id), networkAddress(network_address), streamPointer(stream_pointer) { } HostID hostID; SOCKADDR_IN networkAddress; unsigned long streamPointer; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // L4NetworkManager__HostDisconnectedMessage // The console is expected to send us this message if it disconnects from us // for any reason. This allows the local host to setup the internal state // so the game will auto start even if the console can't stay connected to us // for some reason (for example, the console simulator in the game code can't // connect to more than one host at once). // !!! CheckBuffers should poll the connection state of all the streams and // generate this message automatically whenever a host drops off the net. // !!! HACK At the moment this message is always treated as if it came from // the console host, so it should only be sent down the console stream. // class L4NetworkManager__HostDisconnectedMessage : public NetworkManager::Message { public: L4NetworkManager__HostDisconnectedMessage(HostID host_id, unsigned long stream_pointer) : NetworkManager::Message(L4NetworkManager::HostDisconnectedMessageID, sizeof(L4NetworkManager__HostDisconnectedMessage)), hostID(host_id), streamPointer(stream_pointer) { } HostID hostID; unsigned long streamPointer; };