//===========================================================================// // File: network.hh // // Project: MUNGA Brick: Network Manager // // Contents: Interface specification for network brick // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 11/01/94 JMA Initial coding. // // 11/03/94 ECH Made compatible with BC4.0 // // 11/03/94 ECH Changed InBox to inherit from Node // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// #pragma once #include "Adept.hpp" #include "Receiver.hpp" namespace Adept { const int Maximum_Connection_Numbers=static_cast(255); class Connection; class NetStatCollector; //------------------------------------------------------------------------- // The following helper classes must always be typedef'd or overriden by an // inheritor // typedef Receiver__ClassData InBox__ClassData; typedef Receiver__Message InBox__Message; //----------------------- End of inheritance stuff ----------------------- class __declspec(novtable) InBox: public Receiver { public: friend class NetworkManager; public: static void InitializeClass(); static void TerminateClass(); typedef InBox__ClassData ClassData; typedef InBox__Message Message; static ClassData *DefaultData; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction, Destruction, Testing // public: InBox( ClassData *class_data, int boxID ); ~InBox(); void TestInstance(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Message packet receiving // public: virtual void ReceiveNetworkPacket( const _NetPacket *packet, const Message *message ); void Send( const Message *message, Connection *connection ); void Broadcast(const Message *message) { Check_Object(this); Check_Object(message); ExclusiveBroadcast(message); ReceiveNetworkPacket(NULL, message); } void ExclusiveBroadcast(const Message *message); protected: void SendIt( DWORD destination, const Message *message ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Protected data // protected: int boxID; }; class Network__DataTransferMessage { public: BYTE inBox; size_t dataLength; void TestInstance() const {} }; struct BigMessageCollector { public: BigMessageCollector() { m_bigMessageSize = 0; m_bigMessageType = 0; m_bigPacketCRC = 0; m_bigMessage = 0; } int m_bigMessageSize; int m_bigMessageType; DWORD m_bigPacketCRC; Stuff::DynamicMemoryStream *m_bigMessage; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Network ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class QuedPacket: public Stuff::Plug { public: Stuff::MemoryStream *packetData; int messageType; int connectionID; QuedPacket(int connection, int type, Stuff::MemoryStream *data); ~QuedPacket(); }; //------------------------------------------------------------------------- // The following helper classes must always be typedef'd or overriden by an // inheritor // typedef InBox__ClassData Network__ClassData; typedef InBox__Message Network__Message; class Network: public InBox { friend class InBox; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Public Types // public: typedef Network__ClassData ClassData; typedef Network__Message Message; typedef Network__DataTransferMessage DataTransferMessage; static int DefaultPacketSize; static void InitializeClass(); static void TerminateClass(); static ClassData *DefaultData; static Network* GetInstance() { return reinterpret_cast( GlobalPointers::GetGlobalPointer(NetworkGlobalPointerIndex)); }; enum BoxID { SystemMessageStartID, NetworkBoxID, ConnectionBoxID, ApplicationBoxID, BigPacketStartBufferBoxID, BigPacketPartBufferBoxID, BigPacketEndBufferBoxID, SystemMessageStopID, GameMessageStartID, FullConnectionListMessageID, FirstDirectApplicationMessageID, LastDirectApplicationMessageID = FirstDirectApplicationMessageID+60, FirstDictionaryPageMessageID, LastDictionaryPageMessageID = FirstDictionaryPageMessageID+80, GameMessageStopID, GosMessageStartID = 224, GosMessageStopID = 256, }; enum { NoHash = 0, // don't hash this message type Hash, // hash this message type GameSpecificHash // hash this message type with data about the current game }; static int HashMessageTypeFlags[255]; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Intialize, Construction, Destruction // public: Network(); ~Network(); void Recycle(void); void TestInstance(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Message packet receiving // public: void ReceiveNetworkPacket( const _NetPacket *packet, const Message *message ); BigMessageCollector m_bigMessageCollectors[Maximum_Connection_Numbers]; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Public Interface // public: bool RoutePacket(); void net_AddPlayer(const char* player_name, DWORD net_id); // jcem for Mission review void net_RemovePlayer(DWORD net_id); // jcem for Mission review bool RouteLocalPacket(); InBox* FindInBox(BoxID box_id); public: static DWORD BroadcastAddress; static DWORD ServerAddress; static DWORD MyAddress; static bool bUseNewUI; int packetsSent[Maximum_Connection_Numbers]; int packetsDropped[Maximum_Connection_Numbers]; private: bool amIServer; int currentPlayerCount; int serverKey; int nextConnectionID; Stuff::ChainOf localPacketQue; public: // jcem Accssor for Mission review int Get_currentPlayerCount() const { return currentPlayerCount; } int Get_serverKey() const { return serverKey; } int Get_nextConnectionID() const { return nextConnectionID; } void Set_currentPlayerCount(int n) { currentPlayerCount = n; } void Set_serverKey(int n) { serverKey = n; } void Set_nextConnectionID(int n) { nextConnectionID = n; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Connection Methods // public: Connection* GetConnection(int host_ID); Connection* FindConnection(DWORD net_address); void RemoveConnection(int host_ID); void SendConnections(); void SendNetMessage(int connection, int message_type, Stuff::MemoryStream *message, bool reliable); void SendBigMessage(int connection, int message_type, Stuff::MemoryStream *message, bool reliable); void ReceiveMessage(int connection, int message_type, Stuff::MemoryStream *message); bool AmIServer(){Check_Object(this); return amIServer;} int GetPlayerCount(){Check_Object(this); return currentPlayerCount;} int GetServerKey(){Check_Object(this); return serverKey;} const char *GetGameName(); void RemovePlayer(int connection_id); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Statistics Methods // NetStatCollector *netStatCollector; // these need to be propegated into the mech layer eventually enum { IncomingProtocolHeaderBitSizeStat, OutgoingProtocolHeaderBitSizeStat, IncomingHeaderBitSizeStat, OutgoingHeaderBitSizeStat, IncomingSystemMessageBitSizeStat, OutgoingSystemMessageBitSizeStat, IncomingWeaponMessageBitSizeStat, OutgoingWeaponMessageBitSizeStat, OutgoingMechMovementBitSizeStat, IncomingMechMovementBitSizeStat, MovementConfirmationBitSizeStat, MechInternalBitSizeStat, BuildingDamageBitSizeStat, VehicleBitSizeStat, IncomingPacketCountStat, OutgoingPacketCountStat, IncomingTotalPacketSizeStat, OutgoingTotalPacketSizeStat, NetStatCount }; void AddConnectionToStats(int id); void RemoveConnectionToStats(int id); void AdvanceStats(); protected: Connection* activeConnections[Maximum_Connection_Numbers]; bool startedGosNet; }; inline void InBox::ExclusiveBroadcast(const Message *message) { Check_Object(this); Check_Object(message); SendIt(Network::BroadcastAddress, message); } }