//===========================================================================// // 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 // //===========================================================================// #if !defined(L4NET_HPP) # define L4NET_HPP # if !defined(L4HOST_HPP) # include # endif # if !defined(NETWORK_HPP) # include # endif # if !defined(NETNUB_HPP) # include # endif # if !defined(HOSTMGR_HPP) # include # endif 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: 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 }; unsigned long CheckSocket(unsigned long socket); unsigned long ResolveAddress(CString host_name); unsigned long GetMyAddress(); unsigned long OpenConnection( int connection_type, // NETNUB_TCP_LISTEN or NETNUB_TCP_OPEN int local_port, int remote_port, int internet_address ); void CloseConnection(unsigned long socket_ptr); // socket address from netnub (to close) Logical GetNextMungaPacket( NetworkPacket *network_packet, HostManager::RemoteHostIterator* all_iterator ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Shared Data support // public: static Derivation ClassDerivations; 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; 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; }; //~~~~~~~~~~~~~~~~~~~~~~ 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, unsigned long network_address, unsigned long stream_pointer): NetworkManager::Message( L4NetworkManager::HostConnectedMessageID, sizeof(L4NetworkManager__HostConnectedMessage) ), hostID(host_id), networkAddress(network_address), streamPointer(stream_pointer) {} HostID hostID; unsigned long 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; }; #endif